xf86-video-intel: 3 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/sna_glyphs.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Nov 5 05:01:33 PDT 2011


 src/sna/gen2_render.c |   24 ++---
 src/sna/gen3_render.c |   24 ++---
 src/sna/gen4_render.c |    6 -
 src/sna/gen5_render.c |   10 +-
 src/sna/gen6_render.c |    5 -
 src/sna/gen7_render.c |    5 -
 src/sna/kgem.c        |   27 ++++-
 src/sna/sna_glyphs.c  |  233 ++++++++++++++++++++++++++++++++++----------------
 8 files changed, 218 insertions(+), 116 deletions(-)

New commits:
commit d21c30d0b8b08ec85c3b5d9a02a6969f7c8b9315
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Nov 5 11:56:17 2011 +0000

    sna: Constrain GPU pixmaps to always fit within the blitter
    
    Otherwise we end up always doing expensive readbacks where we would
    obviously prefer it if we simply used cached memory for the CPU
    operation and then upload.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b0e76b7..29f572b 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -443,16 +443,31 @@ static uint32_t kgem_surface_size(struct kgem *kgem,
 		break;
 	}
 
+	/* If it is too wide for the blitter, don't even bother.  */
 	*pitch = ALIGN(width * bpp / 8, tile_width);
-	if (kgem->gen < 40 && tiling != I915_TILING_NONE) {
-		if (*pitch > 8192)
+	if (kgem->gen < 40) {
+		if(tiling != I915_TILING_NONE) {
+			if (*pitch > 8192)
+				return 0;
+			for (size = tile_width; size < *pitch; size <<= 1)
+				;
+			*pitch = size;
+		} else {
+			if (*pitch >= 32768)
+				return 0;
+		}
+	} else {
+		int limit = 32768;
+		if (tiling)
+			limit *= 4;
+		if (*pitch >= limit)
 			return 0;
-		for (size = tile_width; size < *pitch; size <<= 1)
-			;
-		*pitch = size;
 	}
+	height = ALIGN(height, tile_height);
+	if (height >= 65536)
+		return 0;
 
-	size = *pitch * ALIGN(height, tile_height);
+	size = *pitch * height;
 	if (kgem->has_relaxed_fencing || tiling == I915_TILING_NONE)
 		return ALIGN(size, PAGE_SIZE);
 
commit e309cea3ae5c22c58a918008a52e3d8d694c9ff2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Nov 5 11:28:06 2011 +0000

    sna: Do the supported PictOp check first
    
    There is no point even attempting a BLT operation if we know that it is
    an unusual render operation.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 8908ae2..8e09915 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1251,6 +1251,12 @@ gen2_render_composite(struct sna *sna,
 {
 	DBG(("%s()\n", __FUNCTION__));
 
+	if (op >= ARRAY_SIZE(gen2_blend_op)) {
+		DBG(("%s: fallback due to unhandled blend op: %d\n",
+		     __FUNCTION__, op));
+		return FALSE;
+	}
+
 	/* Try to use the BLT engine unless it implies a
 	 * 3D -> 2D context switch.
 	 */
@@ -1264,12 +1270,6 @@ gen2_render_composite(struct sna *sna,
 			      tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen2_blend_op)) {
-		DBG(("%s: fallback due to unhandled blend op: %d\n",
-		     __FUNCTION__, op));
-		return FALSE;
-	}
-
 	if (!gen2_check_dst_format(dst->format)) {
 		DBG(("%s: fallback due to unhandled dst format: %x\n",
 		     __FUNCTION__, dst->format));
@@ -1906,6 +1906,12 @@ gen2_render_fill_boxes(struct sna *sna,
 	struct sna_composite_op tmp;
 	uint32_t pixel;
 
+	if (op >= ARRAY_SIZE(gen2_blend_op)) {
+		DBG(("%s: fallback due to unhandled blend op: %d\n",
+		     __FUNCTION__, op));
+		return FALSE;
+	}
+
 #if NO_FILL_BOXES
 	return gen2_render_fill_boxes_try_blt(sna, op, format, color,
 					      dst, dst_bo,
@@ -1916,12 +1922,6 @@ gen2_render_fill_boxes(struct sna *sna,
 	     __FUNCTION__, op, (int)format,
 	     color->red, color->green, color->blue, color->alpha));
 
-	if (op >= ARRAY_SIZE(gen2_blend_op)) {
-		DBG(("%s: fallback due to unhandled blend op: %d\n",
-		     __FUNCTION__, op));
-		return FALSE;
-	}
-
 	if (dst->drawable.width > 2048 ||
 	    dst->drawable.height > 2048 ||
 	    dst_bo->pitch > 8192 ||
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 01007e9..5439672 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2254,6 +2254,12 @@ gen3_render_composite(struct sna *sna,
 {
 	DBG(("%s()\n", __FUNCTION__));
 
+	if (op >= ARRAY_SIZE(gen3_blend_op)) {
+		DBG(("%s: fallback due to unhandled blend op: %d\n",
+		     __FUNCTION__, op));
+		return FALSE;
+	}
+
 #if NO_COMPOSITE
 	if (mask)
 		return FALSE;
@@ -2278,12 +2284,6 @@ gen3_render_composite(struct sna *sna,
 			      tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen3_blend_op)) {
-		DBG(("%s: fallback due to unhandled blend op: %d\n",
-		     __FUNCTION__, op));
-		return FALSE;
-	}
-
 	if (!gen3_check_dst_format(dst->format)) {
 		DBG(("%s: fallback due to unhandled dst format: %x\n",
 		     __FUNCTION__, dst->format));
@@ -3690,6 +3690,12 @@ gen3_render_fill_boxes(struct sna *sna,
 	struct sna_composite_op tmp;
 	uint32_t pixel;
 
+	if (op >= ARRAY_SIZE(gen3_blend_op)) {
+		DBG(("%s: fallback due to unhandled blend op: %d\n",
+		     __FUNCTION__, op));
+		return FALSE;
+	}
+
 #if NO_FILL_BOXES
 	return gen3_render_fill_boxes_try_blt(sna, op, format, color,
 					      dst, dst_bo,
@@ -3700,12 +3706,6 @@ gen3_render_fill_boxes(struct sna *sna,
 	     __FUNCTION__, op, (int)format,
 	     color->red, color->green, color->blue, color->alpha));
 
-	if (op >= ARRAY_SIZE(gen3_blend_op)) {
-		DBG(("%s: fallback due to unhandled blend op: %d\n",
-		     __FUNCTION__, op));
-		return FALSE;
-	}
-
 	if (dst->drawable.width > 2048 ||
 	    dst->drawable.height > 2048 ||
 	    dst_bo->pitch > 8192 ||
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 3c26994..e3a715e 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1899,6 +1899,9 @@ gen4_render_composite(struct sna *sna,
 	DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
 	     width, height, sna->kgem.mode));
 
+	if (op >= ARRAY_SIZE(gen4_blend_op))
+		return FALSE;
+
 #if NO_COMPOSITE
 	if (mask)
 		return FALSE;
@@ -1919,9 +1922,6 @@ gen4_render_composite(struct sna *sna,
 			      width, height, tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen4_blend_op))
-		return FALSE;
-
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
 					    src_x, src_y,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 28c7a07..82a84d6 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1936,6 +1936,11 @@ gen5_render_composite(struct sna *sna,
 	DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
 	     width, height, sna->kgem.mode));
 
+	if (op >= ARRAY_SIZE(gen5_blend_op)) {
+		DBG(("%s: unhandled blend op %d\n", __FUNCTION__, op));
+		return FALSE;
+	}
+
 	if (mask == NULL &&
 	    try_blt(sna, src, width, height) &&
 	    sna_blt_composite(sna, op,
@@ -1945,11 +1950,6 @@ gen5_render_composite(struct sna *sna,
 			      width, height, tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen5_blend_op)) {
-		DBG(("%s: unhandled blend op %d\n", __FUNCTION__, op));
-		return FALSE;
-	}
-
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
 					    src_x, src_y,
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 7cb8e71..9e18445 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2092,6 +2092,8 @@ gen6_render_composite(struct sna *sna,
 		      int16_t width, int16_t height,
 		      struct sna_composite_op *tmp)
 {
+	if (op >= ARRAY_SIZE(gen6_blend_op))
+		return FALSE;
 
 #if NO_COMPOSITE
 	if (mask)
@@ -2116,9 +2118,6 @@ gen6_render_composite(struct sna *sna,
 			      width, height, tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen6_blend_op))
-		return FALSE;
-
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
 					    src_x, src_y,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index ba6e9d5..7947749 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2228,6 +2228,8 @@ gen7_render_composite(struct sna *sna,
 		      int16_t width, int16_t height,
 		      struct sna_composite_op *tmp)
 {
+	if (op >= ARRAY_SIZE(gen7_blend_op))
+		return FALSE;
 
 #if NO_COMPOSITE
 	if (mask)
@@ -2252,9 +2254,6 @@ gen7_render_composite(struct sna *sna,
 			      width, height, tmp))
 		return TRUE;
 
-	if (op >= ARRAY_SIZE(gen7_blend_op))
-		return FALSE;
-
 	if (need_tiling(sna, width, height))
 		return sna_tiling_composite(op, src, mask, dst,
 					    src_x, src_y,
commit ab3d6d878fa27515eb760107d963d522cc87cd77
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Nov 5 10:08:02 2011 +0000

    sna: Render small glyph masks on the CPU
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 2a16299..ad2c19d 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -722,94 +722,183 @@ glyphs_via_mask(struct sna *sna,
 			return FALSE;
 	}
 
-	pixmap = screen->CreatePixmap(screen,
-				      width, height, format->depth,
-				      SNA_CREATE_SCRATCH);
-	if (!pixmap)
-		return FALSE;
-
 	component_alpha = NeedsComponent(format->format);
-	mask = CreatePicture(0, &pixmap->drawable,
-			     format, CPComponentAlpha,
-			     &component_alpha, serverClient, &error);
-	screen->DestroyPixmap(pixmap);
-	if (!mask)
-		return FALSE;
+	if (width * height * format->depth < 8 * 256) {
+		pixman_image_t *mask_image;
+		int s = dst->pDrawable->pScreen->myNum;
 
-	ValidatePicture(mask);
-	clear_pixmap(sna, pixmap);
+		DBG(("%s: smal mask, rendering glyphs to upload buffer\n",
+		     __FUNCTION__));
 
-	memset(&tmp, 0, sizeof(tmp));
-	glyph_atlas = NULL;
-	do {
-		int n = list->len;
-		x += list->xOff;
-		y += list->yOff;
-		while (n--) {
-			GlyphPtr glyph = *glyphs++;
-			struct sna_glyph *priv;
-			PicturePtr this_atlas;
-			struct sna_composite_rectangles r;
+		pixmap = sna_pixmap_create_upload(screen,
+						   width, height,
+						   format->depth);
+		if (!pixmap)
+			return FALSE;
 
-			if (glyph->info.width == 0 || glyph->info.height == 0)
-				goto next_glyph;
+		memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height);
+		mask_image =
+			pixman_image_create_bits(format->depth << 24 | format->format,
+						 width, height,
+						 pixmap->devPrivate.ptr,
+						 pixmap->devKind);
+		do {
+			int n = list->len;
+			x += list->xOff;
+			y += list->yOff;
+			while (n--) {
+				GlyphPtr g = *glyphs++;
+				PicturePtr picture;
+				pixman_image_t *glyph_image;
+				int16_t xi, yi;
+				int dx, dy;
+
+				if (g->info.width == 0 || g->info.height == 0)
+					goto next_image;
+
+				/* If the mask has been cropped, it is likely
+				 * that some of the glyphs fall outside.
+				 */
+				xi = x - g->info.x;
+				yi = y - g->info.y;
+				if (xi < width || yi < height)
+					goto next_image;
+				if (xi + g->info.width >= 0 ||
+				    yi + g->info.height >= 0)
+					goto next_image;
+
+				picture = GlyphPicture(g)[s];
+				if (picture == NULL)
+					goto next_image;
+
+				glyph_image = image_from_pict(picture, FALSE, &dx, &dy);
+				if (!glyph_image)
+					goto next_image;
 
-			priv = GET_PRIVATE(glyph);
-			if (priv->atlas != NULL) {
-				this_atlas = priv->atlas;
-				r.src = priv->coordinate;
-			} else {
-				if (glyph_atlas) {
-					tmp.done(sna, &tmp);
-					glyph_atlas = NULL;
-				}
-				if (glyph_cache(screen, &sna->render, glyph)) {
+				DBG(("%s: glyph+(%d,%d) to mask (%d, %d)x(%d, %d)\n",
+				     __FUNCTION__,
+				     dx,dy,
+				     xi, yi,
+				     g->info.width,
+				     g->info.height));
+
+				pixman_image_composite(PictOpAdd,
+						       glyph_image,
+						       NULL,
+						       mask_image,
+						       dx, dy,
+						       0, 0,
+						       xi,
+						       yi,
+						       g->info.width,
+						       g->info.height);
+				free_pixman_pict(picture, glyph_image);
+
+next_image:
+				x += g->info.xOff;
+				y += g->info.yOff;
+			}
+			list++;
+		} while (--nlist);
+		pixman_image_unref(mask_image);
+
+		mask = CreatePicture(0, &pixmap->drawable,
+				     format, CPComponentAlpha,
+				     &component_alpha, serverClient, &error);
+		screen->DestroyPixmap(pixmap);
+		if (!mask)
+			return FALSE;
+
+		ValidatePicture(mask);
+	} else {
+		pixmap = screen->CreatePixmap(screen,
+					      width, height, format->depth,
+					      SNA_CREATE_SCRATCH);
+		if (!pixmap)
+			return FALSE;
+
+		mask = CreatePicture(0, &pixmap->drawable,
+				     format, CPComponentAlpha,
+				     &component_alpha, serverClient, &error);
+		screen->DestroyPixmap(pixmap);
+		if (!mask)
+			return FALSE;
+
+		ValidatePicture(mask);
+		clear_pixmap(sna, pixmap);
+
+		memset(&tmp, 0, sizeof(tmp));
+		glyph_atlas = NULL;
+		do {
+			int n = list->len;
+			x += list->xOff;
+			y += list->yOff;
+			while (n--) {
+				GlyphPtr glyph = *glyphs++;
+				struct sna_glyph *priv;
+				PicturePtr this_atlas;
+				struct sna_composite_rectangles r;
+
+				if (glyph->info.width == 0 || glyph->info.height == 0)
+					goto next_glyph;
+
+				priv = GET_PRIVATE(glyph);
+				if (priv->atlas != NULL) {
 					this_atlas = priv->atlas;
 					r.src = priv->coordinate;
 				} else {
-					/* no cache for this glyph */
-					this_atlas = GlyphPicture(glyph)[index];
-					r.src.x = r.src.y = 0;
+					if (glyph_atlas) {
+						tmp.done(sna, &tmp);
+						glyph_atlas = NULL;
+					}
+					if (glyph_cache(screen, &sna->render, glyph)) {
+						this_atlas = priv->atlas;
+						r.src = priv->coordinate;
+					} else {
+						/* no cache for this glyph */
+						this_atlas = GlyphPicture(glyph)[index];
+						r.src.x = r.src.y = 0;
+					}
 				}
-			}
 
-			if (this_atlas != glyph_atlas) {
-				if (glyph_atlas)
-					tmp.done(sna, &tmp);
+				if (this_atlas != glyph_atlas) {
+					if (glyph_atlas)
+						tmp.done(sna, &tmp);
 
-				if (!sna->render.composite(sna, PictOpAdd,
-							   this_atlas, NULL, mask,
-							   0, 0, 0, 0, 0, 0,
-							   0, 0,
-							   &tmp)) {
-					FreePicture(mask, 0);
-					return FALSE;
-				}
+					if (!sna->render.composite(sna, PictOpAdd,
+								   this_atlas, NULL, mask,
+								   0, 0, 0, 0, 0, 0,
+								   0, 0,
+								   &tmp)) {
+						FreePicture(mask, 0);
+						return FALSE;
+					}
 
-				glyph_atlas = this_atlas;
-			}
+					glyph_atlas = this_atlas;
+				}
 
-			DBG(("%s: blt glyph origin (%d, %d), offset (%d, %d), src (%d, %d), size (%d, %d)\n",
-			     __FUNCTION__,
-			     x, y,
-			     glyph->info.x, glyph->info.y,
-			     r.src.x, r.src.y,
-			     glyph->info.width, glyph->info.height));
+				DBG(("%s: blt glyph origin (%d, %d), offset (%d, %d), src (%d, %d), size (%d, %d)\n",
+				     __FUNCTION__,
+				     x, y,
+				     glyph->info.x, glyph->info.y,
+				     r.src.x, r.src.y,
+				     glyph->info.width, glyph->info.height));
 
-			r.dst.x = x - glyph->info.x;
-			r.dst.y = y - glyph->info.y;
-			r.width  = glyph->info.width;
-			r.height = glyph->info.height;
-			tmp.blt(sna, &tmp, &r);
+				r.dst.x = x - glyph->info.x;
+				r.dst.y = y - glyph->info.y;
+				r.width  = glyph->info.width;
+				r.height = glyph->info.height;
+				tmp.blt(sna, &tmp, &r);
 
 next_glyph:
-			x += glyph->info.xOff;
-			y += glyph->info.yOff;
-		}
-		list++;
-	} while (--nlist);
-	if (glyph_atlas)
-		tmp.done(sna, &tmp);
+				x += glyph->info.xOff;
+				y += glyph->info.yOff;
+			}
+			list++;
+		} while (--nlist);
+		if (glyph_atlas)
+			tmp.done(sna, &tmp);
+	}
 
 	sna_composite(op,
 		      src, mask, dst,


More information about the xorg-commit mailing list