xf86-video-intel: 2 commits - src/i830.h src/i830_render.c src/i830_uxa.c src/i915_render.c src/i965_render.c uxa/uxa.h uxa/uxa-render.c

Chris Wilson ickle at kemper.freedesktop.org
Mon May 10 02:48:25 PDT 2010


 src/i830.h        |    5 +
 src/i830_render.c |  104 ++++++++++++++++++--------------------
 src/i830_uxa.c    |    3 +
 src/i915_render.c |  145 +++++++++++++++++++++++++-----------------------------
 src/i965_render.c |  108 +++++++++++++++++++---------------------
 uxa/uxa-render.c  |  130 ++++++++++++++++++++----------------------------
 uxa/uxa.h         |   13 ++++
 7 files changed, 246 insertions(+), 262 deletions(-)

New commits:
commit 21c1c3c7f6eb2b5070d2153b15a8fb1afe938bbb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 10 10:19:28 2010 +0100

    i915: Use 1x1R pixmap for solid drawables
    
      x11perf has a regression
      https://bugs.freedesktop.org/show_bug.cgi?id=25068
    
    caused by
    
      commit e581ceb7381e29ecc1a172597d258824f6a1d2d3
      i915: Use the color channels to pass along solid sources and masks.
    
    Do not convert 1x1R pixmaps into a solid color as the readback from the
    bo negates all the performances advantages of using a smaller vertex
    buffer and fewer samplers.
    
    Before (PineView):
      aa=66800 glyph/s, rgb=28800 glyphs/s
    
    Now:
      aa=96800 glyphs/s, rgb=48500 glyphs/s
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i915_render.c b/src/i915_render.c
index 36f50d4..25ad51c 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -393,19 +393,6 @@ i915_prepare_composite(int op, PicturePtr source_picture,
 			intel->render_source_is_solid = TRUE;
 			intel->render_source_solid = source->solidFill.color;
 		}
-	} else if (source_picture->pDrawable) {
-		intel->render_source_is_solid =
-			source_picture->pDrawable->width == 1 &&
-			source_picture->pDrawable->height == 1 &&
-			source_picture->repeat;
-
-		if (intel->render_source_is_solid) {
-			if (! uxa_get_color_for_pixmap (source,
-							source_picture->format,
-							PICT_a8r8g8b8,
-							&intel->render_source_solid))
-				intel->render_source_is_solid = FALSE;
-		}
 	}
 	if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
 		return FALSE;
@@ -418,18 +405,6 @@ i915_prepare_composite(int op, PicturePtr source_picture,
 				intel->render_mask_is_solid = TRUE;
 				intel->render_mask_solid = source->solidFill.color;
 			}
-		} else if (mask_picture->pDrawable) {
-			intel->render_mask_is_solid =
-				mask_picture->pDrawable->width == 1 &&
-				mask_picture->pDrawable->height == 1 &&
-				mask_picture->repeat;
-			if (intel->render_mask_is_solid) {
-				if (! uxa_get_color_for_pixmap (mask,
-								mask_picture->format,
-								PICT_a8r8g8b8,
-								&intel->render_mask_solid))
-					intel->render_mask_is_solid = FALSE;
-			}
 		}
 		if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
 			return FALSE;
commit f52b6e832292c02c0010b19882e38e1097beeda0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 10 09:39:44 2010 +0100

    uxa: Rearrange checking and preparing of composite textures.
    
      x11perf regression caused by 2D driver
      https://bugs.freedesktop.org/show_bug.cgi?id=28047
    
    caused by
    
      commit a7b800513fcc94e063dfd68d2f63b6bab7fae47d
      uxa: Extract sub-region from in-memory buffers.
    
    The issue is that as we extract the region prior to checking whether the
    composite can in fact be accelerated, we perform expensive surplus
    operations. This is particularly noticeable for ComponentAlpha text,
    such as rgb10text. The solution here is to rearrange the
    check_composite() prior to acquiring the sources, and only extracting
    the subregion if the render path can not actually handle the texture.
    
    Performance (on PineView):
    a7b800513^: aa=68600 glyphs/s, rgb=29900 glyphs/s
    a7b800513: aa=65700 glyphs/s, rgb=13200 glyphs/s
    now: aa=66800 glyph/s, rgb=28800 glyphs/s
    
    The residual lossage seems to be from the extra function call and
    dixPrivate lookups. Hmm. More warning is the extremely low performance,
    however the results are consistent so the improvement looks real...
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830.h b/src/i830.h
index 88949f6..fc26f3a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,8 +447,9 @@ void i830_set_gem_max_sizes(ScrnInfoPtr scrn);
 drm_intel_bo *i830_allocate_framebuffer(ScrnInfoPtr scrn);
 
 /* i830_render.c */
-Bool i830_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
+Bool i830_check_composite(int op, PicturePtr source, PicturePtr mask,
 			  PicturePtr dest);
+Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture);
 Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			    PicturePtr dest, PixmapPtr sourcecPixmap,
 			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
@@ -460,6 +461,7 @@ void i830_done_composite(PixmapPtr dest);
 /* i915_render.c */
 Bool i915_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			  PicturePtr dest);
+Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture);
 Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			    PicturePtr dest, PixmapPtr sourcecPixmap,
 			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
@@ -473,6 +475,7 @@ void gen4_render_state_init(ScrnInfoPtr scrn);
 void gen4_render_state_cleanup(ScrnInfoPtr scrn);
 Bool i965_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			  PicturePtr dest);
+Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture);
 Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			    PicturePtr dest, PixmapPtr sourcecPixmap,
 			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
diff --git a/src/i830_render.c b/src/i830_render.c
index 8e559c9..e7f55ce 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -221,52 +221,6 @@ static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask,
 	return TRUE;
 }
 
-static Bool i830_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
-					 int unit)
-{
-	if (picture->repeatType > RepeatReflect) {
-		intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
-			     picture->repeatType);
-		return FALSE;
-	}
-
-	if (picture->filter != PictFilterNearest &&
-	    picture->filter != PictFilterBilinear) {
-		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
-				     picture->filter);
-		return FALSE;
-	}
-
-	if (picture->pDrawable) {
-		int w, h, i;
-
-		w = picture->pDrawable->width;
-		h = picture->pDrawable->height;
-		if ((w > 2048) || (h > 2048)) {
-			intel_debug_fallback(scrn,
-					     "Picture w/h too large (%dx%d)\n",
-					     w, h);
-			return FALSE;
-		}
-
-		for (i = 0;
-		     i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
-		     i++) {
-			if (i830_tex_formats[i].fmt == picture->format)
-				break;
-		}
-		if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
-		{
-			intel_debug_fallback(scrn, "Unsupported picture format "
-					     "0x%x\n",
-					     (int)picture->format);
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
 static uint32_t i8xx_get_card_format(PicturePtr picture)
 {
 	int i;
@@ -413,22 +367,64 @@ i830_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
 		}
 	}
 
-	if (!i830_check_composite_texture(scrn, source_picture, 0)) {
-		intel_debug_fallback(scrn, "Check Src picture texture\n");
+	if (!i830_get_dest_format(dest_picture, &tmp1)) {
+		intel_debug_fallback(scrn, "Get Color buffer format\n");
 		return FALSE;
 	}
-	if (mask_picture != NULL
-	    && !i830_check_composite_texture(scrn, mask_picture, 1)) {
-		intel_debug_fallback(scrn, "Check Mask picture texture\n");
+
+	return TRUE;
+}
+
+Bool
+i830_check_composite_texture(ScreenPtr screen, PicturePtr picture)
+{
+	if (picture->repeatType > RepeatReflect) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+		intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
+			     picture->repeatType);
 		return FALSE;
 	}
 
-	if (!i830_get_dest_format(dest_picture, &tmp1)) {
-		intel_debug_fallback(scrn, "Get Color buffer format\n");
+	if (picture->filter != PictFilterNearest &&
+	    picture->filter != PictFilterBilinear) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
+				     picture->filter);
 		return FALSE;
 	}
 
-	return TRUE;
+	if (picture->pDrawable) {
+		int w, h, i;
+
+		w = picture->pDrawable->width;
+		h = picture->pDrawable->height;
+		if ((w > 2048) || (h > 2048)) {
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+			intel_debug_fallback(scrn,
+					     "Picture w/h too large (%dx%d)\n",
+					     w, h);
+			return FALSE;
+		}
+
+		for (i = 0;
+		     i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
+		     i++) {
+			if (i830_tex_formats[i].fmt == picture->format)
+				break;
+		}
+		if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
+		{
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+			intel_debug_fallback(scrn, "Unsupported picture format "
+					     "0x%x\n",
+					     (int)picture->format);
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
 }
 
 Bool
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 4a13eb0..8b81e0c 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -1078,17 +1078,20 @@ Bool i830_uxa_init(ScreenPtr screen)
 	/* Composite */
 	if (!IS_I9XX(intel)) {
 		intel->uxa_driver->check_composite = i830_check_composite;
+		intel->uxa_driver->check_composite_texture = i830_check_composite_texture;
 		intel->uxa_driver->prepare_composite = i830_prepare_composite;
 		intel->uxa_driver->composite = i830_composite;
 		intel->uxa_driver->done_composite = i830_done_composite;
 	} else if (IS_I915G(intel) || IS_I915GM(intel) ||
 		   IS_I945G(intel) || IS_I945GM(intel) || IS_G33CLASS(intel)) {
 		intel->uxa_driver->check_composite = i915_check_composite;
+		intel->uxa_driver->check_composite_texture = i915_check_composite_texture;
 		intel->uxa_driver->prepare_composite = i915_prepare_composite;
 		intel->uxa_driver->composite = i915_composite;
 		intel->uxa_driver->done_composite = i830_done_composite;
 	} else {
 		intel->uxa_driver->check_composite = i965_check_composite;
+		intel->uxa_driver->check_composite_texture = i965_check_composite_texture;
 		intel->uxa_driver->prepare_composite = i965_prepare_composite;
 		intel->uxa_driver->composite = i965_composite;
 		intel->uxa_driver->done_composite = i830_done_composite;
diff --git a/src/i915_render.c b/src/i915_render.c
index 98b5b88..36f50d4 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -176,10 +176,50 @@ static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
 	return TRUE;
 }
 
-static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
-					 int unit)
+Bool
+i915_check_composite(int op,
+		     PicturePtr source_picture,
+		     PicturePtr mask_picture,
+		     PicturePtr dest_picture)
+{
+	ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
+	uint32_t tmp1;
+
+	/* Check for unsupported compositing operations. */
+	if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
+		intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
+				     op);
+		return FALSE;
+	}
+	if (mask_picture != NULL && mask_picture->componentAlpha &&
+	    PICT_FORMAT_RGB(mask_picture->format)) {
+		/* Check if it's component alpha that relies on a source alpha
+		 * and on the source value.  We can only get one of those
+		 * into the single source value that we get to blend with.
+		 */
+		if (i915_blend_op[op].src_alpha &&
+		    (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
+			intel_debug_fallback(scrn,
+					     "Component alpha not supported "
+					     "with source alpha and source "
+					     "value blending.\n");
+			return FALSE;
+		}
+	}
+
+	if (!i915_get_dest_format(dest_picture, &tmp1)) {
+		intel_debug_fallback(scrn, "Get Color buffer format\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+Bool
+i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
 {
 	if (picture->repeatType > RepeatReflect) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 		intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
 			     picture->repeatType);
 		return FALSE;
@@ -187,17 +227,25 @@ static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
 
 	if (picture->filter != PictFilterNearest &&
 	    picture->filter != PictFilterBilinear) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
 				     picture->filter);
 		return FALSE;
 	}
 
+	if (picture->pSourcePict) {
+		SourcePict *source = picture->pSourcePict;
+		if (source->type == SourcePictTypeSolidFill)
+			return TRUE;
+	}
+
 	if (picture->pDrawable) {
 		int w, h, i;
 
 		w = picture->pDrawable->width;
 		h = picture->pDrawable->height;
 		if ((w > 2048) || (h > 2048)) {
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 			intel_debug_fallback(scrn,
 					     "Picture w/h too large (%dx%d)\n",
 					     w, h);
@@ -212,61 +260,17 @@ static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
 		}
 		if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
 		{
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 			intel_debug_fallback(scrn, "Unsupported picture format "
 					     "0x%x\n",
 					     (int)picture->format);
 			return FALSE;
 		}
-	}
 
-	return TRUE;
-}
-
-Bool
-i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
-		     PicturePtr dest_picture)
-{
-	ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
-	uint32_t tmp1;
-
-	/* Check for unsupported compositing operations. */
-	if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
-		intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
-				     op);
-		return FALSE;
-	}
-	if (mask_picture != NULL && mask_picture->componentAlpha &&
-	    PICT_FORMAT_RGB(mask_picture->format)) {
-		/* Check if it's component alpha that relies on a source alpha
-		 * and on the source value.  We can only get one of those
-		 * into the single source value that we get to blend with.
-		 */
-		if (i915_blend_op[op].src_alpha &&
-		    (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
-			intel_debug_fallback(scrn,
-					     "Component alpha not supported "
-					     "with source alpha and source "
-					     "value blending.\n");
-			return FALSE;
-		}
-	}
-
-	if (!i915_check_composite_texture(scrn, source_picture, 0)) {
-		intel_debug_fallback(scrn, "Check Src picture texture\n");
-		return FALSE;
-	}
-	if (mask_picture != NULL
-	    && !i915_check_composite_texture(scrn, mask_picture, 1)) {
-		intel_debug_fallback(scrn, "Check Mask picture texture\n");
-		return FALSE;
-	}
-
-	if (!i915_get_dest_format(dest_picture, &tmp1)) {
-		intel_debug_fallback(scrn, "Get Color buffer format\n");
-		return FALSE;
+		return TRUE;
 	}
 
-	return TRUE;
+	return FALSE;
 }
 
 static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
@@ -382,39 +386,53 @@ i915_prepare_composite(int op, PicturePtr source_picture,
 	intel->render_dest_picture = dest_picture;
 	intel->render_dest = dest;
 
-	intel->render_source_is_solid =
-	    source_picture->pDrawable &&
-	    source_picture->pDrawable->width == 1 &&
-	    source_picture->pDrawable->height == 1 &&
-	    source_picture->repeat;
-
-	if (intel->render_source_is_solid) {
-	    if (! uxa_get_color_for_pixmap (source,
-					    source_picture->format,
-					    PICT_a8r8g8b8,
-					    &intel->render_source_solid))
-		intel->render_source_is_solid = FALSE;
+	intel->render_source_is_solid = FALSE;
+	if (source_picture->pSourcePict) {
+		SourcePict *source = source_picture->pSourcePict;
+		if (source->type == SourcePictTypeSolidFill) {
+			intel->render_source_is_solid = TRUE;
+			intel->render_source_solid = source->solidFill.color;
+		}
+	} else if (source_picture->pDrawable) {
+		intel->render_source_is_solid =
+			source_picture->pDrawable->width == 1 &&
+			source_picture->pDrawable->height == 1 &&
+			source_picture->repeat;
+
+		if (intel->render_source_is_solid) {
+			if (! uxa_get_color_for_pixmap (source,
+							source_picture->format,
+							PICT_a8r8g8b8,
+							&intel->render_source_solid))
+				intel->render_source_is_solid = FALSE;
+		}
 	}
 	if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
 		return FALSE;
 
-
 	intel->render_mask_is_solid = TRUE; /* mask == NULL => opaque */
 	if (mask) {
-	    intel->render_mask_is_solid =
-		mask_picture->pDrawable &&
-		mask_picture->pDrawable->width == 1 &&
-		mask_picture->pDrawable->height == 1 &&
-		mask_picture->repeat;
-	    if (intel->render_mask_is_solid) {
-		if (! uxa_get_color_for_pixmap (mask,
-						mask_picture->format,
-						PICT_a8r8g8b8,
-						&intel->render_mask_solid))
-		    intel->render_mask_is_solid = FALSE;
-	    }
-	    if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
-		    return FALSE;
+		if (mask_picture->pSourcePict) {
+			SourcePict *source = mask_picture->pSourcePict;
+			if (source->type == SourcePictTypeSolidFill) {
+				intel->render_mask_is_solid = TRUE;
+				intel->render_mask_solid = source->solidFill.color;
+			}
+		} else if (mask_picture->pDrawable) {
+			intel->render_mask_is_solid =
+				mask_picture->pDrawable->width == 1 &&
+				mask_picture->pDrawable->height == 1 &&
+				mask_picture->repeat;
+			if (intel->render_mask_is_solid) {
+				if (! uxa_get_color_for_pixmap (mask,
+								mask_picture->format,
+								PICT_a8r8g8b8,
+								&intel->render_mask_solid))
+					intel->render_mask_is_solid = FALSE;
+			}
+		}
+		if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
+			return FALSE;
 	}
 
 	if (!intel_check_pitch_3d(dest))
diff --git a/src/i965_render.c b/src/i965_render.c
index 3623549..c38bbfc 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -183,54 +183,6 @@ static Bool i965_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
 	return TRUE;
 }
 
-static Bool i965_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
-					 int unit)
-{
-	if (picture->repeatType > RepeatReflect) {
-		intel_debug_fallback(scrn,
-				     "extended repeat (%d) not supported\n",
-				     picture->repeatType);
-		return FALSE;
-	}
-
-	if (picture->filter != PictFilterNearest &&
-	    picture->filter != PictFilterBilinear) {
-		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
-				     picture->filter);
-		return FALSE;
-	}
-
-	if (picture->pDrawable) {
-		int w, h, i;
-
-		w = picture->pDrawable->width;
-		h = picture->pDrawable->height;
-		if ((w > 8192) || (h > 8192)) {
-			intel_debug_fallback(scrn,
-					     "Picture w/h too large (%dx%d)\n",
-					     w, h);
-			return FALSE;
-		}
-
-		for (i = 0;
-		     i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
-		     i++) {
-			if (i965_tex_formats[i].fmt == picture->format)
-				break;
-		}
-		if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
-		{
-			intel_debug_fallback(scrn,
-					     "Unsupported picture format "
-					     "0x%x\n",
-					     (int)picture->format);
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
 Bool
 i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
 		     PicturePtr dest_picture)
@@ -267,25 +219,69 @@ i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
 		}
 	}
 
-	if (!i965_check_composite_texture(scrn, source_picture, 0)) {
-		intel_debug_fallback(scrn, "Check Src picture texture\n");
+	if (!i965_get_dest_format(dest_picture, &tmp1)) {
+		intel_debug_fallback(scrn, "Get Color buffer format\n");
 		return FALSE;
 	}
-	if (mask_picture != NULL
-	    && !i965_check_composite_texture(scrn, mask_picture, 1)) {
-		intel_debug_fallback(scrn, "Check Mask picture texture\n");
+
+	return TRUE;
+}
+
+Bool
+i965_check_composite_texture(ScreenPtr screen, PicturePtr picture)
+{
+	if (picture->repeatType > RepeatReflect) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+		intel_debug_fallback(scrn,
+				     "extended repeat (%d) not supported\n",
+				     picture->repeatType);
 		return FALSE;
 	}
 
-	if (!i965_get_dest_format(dest_picture, &tmp1)) {
-		intel_debug_fallback(scrn, "Get Color buffer format\n");
+	if (picture->filter != PictFilterNearest &&
+	    picture->filter != PictFilterBilinear) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
+				     picture->filter);
 		return FALSE;
 	}
 
-	return TRUE;
+	if (picture->pDrawable) {
+		int w, h, i;
 
+		w = picture->pDrawable->width;
+		h = picture->pDrawable->height;
+		if ((w > 8192) || (h > 8192)) {
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+			intel_debug_fallback(scrn,
+					     "Picture w/h too large (%dx%d)\n",
+					     w, h);
+			return FALSE;
+		}
+
+		for (i = 0;
+		     i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
+		     i++) {
+			if (i965_tex_formats[i].fmt == picture->format)
+				break;
+		}
+		if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
+		{
+			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+			intel_debug_fallback(scrn,
+					     "Unsupported picture format "
+					     "0x%x\n",
+					     (int)picture->format);
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
 }
 
+
 #define BRW_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
 
 /* Set up a default static partitioning of the URB, which is supposed to
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 3112677..ddee172 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -642,8 +642,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
 		     PicturePtr pSrc,
 		     INT16 x, INT16 y,
 		     CARD16 width, CARD16 height,
-		     INT16 * out_x, INT16 * out_y,
-		     Bool force)
+		     INT16 * out_x, INT16 * out_y)
 {
 	PixmapPtr pPixmap;
 	PicturePtr pDst;
@@ -651,17 +650,17 @@ uxa_acquire_drawable(ScreenPtr pScreen,
 	int depth, error;
 	int tx, ty;
 
-	if (!force && uxa_drawable_is_offscreen(pSrc->pDrawable)) {
-		*out_x = x + pSrc->pDrawable->x;
-		*out_y = y + pSrc->pDrawable->y;
-		return pSrc;
-	}
-
 	depth = pSrc->pDrawable->depth;
 	if (depth == 1 || !transform_is_integer_translation(pSrc->transform, &tx, &ty)) {
 		/* XXX extract the sample extents and do the transformation on the GPU */
 		pDst = uxa_render_picture(pScreen, pSrc, x, y, width, height);
 		goto done;
+	} else {
+		if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->depth) {
+			*out_x = x + pSrc->pDrawable->x;
+			*out_y = y + pSrc->pDrawable->y;
+			return pSrc;
+		}
 	}
 
 	pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, 0);
@@ -671,9 +670,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
 	/* Skip the copy if the result remains in memory and not a bo */
 	if (!uxa_drawable_is_offscreen(&pPixmap->drawable)) {
 		pScreen->DestroyPixmap(pPixmap);
-		*out_x = x + pSrc->pDrawable->x;
-		*out_y = y + pSrc->pDrawable->y;
-		return pSrc;
+		return 0;
 	}
 
 	pGC = GetScratchGC(depth, pScreen);
@@ -705,14 +702,21 @@ uxa_acquire_source(ScreenPtr pScreen,
 		   PicturePtr pPict,
 		   INT16 x, INT16 y,
 		   CARD16 width, CARD16 height,
-		   INT16 * out_x, INT16 * out_y,
-		   Bool force)
+		   INT16 * out_x, INT16 * out_y)
 {
+	uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+	if (uxa_screen->info->check_composite_texture &&
+	    uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+		*out_x = x + pPict->pDrawable->x;
+		*out_y = y + pPict->pDrawable->y;
+		return pPict;
+	}
+
 	if (pPict->pDrawable)
 		return uxa_acquire_drawable(pScreen, pPict,
 					    x, y, width, height,
-					    out_x, out_y,
-					    force);
+					    out_x, out_y);
 
 	*out_x = 0;
 	*out_y = 0;
@@ -725,14 +729,21 @@ uxa_acquire_mask(ScreenPtr pScreen,
 		 PicturePtr pPict,
 		 INT16 x, INT16 y,
 		 INT16 width, INT16 height,
-		 INT16 * out_x, INT16 * out_y,
-		 Bool force)
+		 INT16 * out_x, INT16 * out_y)
 {
+	uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+	if (uxa_screen->info->check_composite_texture &&
+	    uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+		*out_x = x + pPict->pDrawable->x;
+		*out_y = y + pPict->pDrawable->y;
+		return pPict;
+	}
+
 	if (pPict->pDrawable)
 		return uxa_acquire_drawable(pScreen, pPict,
 					    x, y, width, height,
-					    out_x, out_y,
-					    force);
+					    out_x, out_y);
 
 	*out_x = 0;
 	*out_y = 0;
@@ -872,12 +883,14 @@ uxa_try_driver_composite(CARD8 op,
 	RegionRec region;
 	BoxPtr pbox;
 	int nbox;
-	INT16 _xSrc = xSrc, _ySrc = ySrc;
-	INT16 _xMask = xMask, _yMask = yMask;
 	int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
 	PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
 	PicturePtr localSrc, localMask = NULL;
 
+	if (uxa_screen->info->check_composite &&
+	    !(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst))
+		return -1;
+
 	pDstPix =
 	    uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
 	if (!pDstPix)
@@ -886,18 +899,18 @@ uxa_try_driver_composite(CARD8 op,
 	xDst += pDst->pDrawable->x;
 	yDst += pDst->pDrawable->y;
 
-	localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
-				      pSrc, xSrc, ySrc, width, height,
-				      &xSrc, &ySrc,
-				      FALSE);
+	localSrc = uxa_acquire_source(pDst->pDrawable->pScreen, pSrc,
+				      xSrc, ySrc,
+				      width, height,
+				      &xSrc, &ySrc);
 	if (!localSrc)
 		return 0;
 
 	if (pMask) {
-		localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
-					     pMask, xMask, yMask, width, height,
-					     &xMask, &yMask,
-					     FALSE);
+		localMask = uxa_acquire_mask(pDst->pDrawable->pScreen, pMask,
+					     xMask, yMask,
+					     width, height,
+					     &xMask, &yMask);
 		if (!localMask) {
 			if (localSrc != pSrc)
 				FreePicture(localSrc, 0);
@@ -906,45 +919,6 @@ uxa_try_driver_composite(CARD8 op,
 		}
 	}
 
-recheck:
-	if (uxa_screen->info->check_composite &&
-	    !(*uxa_screen->info->check_composite) (op, localSrc, localMask,
-						   pDst)) {
-		if (localSrc == pSrc || (localMask && localMask == pMask)) {
-			if (localSrc == pSrc) {
-				localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
-							      pSrc, _xSrc, _ySrc, width, height,
-							      &xSrc, &ySrc, TRUE);
-				if (!localSrc || localSrc == pSrc) {
-					if (localMask && localMask != pMask)
-						FreePicture(localMask, 0);
-					return -(localSrc == pSrc);
-				}
-			}
-
-			if (localMask && localMask == pMask) {
-				localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
-							     pMask, _xMask, _yMask, width, height,
-							     &xMask, &yMask, TRUE);
-				if (!localMask || localMask == pMask) {
-					if (localSrc != pSrc)
-						FreePicture(localSrc, 0);
-
-					return -(localMask == pMask);
-				}
-			}
-
-			goto recheck;
-		}
-
-		if (localSrc != pSrc)
-			FreePicture(localSrc, 0);
-		if (localMask && localMask != pMask)
-			FreePicture(localMask, 0);
-
-		return -1;
-	}
-
 	if (!miComputeCompositeRegion(&region, localSrc, localMask, pDst,
 				      xSrc, ySrc, xMask, yMask, xDst, yDst,
 				      width, height)) {
@@ -1306,9 +1280,15 @@ uxa_composite(CARD8 op,
 		/* For generic masks and solid src pictures, mach64 can do
 		 * Over in two passes, similar to the component-alpha case.
 		 */
-		isSrcSolid = pSrc->pDrawable &&
-		    pSrc->pDrawable->width == 1 &&
-		    pSrc->pDrawable->height == 1 && pSrc->repeat;
+
+		isSrcSolid =
+			pSrc->pDrawable ?
+				pSrc->pDrawable->width == 1 &&
+				pSrc->pDrawable->height == 1 &&
+				pSrc->repeat :
+			pSrc->pSourcePict ?
+				pSrc->pSourcePict->type == SourcePictTypeSolidFill :
+			0;
 
 		/* If we couldn't do the Composite in a single pass, and it
 		 * was a component-alpha Over, see if we can do it in two
@@ -1320,13 +1300,13 @@ uxa_composite(CARD8 op,
 			    uxa_try_magic_two_pass_composite_helper(op, pSrc,
 								    pMask, pDst,
 								    xSrc, ySrc,
-								    xMask,
-								    yMask, xDst,
-								    yDst, width,
-								    height);
+								    xMask, yMask,
+								    xDst, yDst,
+								    width, height);
 			if (ret == 1)
 				goto done;
 		}
+
 	}
 
 fallback:
diff --git a/uxa/uxa.h b/uxa/uxa.h
index c7e5566..32a86a9 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -252,6 +252,19 @@ typedef struct _UxaDriver {
 				PicturePtr pDstPicture);
 
 	/**
+	 * check_composite_texture() checks to see if a source to the composite
+	 * operation can be used without midification.
+	 *
+	 * @param pScreen Screen
+	 * @param pPicture Picture
+	 *
+	 * The check_composite_texture() call is recommended if prepare_composite() is
+	 * implemented, but is not required.
+	 */
+	Bool(*check_composite_texture) (ScreenPtr pScreen,
+					PicturePtr pPicture);
+
+	/**
 	 * prepare_composite() sets up the driver for doing a composite
 	 * operation described in the Render extension protocol spec.
 	 *


More information about the xorg-commit mailing list