xf86-video-intel: 3 commits - src/sna/g4x_render.c 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/sna_accel.c src/sna/sna_blt.c src/sna/sna_render.c src/sna/sna_render.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Nov 25 04:37:40 PST 2012


 src/sna/g4x_render.c  |    3 -
 src/sna/gen2_render.c |   10 ++-
 src/sna/gen3_render.c |    3 -
 src/sna/gen4_render.c |    3 -
 src/sna/gen5_render.c |    3 -
 src/sna/gen6_render.c |    3 -
 src/sna/gen7_render.c |    3 -
 src/sna/sna_accel.c   |    4 -
 src/sna/sna_blt.c     |   40 +++++++++++--
 src/sna/sna_render.c  |  145 +++++++++++++++++++++++++++++++++++---------------
 src/sna/sna_render.h  |    3 -
 11 files changed, 158 insertions(+), 62 deletions(-)

New commits:
commit 1367e3f9ef5f606c8927cbde441a2ea41fa6d025
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Nov 25 00:24:45 2012 +0000

    sna: Exploit the alpha-fixup of the BLT for texture format conversions
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/g4x_render.c b/src/sna/g4x_render.c
index 9de8340..f92a33a 100644
--- a/src/sna/g4x_render.c
+++ b/src/sna/g4x_render.c
@@ -1927,7 +1927,8 @@ g4x_composite_picture(struct sna *sna,
 	channel->card_format = g4x_get_card_format(picture->format);
 	if (channel->card_format == -1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
 		return sna_render_picture_extract(sna, picture, channel,
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 9663dff..31074af 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1304,7 +1304,8 @@ static bool
 gen2_check_card_format(struct sna *sna,
 		       PicturePtr picture,
 		       struct sna_composite_channel *channel,
-		       int x, int y, int w, int h)
+		       int x, int y, int w, int h,
+		       bool *fixup_alpha)
 {
 	uint32_t format = picture->format;
 	unsigned int i;
@@ -1324,10 +1325,12 @@ gen2_check_card_format(struct sna *sna,
 				return true;
 			}
 
+			*fixup_alpha = true;
 			return false;
 		}
 	}
 
+	*fixup_alpha = false;
 	return false;
 }
 
@@ -1343,6 +1346,7 @@ gen2_composite_picture(struct sna *sna,
 	PixmapPtr pixmap;
 	uint32_t color;
 	int16_t dx, dy;
+	bool fixup_alpha;
 
 	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
 	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
@@ -1417,9 +1421,9 @@ gen2_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
-	if (!gen2_check_card_format(sna, picture, channel, x,  y, w ,h))
+	if (!gen2_check_card_format(sna, picture, channel, x,  y, w ,h, &fixup_alpha))
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y, fixup_alpha);
 
 	channel->pict_format = picture->format;
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index f0f0a48..9dcdfcd 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2402,7 +2402,8 @@ gen3_composite_picture(struct sna *sna,
 	if (!gen3_composite_channel_set_format(channel, picture->format) &&
 	    !gen3_composite_channel_set_xformat(picture, channel, x, y, w, h))
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
 		DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n",
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 057192d..5134bb9 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1918,7 +1918,8 @@ gen4_composite_picture(struct sna *sna,
 	channel->card_format = gen4_get_card_format(picture->format);
 	if (channel->card_format == -1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
 		return sna_render_picture_extract(sna, picture, channel,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index b49b25e..31f6f21 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1936,7 +1936,8 @@ gen5_composite_picture(struct sna *sna,
 	channel->card_format = gen5_get_card_format(picture->format);
 	if (channel->card_format == -1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
 		return sna_render_picture_extract(sna, picture, channel,
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index fbe0951..6cc1a7d 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2274,7 +2274,8 @@ gen6_composite_picture(struct sna *sna,
 	channel->card_format = gen6_get_card_format(picture->format);
 	if (channel->card_format == (unsigned)-1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
 		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 3bec5df..a106a18 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2386,7 +2386,8 @@ gen7_composite_picture(struct sna *sna,
 	channel->card_format = gen7_get_card_format(picture->format);
 	if (channel->card_format == (unsigned)-1)
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y);
+						  x, y, w, h, dst_x, dst_y,
+						  false);
 
 	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
 		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index c534f61..0a2856e 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1637,11 +1637,10 @@ sna_render_picture_convert(struct sna *sna,
 			   PixmapPtr pixmap,
 			   int16_t x, int16_t y,
 			   int16_t w, int16_t h,
-			   int16_t dst_x, int16_t dst_y)
+			   int16_t dst_x, int16_t dst_y,
+			   bool fixup_alpha)
 {
-	pixman_image_t *src, *dst;
 	BoxRec box;
-	void *ptr;
 
 #if NO_CONVERT
 	return -1;
@@ -1691,52 +1690,113 @@ sna_render_picture_convert(struct sna *sna,
 		return 0;
 	}
 
-	if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
-		return 0;
+	if (fixup_alpha && is_gpu(&pixmap->drawable)) {
+		ScreenPtr screen = pixmap->drawable.pScreen;
+		PixmapPtr tmp;
+		PicturePtr src, dst;
+		int error;
 
-	src = pixman_image_create_bits(picture->format,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height,
-				       pixmap->devPrivate.ptr,
-				       pixmap->devKind);
-	if (!src)
-		return 0;
+		assert(PICT_FORMAT_BPP(picture->format) == pixmap->drawable.bitsPerPixel);
+		channel->pict_format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format),
+						   PICT_FORMAT_TYPE(picture->format),
+						   PICT_FORMAT_BPP(picture->format) - PIXMAN_FORMAT_DEPTH(picture->format),
+						   PICT_FORMAT_R(picture->format),
+						   PICT_FORMAT_G(picture->format),
+						   PICT_FORMAT_B(picture->format));
 
-	if (PICT_FORMAT_RGB(picture->format) == 0) {
-		channel->pict_format = PIXMAN_a8;
-		DBG(("%s: converting to a8 from %08x\n",
+		DBG(("%s: converting to %08x from %08x using composite alpha-fixup\n",
 		     __FUNCTION__, picture->format));
+
+		tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0);
+		if (tmp == NULL)
+			return 0;
+
+		dst = CreatePicture(0, &tmp->drawable,
+				    PictureMatchFormat(screen,
+						       pixmap->drawable.bitsPerPixel,
+						       channel->pict_format),
+				    0, NULL, serverClient, &error);
+		if (dst == NULL) {
+			screen->DestroyPixmap(tmp);
+			return 0;
+		}
+
+		src = CreatePicture(0, &pixmap->drawable,
+				    PictureMatchFormat(screen,
+						       pixmap->drawable.depth,
+						       picture->format),
+				    0, NULL, serverClient, &error);
+		if (dst == NULL) {
+			FreePicture(dst, 0);
+			screen->DestroyPixmap(tmp);
+			return 0;
+		}
+
+		ValidatePicture(src);
+		ValidatePicture(dst);
+
+		sna_composite(PictOpSrc, src, NULL, dst,
+			      box.x1, box.y1,
+			      0, 0,
+			      0, 0,
+			      w, h);
+		FreePicture(dst, 0);
+		FreePicture(src, 0);
+
+		channel->bo = sna_pixmap_get_bo(tmp);
+		kgem_bo_reference(channel->bo);
+		screen->DestroyPixmap(tmp);
 	} else {
-		channel->pict_format = PIXMAN_a8r8g8b8;
-		DBG(("%s: converting to a8r8g8b8 from %08x\n",
-		     __FUNCTION__, picture->format));
-	}
+		pixman_image_t *src, *dst;
+		void *ptr;
 
-	channel->bo = kgem_create_buffer_2d(&sna->kgem,
-					    w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
-					    KGEM_BUFFER_WRITE_INPLACE,
-					    &ptr);
-	if (!channel->bo) {
-		pixman_image_unref(src);
-		return 0;
-	}
+		if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
+			return 0;
 
-	dst = pixman_image_create_bits(channel->pict_format,
-				       w, h, ptr, channel->bo->pitch);
-	if (!dst) {
-		kgem_bo_destroy(&sna->kgem, channel->bo);
+		src = pixman_image_create_bits(picture->format,
+					       pixmap->drawable.width,
+					       pixmap->drawable.height,
+					       pixmap->devPrivate.ptr,
+					       pixmap->devKind);
+		if (!src)
+			return 0;
+
+		if (PICT_FORMAT_RGB(picture->format) == 0) {
+			channel->pict_format = PIXMAN_a8;
+			DBG(("%s: converting to a8 from %08x\n",
+			     __FUNCTION__, picture->format));
+		} else {
+			channel->pict_format = PIXMAN_a8r8g8b8;
+			DBG(("%s: converting to a8r8g8b8 from %08x\n",
+			     __FUNCTION__, picture->format));
+		}
+
+		channel->bo = kgem_create_buffer_2d(&sna->kgem,
+						    w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
+						    KGEM_BUFFER_WRITE_INPLACE,
+						    &ptr);
+		if (!channel->bo) {
+			pixman_image_unref(src);
+			return 0;
+		}
+
+		dst = pixman_image_create_bits(channel->pict_format,
+					       w, h, ptr, channel->bo->pitch);
+		if (!dst) {
+			kgem_bo_destroy(&sna->kgem, channel->bo);
+			pixman_image_unref(src);
+			return 0;
+		}
+
+		pixman_image_composite(PictOpSrc, src, NULL, dst,
+				       box.x1, box.y1,
+				       0, 0,
+				       0, 0,
+				       w, h);
+		pixman_image_unref(dst);
 		pixman_image_unref(src);
-		return 0;
 	}
 
-	pixman_image_composite(PictOpSrc, src, NULL, dst,
-			       box.x1, box.y1,
-			       0, 0,
-			       0, 0,
-			       w, h);
-	pixman_image_unref(dst);
-	pixman_image_unref(src);
-
 	channel->width  = w;
 	channel->height = h;
 
@@ -1745,11 +1805,10 @@ sna_render_picture_convert(struct sna *sna,
 	channel->offset[0] = x - dst_x - box.x1;
 	channel->offset[1] = y - dst_y - box.y1;
 
-	DBG(("%s: offset=(%d, %d), size=(%d, %d) ptr[0]=%08x\n",
+	DBG(("%s: offset=(%d, %d), size=(%d, %d)\n",
 	     __FUNCTION__,
 	     channel->offset[0], channel->offset[1],
-	     channel->width, channel->height,
-	     *(uint32_t*)ptr));
+	     channel->width, channel->height));
 	return 1;
 }
 
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 97b9222..e9ec2ba 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -691,7 +691,8 @@ sna_render_picture_convert(struct sna *sna,
 			   PixmapPtr pixmap,
 			   int16_t x, int16_t y,
 			   int16_t w, int16_t h,
-			   int16_t dst_x, int16_t dst_y);
+			   int16_t dst_x, int16_t dst_y,
+			   bool fixup_alpha);
 
 inline static void sna_render_composite_redirect_init(struct sna_composite_op *op)
 {
commit 6d6399f97cf7cb91dcf89e9a5cd1243f761e4314
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Nov 25 00:05:44 2012 +0000

    sna: Transform a simple repeat pattern into range of the BLT
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 9aa636c..ea11d00 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1840,10 +1840,21 @@ clear:
 	if (x < 0 || y < 0 ||
 	    x + width > src->pDrawable->width ||
 	    y + height > src->pDrawable->height) {
-		DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d\n",
+		DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d, repeat=%d\n",
 		     __FUNCTION__,
-		     x, y, x+width, y+width, src->pDrawable->width, src->pDrawable->height));
-		return false;
+		     x, y, x+width, y+width, src->pDrawable->width, src->pDrawable->height, src->repeatType));
+		if (src->repeat && src->repeatType == RepeatNormal) {
+			x = x % src->pDrawable->width;
+			y = y % src->pDrawable->height;
+			if (x < 0)
+				x += src->pDrawable->width;
+			if (y < 0)
+				y += src->pDrawable->height;
+			if (x + width  > src->pDrawable->width ||
+			    y + height > src->pDrawable->height)
+				return false;
+		} else
+			return false;
 	}
 
 	src_pixmap = get_drawable_pixmap(src->pDrawable);
@@ -2000,6 +2011,10 @@ sna_blt_composite__convert(struct sna *sna,
 		return false;
 	}
 
+	tmp->u.blt.src_pixmap = NULL;
+	tmp->u.blt.sx = tmp->src.offset[0];
+	tmp->u.blt.sy = tmp->src.offset[1];
+
 	x += tmp->src.offset[0];
 	y += tmp->src.offset[1];
 	if (x < 0 || y < 0 ||
@@ -2008,7 +2023,21 @@ sna_blt_composite__convert(struct sna *sna,
 		DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d\n",
 		     __FUNCTION__,
 		     x, y, x+width, y+width, tmp->src.width, tmp->src.height));
-		return false;
+		if (tmp->src.repeat == RepeatNormal) {
+			int xx = x % tmp->src.width;
+			int yy = y % tmp->src.height;
+			if (xx < 0)
+				xx += tmp->src.width;
+			if (yy < 0)
+				yy += tmp->src.height;
+			if (xx + width  > tmp->src.width ||
+			    yy + height > tmp->src.height)
+				return false;
+
+			tmp->u.blt.sx += xx - x;
+			tmp->u.blt.sy += yy - y;
+		} else
+			return false;
 	}
 
 	if (!kgem_check_many_bo_fenced(&sna->kgem, tmp->dst.bo, tmp->src.bo, NULL)) {
@@ -2021,9 +2050,6 @@ sna_blt_composite__convert(struct sna *sna,
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
 
-	tmp->u.blt.src_pixmap = NULL;
-	tmp->u.blt.sx = tmp->src.offset[0];
-	tmp->u.blt.sy = tmp->src.offset[1];
 	DBG(("%s: blt dst offset (%d, %d), source offset (%d, %d), with alpha fixup? %x\n",
 	     __FUNCTION__,
 	     tmp->dst.x, tmp->dst.y, tmp->u.blt.sx, tmp->u.blt.sy, alpha_fixup));
commit 39f1e228b74e98d3d87157cf093fc56ca31e6b13
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Nov 24 20:16:29 2012 +0000

    sna: Make GPU idle more consistent during wakeup
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1f9374f..2f49f12 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -14429,9 +14429,9 @@ void sna_accel_wakeup_handler(struct sna *sna)
 
 	if (sna->kgem.need_retire)
 		kgem_retire(&sna->kgem);
-	if (!sna->mode.shadow_active && !sna->kgem.need_retire) {
+	if (sna->kgem.nbatch && kgem_is_idle(&sna->kgem)) {
 		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
-		kgem_submit(&sna->kgem);
+		_kgem_submit(&sna->kgem);
 	}
 	if (sna->kgem.need_purge)
 		kgem_purge_cache(&sna->kgem);


More information about the xorg-commit mailing list