summaryrefslogtreecommitdiff
path: root/src/uxa/intel_uxa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uxa/intel_uxa.c')
-rw-r--r--src/uxa/intel_uxa.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index e90b1489..3bc1d23b 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -633,18 +633,38 @@ dri_bo *intel_get_pixmap_bo(PixmapPtr pixmap)
return intel->bo;
}
+static unsigned intel_get_tile_width(intel_screen_private *intel, int tiling, int pitch)
+{
+ unsigned long tile_width;
+
+ if (tiling == I915_TILING_NONE)
+ return 4;
+
+ tile_width = (tiling == I915_TILING_Y) ? 128 : 512;
+ if (INTEL_INFO(intel)->gen >= 040)
+ return tile_width;
+
+ while (tile_width < pitch)
+ tile_width <<= 1;
+
+ return tile_width;
+}
+
void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
struct intel_pixmap *priv;
priv = intel_get_pixmap_private(pixmap);
if (priv == NULL && bo == NULL)
- return;
+ return;
if (priv != NULL) {
if (priv->bo == bo)
return;
+free_priv:
dri_bo_unreference(priv->bo);
list_del(&priv->batch);
@@ -653,9 +673,9 @@ void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
}
if (bo != NULL) {
- uint32_t tiling;
- uint32_t swizzle_mode;
- int ret;
+ uint32_t tiling, swizzle_mode;
+ unsigned tile_width;
+ int size, stride;
priv = calloc(1, sizeof (struct intel_pixmap));
if (priv == NULL)
@@ -667,15 +687,45 @@ void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
priv->bo = bo;
priv->stride = intel_pixmap_pitch(pixmap);
- ret = drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode);
- if (ret != 0) {
- FatalError("Couldn't get tiling on bo %p: %s\n",
- bo, strerror(-ret));
+ if (drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode)) {
+ bo = NULL;
+ goto free_priv;
}
priv->tiling = tiling;
priv->busy = -1;
priv->offscreen = 1;
+
+ stride = (pixmap->drawable.width * pixmap->drawable.bitsPerPixel + 7) / 8;
+ tile_width = intel_get_tile_width(intel, tiling, stride);
+ stride = ALIGN(stride, tile_width);
+
+ if (priv->stride < stride ||
+ priv->stride & (tile_width - 1) ||
+ priv->stride >= KB(32)) {
+ bo = NULL;
+ goto free_priv;
+ }
+
+ if (tiling != I915_TILING_NONE) {
+ int height;
+
+ if (IS_GEN2(intel))
+ height = 16;
+ else if (tiling == I915_TILING_X)
+ height = 8;
+ else
+ height = 32;
+
+ height = ALIGN(pixmap->drawable.height, 2*height);
+ size = intel_get_fence_size(intel, priv->stride * height);
+ } else
+ size = priv->stride * pixmap->drawable.height;
+
+ if (bo->size < size || bo->size > intel->max_bo_size) {
+ bo = NULL;
+ goto free_priv;
+ }
}
BAIL:
@@ -1422,5 +1472,6 @@ Bool intel_uxa_init(ScreenPtr screen)
uxa_set_fallback_debug(screen, intel->fallback_debug);
uxa_set_force_fallback(screen, intel->force_fallback);
+ intel->flush_rendering = intel_flush_rendering;
return TRUE;
}