xf86-video-intel: 6 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/sna_render.c src/sna/sna_tiling.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Feb 7 12:20:09 PST 2012


 src/sna/gen2_render.c |    4 -
 src/sna/gen3_render.c |    4 -
 src/sna/gen4_render.c |    6 -
 src/sna/gen5_render.c |    4 -
 src/sna/gen6_render.c |   20 +++---
 src/sna/gen7_render.c |    9 +-
 src/sna/sna_render.c  |  155 +++++++++++++++++++++++++++++---------------------
 src/sna/sna_tiling.c  |   48 +++++++++------
 8 files changed, 146 insertions(+), 104 deletions(-)

New commits:
commit 798aad6c95a1a95fd587430dc7a6d59497a10ce1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 20:16:48 2012 +0000

    sna/gen[4-7]: Fix erroneous scale factor for partial large bo render copies
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 700a271..6246538 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2550,8 +2550,6 @@ fallback_blt:
 	gen4_copy_bind_surfaces(sna, &tmp);
 	gen4_align_vertex(sna, &tmp);
 
-	tmp.src.scale[0] = 1.f/src->drawable.width;
-	tmp.src.scale[1] = 1.f/src->drawable.height;
 	do {
 		gen4_render_copy_one(sna, &tmp,
 				     box->x1 + src_dx, box->y1 + src_dy,
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 213b80b..17789e9 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3253,7 +3253,7 @@ fallback_blt:
 	if (!gen6_check_format(tmp.src.pict_format))
 		goto fallback_blt;
 
-	tmp.op = PictOpSrc;
+	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
 	tmp.dst.pixmap = dst;
 	tmp.dst.width  = dst->drawable.width;
 	tmp.dst.height = dst->drawable.height;
@@ -3357,8 +3357,6 @@ fallback_blt:
 	gen6_emit_copy_state(sna, &tmp);
 	gen6_align_vertex(sna, &tmp);
 
-	tmp.src.scale[0] = 1.f / src->drawable.width;
-	tmp.src.scale[1] = 1.f / src->drawable.height;
 	do {
 		float *v;
 		int n_this_time = gen6_get_rectangles(sna, &tmp, n);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 731d952..9757405 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3271,8 +3271,7 @@ fallback_blt:
 
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
-	tmp.src.card_format =
-		gen7_get_card_format(tmp.src.pict_format);
+	tmp.src.card_format = gen7_get_card_format(tmp.src.pict_format);
 	if (too_large(src->drawable.width, src->drawable.height)) {
 		BoxRec extents = box[0];
 		int i;
@@ -3337,8 +3336,6 @@ fallback_blt:
 	gen7_emit_copy_state(sna, &tmp);
 	gen7_align_vertex(sna, &tmp);
 
-	tmp.src.scale[0] = 1.f / src->drawable.width;
-	tmp.src.scale[1] = 1.f / src->drawable.height;
 	do {
 		float *v;
 		int n_this_time = gen7_get_rectangles(sna, &tmp, n);
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 676f5c7..572d6ea 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -831,13 +831,13 @@ sna_render_pixmap_partial(struct sna *sna,
 	box.y1 = y;
 	box.x2 = x + w;
 	box.y2 = y + h;
+	DBG(("%s: unaligned box (%d, %d), (%d, %d)\n",
+	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
 
 	if (box.x1 < 0)
 		box.x1 = 0;
 	if (box.y1 < 0)
 		box.y1 = 0;
-	DBG(("%s: unaligned box (%d, %d), (%d, %d)\n",
-	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
 
 	if (bo->tiling) {
 		int tile_width, tile_height, tile_size;
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index d491b3b..17ecaea 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -599,20 +599,6 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 			if (tile.x2 > extents.x2)
 				tile.x2 = extents.x2;
 
-			p.drawable.width  = tile.x2 - tile.x1;
-			p.drawable.height = tile.y2 - tile.y1;
-
-			DBG(("%s: tile (%d, %d), (%d, %d)\n",
-			     __FUNCTION__, tile.x1, tile.y1, tile.x2, tile.y2));
-
-			tmp_bo = kgem_create_2d(&sna->kgem,
-						p.drawable.width,
-						p.drawable.height,
-						p.drawable.bitsPerPixel,
-						tiling, CREATE_TEMPORARY);
-			if (!tmp_bo)
-				goto tiled_error;
-
 			c = clipped;
 			for (i = 0; i < n; i++) {
 				*c = box[i];
@@ -628,17 +614,31 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 				     c->y1 - tile.y1));
 				c++;
 			}
+			if (c == clipped)
+				continue;
+
+			p.drawable.width  = tile.x2 - tile.x1;
+			p.drawable.height = tile.y2 - tile.y1;
+
+			DBG(("%s: tile (%d, %d), (%d, %d)\n",
+			     __FUNCTION__, tile.x1, tile.y1, tile.x2, tile.y2));
+
+			tmp_bo = kgem_create_2d(&sna->kgem,
+						p.drawable.width,
+						p.drawable.height,
+						p.drawable.bitsPerPixel,
+						tiling, CREATE_TEMPORARY);
+			if (!tmp_bo)
+				goto tiled_error;
 
-			if (c == clipped ||
-			    (sna->render.copy_boxes(sna, GXcopy,
+			i = (sna->render.copy_boxes(sna, GXcopy,
 						    src, src_bo, src_dx, src_dy,
 						    &p, tmp_bo, -tile.x1, -tile.y1,
 						    clipped, c - clipped) &&
 			     sna->render.copy_boxes(sna, alu,
 						    &p, tmp_bo, -tile.x1, -tile.y1,
 						    dst, dst_bo, dst_dx, dst_dy,
-						    clipped, c - clipped)))
-				i = 1;
+						    clipped, c - clipped));
 
 			kgem_bo_destroy(&sna->kgem, tmp_bo);
 
commit ea6588726107f1ab0ef5a8f69d420b5bff819a76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 15:26:50 2012 +0000

    sna: Apply offsets correctly for partial src/dst in large copy boxes
    
    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 3db9ce7..ed48ce6 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -2890,7 +2890,8 @@ fallback:
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 0f0345c..fc006ac 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3879,7 +3879,8 @@ fallback_blt:
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 459b428..700a271 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2485,7 +2485,8 @@ fallback_blt:
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 7246ed6..b9c7a92 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2801,7 +2801,8 @@ fallback_blt:
 		}
 
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 59372f8..213b80b 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3278,7 +3278,8 @@ fallback_blt:
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 8a5d95c..731d952 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3262,7 +3262,8 @@ fallback_blt:
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1, extents.y1,
+						   extents.x1 + dst_dx,
+						   extents.y1 + dst_dy,
 						   extents.x2 - extents.x1,
 						   extents.y2 - extents.y1))
 			goto fallback_tiled;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 1625b91..676f5c7 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -836,10 +836,6 @@ sna_render_pixmap_partial(struct sna *sna,
 		box.x1 = 0;
 	if (box.y1 < 0)
 		box.y1 = 0;
-	if (box.x2 > pixmap->drawable.width)
-		box.x2 = pixmap->drawable.width;
-	if (box.y2 > pixmap->drawable.height)
-		box.y2 = pixmap->drawable.height;
 	DBG(("%s: unaligned box (%d, %d), (%d, %d)\n",
 	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
 
@@ -854,19 +850,20 @@ sna_render_pixmap_partial(struct sna *sna,
 		/* Ensure we align to an even tile row */
 		box.y1 = box.y1 & ~(2*tile_height - 1);
 		box.y2 = ALIGN(box.y2, 2*tile_height);
-		if (box.y2 > pixmap->drawable.height)
-			box.y2 = pixmap->drawable.height;
 
 		assert(tile_width * 8 >= pixmap->drawable.bitsPerPixel);
 		box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1);
 		box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel);
-		if (box.x2 > pixmap->drawable.width)
-			box.x2 = pixmap->drawable.width;
 
 		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
 	} else
 		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8;
 
+	if (box.x2 > pixmap->drawable.width)
+		box.x2 = pixmap->drawable.width;
+	if (box.y2 > pixmap->drawable.height)
+		box.y2 = pixmap->drawable.height;
+
 	w = box.x2 - box.x1;
 	h = box.y2 - box.y1;
 	DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__,
@@ -889,8 +886,8 @@ sna_render_pixmap_partial(struct sna *sna,
 
 	channel->bo->pitch = bo->pitch;
 
-	channel->offset[0] = x - box.x1;
-	channel->offset[1] = y - box.y1;
+	channel->offset[0] = -box.x1;
+	channel->offset[1] = -box.y1;
 	channel->scale[0] = 1.f/w;
 	channel->scale[1] = 1.f/h;
 	channel->width  = w;
commit 14c91e108464a305fb23b3313b842bfaeb9420fc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 15:25:48 2012 +0000

    sna/tiling: Request Y-tiles if we know we cannot BLT to either the src or dst
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index c305da0..d491b3b 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -548,7 +548,7 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 {
 	BoxRec extents, tile, stack[64], *clipped, *c;
 	PixmapRec p;
-	int i, step;
+	int i, step, tiling;
 	Bool ret = FALSE;
 
 	extents = box[0];
@@ -568,8 +568,13 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 	while (step * step * 4 > sna->kgem.max_upload_tile_size)
 		step /= 2;
 
-	DBG(("%s: tiling copy, using %dx%d tiles\n",
-	     __FUNCTION__, step, step));
+	tiling = I915_TILING_X;
+	if (!kgem_bo_can_blt(&sna->kgem, src_bo) ||
+	    !kgem_bo_can_blt(&sna->kgem, dst_bo))
+		tiling = I915_TILING_Y;
+
+	DBG(("%s: tiling copy, using %dx%d %c tiles\n",
+	     __FUNCTION__, step, step, tiling == I915_TILING_X ? 'X' : 'Y'));
 
 	if (n > ARRAY_SIZE(stack)) {
 		clipped = malloc(sizeof(BoxRec) * n);
@@ -597,12 +602,14 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 			p.drawable.width  = tile.x2 - tile.x1;
 			p.drawable.height = tile.y2 - tile.y1;
 
+			DBG(("%s: tile (%d, %d), (%d, %d)\n",
+			     __FUNCTION__, tile.x1, tile.y1, tile.x2, tile.y2));
+
 			tmp_bo = kgem_create_2d(&sna->kgem,
 						p.drawable.width,
 						p.drawable.height,
 						p.drawable.bitsPerPixel,
-						I915_TILING_X,
-					       	CREATE_TEMPORARY);
+						tiling, CREATE_TEMPORARY);
 			if (!tmp_bo)
 				goto tiled_error;
 
commit 3131217e3ecbdf6cd40b044bd31e8228ff5c6bff
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 14:35:59 2012 +0000

    sna: Mark up the temporary allocations
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index c6e898b..c305da0 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -384,7 +384,7 @@ sna_tiling_fill_boxes(struct sna *sna,
 							       tmp.drawable.width,
 							       tmp.drawable.height,
 							       dst->drawable.bitsPerPixel),
-					    CREATE_SCANOUT);
+					    CREATE_SCANOUT | CREATE_TEMPORARY);
 			if (bo) {
 				int16_t dx = this.extents.x1;
 				int16_t dy = this.extents.y1;
@@ -489,7 +489,7 @@ Bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu,
 					    kgem_choose_tiling(&sna->kgem,
 							       I915_TILING_X,
 							       w, h, bpp),
-					    0);
+					    CREATE_TEMPORARY);
 			if (bo) {
 				int16_t dx = this.extents.x1;
 				int16_t dy = this.extents.y1;
@@ -601,7 +601,8 @@ sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
 						p.drawable.width,
 						p.drawable.height,
 						p.drawable.bitsPerPixel,
-						I915_TILING_X, 0);
+						I915_TILING_X,
+					       	CREATE_TEMPORARY);
 			if (!tmp_bo)
 				goto tiled_error;
 
commit ec1ccb6bf6a984cbe3317e636d7ff73887348a46
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 13:37:52 2012 +0000

    sna: Set the damage for render->copy_boxes to NULL before use
    
    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 1e0c680..3db9ce7 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -2870,6 +2870,7 @@ fallback:
 	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height) ||
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index b9afdb9..0f0345c 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3859,6 +3859,7 @@ fallback_blt:
 	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height) ||
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 530251c..459b428 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2466,6 +2466,7 @@ fallback_blt:
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.x = tmp.dst.y = 0;
 	tmp.dst.bo = dst_bo;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height)) {
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 487d903..7246ed6 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2781,6 +2781,7 @@ fallback_blt:
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.x = tmp.dst.y = 0;
 	tmp.dst.bo = dst_bo;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height)) {
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index d337b30..59372f8 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3259,6 +3259,7 @@ fallback_blt:
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height)) {
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 2e9948d..8a5d95c 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3243,6 +3243,7 @@ fallback_blt:
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
+	tmp.damage = NULL;
 
 	sna_render_composite_redirect_init(&tmp);
 	if (too_large(tmp.dst.width, tmp.dst.height)) {
commit 58f634b792c6d109c5f2374a3e24d759e744abb4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 7 13:32:20 2012 +0000

    sna: Handle tile alignment for untiled large bo more carefully
    
    We ended up trying to align the upper bound to zero as the integer
    divsion of the tile width by pixel was zero.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index c4d2301..d337b30 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3285,8 +3285,7 @@ fallback_blt:
 
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
 	tmp.src.repeat = SAMPLER_EXTEND_NONE;
-	tmp.src.card_format =
-		gen6_get_card_format(tmp.src.pict_format);
+	tmp.src.card_format = gen6_get_card_format(tmp.src.pict_format);
 	if (too_large(src->drawable.width, src->drawable.height)) {
 		BoxRec extents = box[0];
 		int i;
@@ -3307,8 +3306,10 @@ fallback_blt:
 					       extents.x1 + src_dx,
 					       extents.y1 + src_dy,
 					       extents.x2 - extents.x1,
-					       extents.y2 - extents.y1))
+					       extents.y2 - extents.y1)) {
+			DBG(("%s: unable to extract partial pixmap\n", __FUNCTION__));
 			goto fallback_tiled_dst;
+		}
 	} else {
 		tmp.src.bo = kgem_bo_reference(src_bo);
 		tmp.src.width  = src->drawable.width;
@@ -3336,8 +3337,11 @@ fallback_blt:
 	kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
 		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
+		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
+			DBG(("%s: too large for a single operation\n",
+			     __FUNCTION__));
 			goto fallback_tiled_src;
+		}
 		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	}
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 3309157..1625b91 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -819,10 +819,10 @@ sna_render_pixmap_partial(struct sna *sna,
 			  int16_t w, int16_t h)
 {
 	BoxRec box;
-	int tile_width, tile_height, tile_size;
 	int offset;
 
-	DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
+	DBG(("%s (%d, %d)x(%d, %d), pitch %d, max %d\n",
+	     __FUNCTION__, x, y, w, h, bo->pitch, sna->render.max_3d_pitch));
 
 	if (bo->pitch > sna->render.max_3d_pitch)
 		return false;
@@ -840,20 +840,32 @@ sna_render_pixmap_partial(struct sna *sna,
 		box.x2 = pixmap->drawable.width;
 	if (box.y2 > pixmap->drawable.height)
 		box.y2 = pixmap->drawable.height;
+	DBG(("%s: unaligned box (%d, %d), (%d, %d)\n",
+	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
 
-	kgem_get_tile_size(&sna->kgem, bo->tiling,
-			   &tile_width, &tile_height, &tile_size);
+	if (bo->tiling) {
+		int tile_width, tile_height, tile_size;
 
-	/* Ensure we align to an even tile row */
-	box.y1 = box.y1 & ~(2*tile_height - 1);
-	box.y2 = ALIGN(box.y2, 2*tile_height);
-	if (box.y2 > pixmap->drawable.height)
-		box.y2 = pixmap->drawable.height;
+		kgem_get_tile_size(&sna->kgem, bo->tiling,
+				   &tile_width, &tile_height, &tile_size);
+		DBG(("%s: tile size for tiling %d: %dx%d, size=%d\n",
+		     __FUNCTION__, bo->tiling, tile_width, tile_height, tile_size));
 
-	box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1);
-	box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel);
-	if (box.x2 > pixmap->drawable.width)
-		box.x2 = pixmap->drawable.width;
+		/* Ensure we align to an even tile row */
+		box.y1 = box.y1 & ~(2*tile_height - 1);
+		box.y2 = ALIGN(box.y2, 2*tile_height);
+		if (box.y2 > pixmap->drawable.height)
+			box.y2 = pixmap->drawable.height;
+
+		assert(tile_width * 8 >= pixmap->drawable.bitsPerPixel);
+		box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1);
+		box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel);
+		if (box.x2 > pixmap->drawable.width)
+			box.x2 = pixmap->drawable.width;
+
+		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
+	} else
+		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8;
 
 	w = box.x2 - box.x1;
 	h = box.y2 - box.y1;
@@ -862,11 +874,13 @@ sna_render_pixmap_partial(struct sna *sna,
 	     pixmap->drawable.width, pixmap->drawable.height));
 	if (w <= 0 || h <= 0 ||
 	    w > sna->render.max_3d_size ||
-	    h > sna->render.max_3d_size)
+	    h > sna->render.max_3d_size) {
+		DBG(("%s: box too large (%dx%d) for 3D pipeline (max %d)\n",
+		    __FUNCTION__, w, h, sna->render.max_3d_size));
 		return false;
+	}
 
 	/* How many tiles across are we? */
-	offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
 	channel->bo = kgem_create_proxy(bo,
 					box.y1 * bo->pitch + offset,
 					h * bo->pitch);
@@ -895,27 +909,11 @@ sna_render_picture_partial(struct sna *sna,
 	struct kgem_bo *bo = NULL;
 	PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable);
 	BoxRec box;
-	int tile_width, tile_height, tile_size;
 	int offset;
 
 	DBG(("%s (%d, %d)x(%d, %d) [dst=(%d, %d)]\n",
 	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
 
-	if (use_cpu_bo(sna, pixmap, &box)) {
-		if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
-			return 0;
-
-		bo = sna_pixmap(pixmap)->cpu_bo;
-	} else {
-		if (!sna_pixmap_force_to_gpu(pixmap, MOVE_READ))
-			return 0;
-
-		bo = sna_pixmap(pixmap)->gpu_bo;
-	}
-
-	if (bo->pitch > sna->render.max_3d_pitch)
-		return 0;
-
 	box.x1 = x;
 	box.y1 = y;
 	box.x2 = x + w;
@@ -951,19 +949,41 @@ sna_render_picture_partial(struct sna *sna,
 		}
 	}
 
-	kgem_get_tile_size(&sna->kgem, bo->tiling,
-			   &tile_width, &tile_height, &tile_size);
+	if (use_cpu_bo(sna, pixmap, &box)) {
+		if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
+			return 0;
 
-	/* Ensure we align to an even tile row */
-	box.y1 = box.y1 & ~(2*tile_height - 1);
-	box.y2 = ALIGN(box.y2, 2*tile_height);
-	if (box.y2 > pixmap->drawable.height)
-		box.y2 = pixmap->drawable.height;
+		bo = sna_pixmap(pixmap)->cpu_bo;
+	} else {
+		if (!sna_pixmap_force_to_gpu(pixmap, MOVE_READ))
+			return 0;
 
-	box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1);
-	box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel);
-	if (box.x2 > pixmap->drawable.width)
-		box.x2 = pixmap->drawable.width;
+		bo = sna_pixmap(pixmap)->gpu_bo;
+	}
+
+	if (bo->pitch > sna->render.max_3d_pitch)
+		return 0;
+
+	if (bo->tiling) {
+		int tile_width, tile_height, tile_size;
+
+		kgem_get_tile_size(&sna->kgem, bo->tiling,
+				   &tile_width, &tile_height, &tile_size);
+
+		/* Ensure we align to an even tile row */
+		box.y1 = box.y1 & ~(2*tile_height - 1);
+		box.y2 = ALIGN(box.y2, 2*tile_height);
+		if (box.y2 > pixmap->drawable.height)
+			box.y2 = pixmap->drawable.height;
+
+		box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1);
+		box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel);
+		if (box.x2 > pixmap->drawable.width)
+			box.x2 = pixmap->drawable.width;
+
+		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
+	} else
+		offset = box.x1 * pixmap->drawable.bitsPerPixel / 8;
 
 	w = box.x2 - box.x1;
 	h = box.y2 - box.y1;
@@ -976,7 +996,6 @@ sna_render_picture_partial(struct sna *sna,
 		return 0;
 
 	/* How many tiles across are we? */
-	offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
 	channel->bo = kgem_create_proxy(bo,
 					box.y1 * bo->pitch + offset,
 					h * bo->pitch);
@@ -1638,53 +1657,63 @@ sna_render_composite_redirect(struct sna *sna,
 	return FALSE;
 #endif
 
-	DBG(("%s: target too large (%dx%d), copying to temporary %dx%d\n",
-	     __FUNCTION__, op->dst.width, op->dst.height, width,height));
+	DBG(("%s: target too large (%dx%d), copying to temporary %dx%d, max %d\n",
+	     __FUNCTION__,
+	     op->dst.width, op->dst.height,
+	     width, height,
+	     sna->render.max_3d_size));
 
 	if (!width || !height)
 		return FALSE;
 
-	if (width  > sna->render.max_3d_pitch ||
-	    height > sna->render.max_3d_pitch)
+	if (width  > sna->render.max_3d_size ||
+	    height > sna->render.max_3d_size)
 		return FALSE;
 
 	if (op->dst.bo->pitch <= sna->render.max_3d_pitch) {
-		int tile_width, tile_height, tile_size;
 		BoxRec box;
-		int w, h;
+		int w, h, offset;
 
 		DBG(("%s: dst pitch (%d) fits within render pipeline (%d)\n",
 		     __FUNCTION__, op->dst.bo->pitch, sna->render.max_3d_pitch));
 
-		kgem_get_tile_size(&sna->kgem, op->dst.bo->tiling,
-				   &tile_width, &tile_height, &tile_size);
-
 		box.x1 = x;
 		box.x2 = x + width;
 		box.y1 = y;
 		box.y2 = y + height;
 
 		/* Ensure we align to an even tile row */
-		box.y1 = box.y1 & ~(2*tile_height - 1);
-		box.y2 = ALIGN(box.y2, 2*tile_height);
+		if (op->dst.bo->tiling) {
+			int tile_width, tile_height, tile_size;
+
+			kgem_get_tile_size(&sna->kgem, op->dst.bo->tiling,
+					   &tile_width, &tile_height, &tile_size);
+
+			box.y1 = box.y1 & ~(2*tile_height - 1);
+			box.y2 = ALIGN(box.y2, 2*tile_height);
+
+			box.x1 = box.x1 & ~(tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel - 1);
+			box.x2 = ALIGN(box.x2, tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel);
+
+			offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
+		} else
+			offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8;
+
 		if (box.y2 > op->dst.pixmap->drawable.height)
 			box.y2 = op->dst.pixmap->drawable.height;
 
-		box.x1 = box.x1 & ~(tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel - 1);
-		box.x2 = ALIGN(box.x2, tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel);
 		if (box.x2 > op->dst.pixmap->drawable.width)
 			box.x2 = op->dst.pixmap->drawable.width;
 
 		w = box.x2 - box.x1;
 		h = box.y2 - box.y1;
-		DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__,
+		DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d), max %d\n", __FUNCTION__,
 		     box.x1, box.y1, box.x2, box.y2, w, h,
 		     op->dst.pixmap->drawable.width,
-		     op->dst.pixmap->drawable.height));
+		     op->dst.pixmap->drawable.height,
+		     sna->render.max_3d_size));
 		if (w <= sna->render.max_3d_size &&
 		    h <= sna->render.max_3d_size) {
-			int offset;
-
 			t->box.x2 = t->box.x1 = op->dst.x;
 			t->box.y2 = t->box.y1 = op->dst.y;
 			t->real_bo = op->dst.bo;
@@ -1695,7 +1724,6 @@ sna_render_composite_redirect(struct sna *sna,
 			}
 
 			/* How many tiles across are we? */
-			offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
 			op->dst.bo = kgem_create_proxy(op->dst.bo,
 						       box.y1 * op->dst.bo->pitch + offset,
 						       h * op->dst.bo->pitch);


More information about the xorg-commit mailing list