xf86-video-intel: 9 commits - src/sna/fb 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_blt.c src/sna/sna_composite.c src/sna/sna_damage.c src/sna/sna_render.c src/sna/sna_render.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Aug 19 02:29:38 PDT 2012


 src/sna/fb/fbbitmap.c    |    4 
 src/sna/gen2_render.c    |    4 
 src/sna/gen3_render.c    |    2 
 src/sna/gen4_render.c    |    3 
 src/sna/gen5_render.c    |    3 
 src/sna/gen6_render.c    |    6 
 src/sna/gen7_render.c    |    6 
 src/sna/sna_blt.c        |  326 ++++++++++++++++++++++++++++++++++++++---------
 src/sna/sna_composite.c  |    7 -
 src/sna/sna_damage.c     |   46 +++++-
 src/sna/sna_render.c     |   93 +++----------
 src/sna/sna_render.h     |    3 
 src/sna/sna_trapezoids.c |   28 +++-
 13 files changed, 376 insertions(+), 155 deletions(-)

New commits:
commit 13d1a105159222518800d3c5ad5660725864ec6b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Aug 19 09:48:05 2012 +0100

    sna: compare the correct trailing dword when skipping identical bitmap lines
    
    Fixes regression in 2.20.4 from
    
    commit 85192f00e345830541e3715e211b1f98154bbef4
    Author: Chris Wilson <chris at chris-wilson.co.uk>
    Date:   Wed Aug 8 12:11:50 2012 +0100
    
        sna: Ignore trailing bits when comparing lines inside the bitmap
    
    Reported-by: Edward Sheldrake <ejsheldrake at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=53699
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/fb/fbbitmap.c b/src/sna/fb/fbbitmap.c
index bba6ea3..7c037fe 100644
--- a/src/sna/fb/fbbitmap.c
+++ b/src/sna/fb/fbbitmap.c
@@ -88,9 +88,7 @@ fbBitmapToRegion(PixmapPtr pixmap)
 		line += stride;
 		while (y2 < pixmap->drawable.height &&
 		       memcmp(bits, line, width >> 3) == 0 &&
-		       (maskw == 0 ||
-			(bits[width >> (FB_SHIFT - 3)] & maskw) ==
-			(line[width >> (FB_SHIFT - 3)] & maskw)))
+		       (maskw == 0 || (bits[width >> FB_SHIFT] & maskw) == (line[width >> FB_SHIFT] & maskw)))
 			line += stride, y2++;
 
 		if (READ(bits) & MASK_0)
commit a13781d19defc97af6a279c11a85e33ef825020e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Aug 19 09:45:12 2012 +0100

    sna: Enable BLT composite functions to target CPU buffers
    
    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 9824202..f050669 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -760,6 +760,65 @@ static void blt_composite_fill(struct sna *sna,
 	sna_blt_fill_one(sna, &op->u.blt, x1, y1, x2-x1, y2-y1);
 }
 
+fastcall
+static void blt_composite_fill__cpu(struct sna *sna,
+				    const struct sna_composite_op *op,
+				    const struct sna_composite_rectangles *r)
+{
+	int x1, x2, y1, y2;
+
+	x1 = r->dst.x + op->dst.x;
+	y1 = r->dst.y + op->dst.y;
+	x2 = x1 + r->width;
+	y2 = y1 + r->height;
+
+	if (x1 < 0)
+		x1 = 0;
+	if (y1 < 0)
+		y1 = 0;
+
+	if (x2 > op->dst.width)
+		x2 = op->dst.width;
+	if (y2 > op->dst.height)
+		y2 = op->dst.height;
+
+	if (x2 <= x1 || y2 <= y1)
+		return;
+
+	pixman_fill(op->dst.pixmap->devPrivate.ptr,
+		    op->dst.pixmap->devKind / sizeof(uint32_t),
+		    op->dst.pixmap->drawable.bitsPerPixel,
+		    x1, y1, x2-x1, y2-y1,
+		    op->u.blt.pixel);
+}
+
+fastcall static void
+blt_composite_fill_box__cpu(struct sna *sna,
+			    const struct sna_composite_op *op,
+			    const BoxRec *box)
+{
+	pixman_fill(op->dst.pixmap->devPrivate.ptr,
+		    op->dst.pixmap->devKind / sizeof(uint32_t),
+		    op->dst.pixmap->drawable.bitsPerPixel,
+		    box->x1, box->y1, box->x2-box->x1, box->y2-box->y1,
+		    op->u.blt.pixel);
+}
+
+static void
+blt_composite_fill_boxes__cpu(struct sna *sna,
+			      const struct sna_composite_op *op,
+			      const BoxRec *box, int n)
+{
+	do {
+		pixman_fill(op->dst.pixmap->devPrivate.ptr,
+			    op->dst.pixmap->devKind / sizeof(uint32_t),
+			    op->dst.pixmap->drawable.bitsPerPixel,
+			    box->x1, box->y1, box->x2-box->x1, box->y2-box->y1,
+			    op->u.blt.pixel);
+		box++;
+	} while (--n);
+}
+
 inline static void _sna_blt_fill_box(struct sna *sna,
 				     const struct sna_blt_state *blt,
 				     const BoxRec *box)
@@ -932,6 +991,15 @@ prepare_blt_clear(struct sna *sna,
 {
 	DBG(("%s\n", __FUNCTION__));
 
+	if (op->dst.bo == NULL) {
+		op->blt   = blt_composite_fill__cpu;
+		op->box   = blt_composite_fill_box__cpu;
+		op->boxes = blt_composite_fill_boxes__cpu;
+		op->done  = nop_done;
+		op->u.blt.pixel = 0;
+		return true;
+	}
+
 	op->blt = blt_composite_fill;
 	if (op->dst.x|op->dst.y) {
 		op->box   = blt_composite_fill_box;
@@ -958,6 +1026,15 @@ prepare_blt_fill(struct sna *sna,
 {
 	DBG(("%s\n", __FUNCTION__));
 
+	if (op->dst.bo == NULL) {
+		op->u.blt.pixel = get_solid_color(source, op->dst.format);
+		op->blt = blt_composite_fill__cpu;
+		op->box   = blt_composite_fill_box__cpu;
+		op->boxes = blt_composite_fill_boxes__cpu;
+		op->done = nop_done;
+		return true;
+	}
+
 	op->blt = blt_composite_fill;
 	if (op->dst.x|op->dst.y) {
 		op->box   = blt_composite_fill_box;
@@ -1143,6 +1220,9 @@ prepare_blt_copy(struct sna *sna,
 {
 	PixmapPtr src = op->u.blt.src_pixmap;
 
+	assert(op->dst.bo);
+	assert(kgem_bo_can_blt(&sna->kgem, op->dst.bo));
+
 	if (!kgem_bo_can_blt(&sna->kgem, bo)) {
 		DBG(("%s: fallback -- can't blt from source\n", __FUNCTION__));
 		return false;
@@ -1189,6 +1269,100 @@ prepare_blt_copy(struct sna *sna,
 }
 
 fastcall static void
+blt_put_composite__cpu(struct sna *sna,
+		       const struct sna_composite_op *op,
+		       const struct sna_composite_rectangles *r)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr,
+		   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+		   r->src.x + op->u.blt.sx, r->src.y + op->u.blt.sy,
+		   r->width, r->height,
+		   r->dst.x + op->dst.x, r->dst.y + op->dst.y);
+}
+
+fastcall static void
+blt_put_composite_box__cpu(struct sna *sna,
+			   const struct sna_composite_op *op,
+			   const BoxRec *box)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr,
+		   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+		   box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy,
+		   box->x2-box->x1, box->y2-box->y1,
+		   box->x1 + op->dst.x, box->y1 + op->dst.y);
+}
+
+static void
+blt_put_composite_boxes__cpu(struct sna *sna,
+			     const struct sna_composite_op *op,
+			     const BoxRec *box, int n)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	do {
+		memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr,
+			   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+			   box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy,
+			   box->x2-box->x1, box->y2-box->y1,
+			   box->x1 + op->dst.x, box->y1 + op->dst.y);
+		box++;
+	} while (--n);
+}
+
+fastcall static void
+blt_put_composite_with_alpha__cpu(struct sna *sna,
+				  const struct sna_composite_op *op,
+				  const struct sna_composite_rectangles *r)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr,
+		   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+		   r->src.x + op->u.blt.sx, r->src.y + op->u.blt.sy,
+		   r->width, r->height,
+		   r->dst.x + op->dst.x, r->dst.y + op->dst.y,
+		   0xffffffff, op->u.blt.pixel);
+
+}
+
+fastcall static void
+blt_put_composite_box_with_alpha__cpu(struct sna *sna,
+				      const struct sna_composite_op *op,
+				      const BoxRec *box)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr,
+		   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+		   box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy,
+		   box->x2-box->x1, box->y2-box->y1,
+		   box->x1 + op->dst.x, box->y1 + op->dst.y,
+		   0xffffffff, op->u.blt.pixel);
+}
+
+static void
+blt_put_composite_boxes_with_alpha__cpu(struct sna *sna,
+					const struct sna_composite_op *op,
+					const BoxRec *box, int n)
+{
+	PixmapPtr dst = op->dst.pixmap;
+	PixmapPtr src = op->u.blt.src_pixmap;
+	do {
+		memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr,
+			   src->drawable.bitsPerPixel, src->devKind, dst->devKind,
+			   box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy,
+			   box->x2-box->x1, box->y2-box->y1,
+			   box->x1 + op->dst.x, box->y1 + op->dst.y,
+			   0xffffffff, op->u.blt.pixel);
+		box++;
+	} while (--n);
+}
+
+fastcall static void
 blt_put_composite(struct sna *sna,
 		  const struct sna_composite_op *op,
 		  const struct sna_composite_rectangles *r)
@@ -1439,46 +1613,34 @@ prepare_blt_put(struct sna *sna,
 	assert(src->devKind);
 	assert(src->devPrivate.ptr);
 
-	if (alpha_fixup) {
-		op->u.blt.pixel = alpha_fixup;
-		op->blt   = blt_put_composite_with_alpha;
-		op->box   = blt_put_composite_box_with_alpha;
-		op->boxes = blt_put_composite_boxes_with_alpha;
+	if (op->dst.bo) {
+		if (alpha_fixup) {
+			op->u.blt.pixel = alpha_fixup;
+			op->blt   = blt_put_composite_with_alpha;
+			op->box   = blt_put_composite_box_with_alpha;
+			op->boxes = blt_put_composite_boxes_with_alpha;
+		} else {
+			op->blt   = blt_put_composite;
+			op->box   = blt_put_composite_box;
+			op->boxes = blt_put_composite_boxes;
+		}
 	} else {
-		op->blt   = blt_put_composite;
-		op->box   = blt_put_composite_box;
-		op->boxes = blt_put_composite_boxes;
+		if (alpha_fixup) {
+			op->u.blt.pixel = alpha_fixup;
+			op->blt   = blt_put_composite_with_alpha__cpu;
+			op->box   = blt_put_composite_box_with_alpha__cpu;
+			op->boxes = blt_put_composite_boxes_with_alpha__cpu;
+		} else {
+			op->blt   = blt_put_composite__cpu;
+			op->box   = blt_put_composite_box__cpu;
+			op->boxes = blt_put_composite_boxes__cpu;
+		}
 	}
 	op->done = nop_done;
 
 	return true;
 }
 
-static void
-reduce_damage(struct sna_composite_op *op,
-	      int dst_x, int dst_y,
-	      int width, int height)
-{
-	BoxRec r;
-
-	if (op->damage == NULL || *op->damage == NULL)
-		return;
-
-	if ((*op->damage)->mode == DAMAGE_ALL) {
-		op->damage = NULL;
-		return;
-	}
-
-	r.x1 = dst_x + op->dst.x;
-	r.x2 = r.x1 + width;
-
-	r.y1 = dst_y + op->dst.y;
-	r.y2 = r.y1 + height;
-
-	if (sna_damage_contains_box__no_reduce(*op->damage, &r))
-		op->damage = NULL;
-}
-
 #define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format),		\
 				      PICT_FORMAT_TYPE(format),		\
 				      0,				\
@@ -1499,10 +1661,9 @@ sna_blt_composite(struct sna *sna,
 {
 	PictFormat src_format = src->format;
 	PixmapPtr src_pixmap;
-	struct sna_pixmap *priv;
 	struct kgem_bo *bo;
 	int16_t tx, ty;
-	BoxRec box;
+	BoxRec dst_box, src_box;
 	uint32_t alpha_fixup;
 	bool was_clear;
 	bool ret;
@@ -1527,14 +1688,13 @@ sna_blt_composite(struct sna *sna,
 
 	was_clear = sna_drawable_is_clear(dst->pDrawable);
 	tmp->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
-	priv = sna_pixmap_move_to_gpu(tmp->dst.pixmap, MOVE_WRITE | MOVE_READ);
-	if (priv == NULL) {
-		DBG(("%s: dst not attached\n", __FUNCTION__));
-		return false;
-	}
-	if (!kgem_bo_can_blt(&sna->kgem, priv->gpu_bo)) {
+
+	dst_box.x1 = dst_x; dst_box.x2 = dst_x + width;
+	dst_box.y1 = dst_y; dst_box.y2 = dst_y + height;
+	bo = sna_drawable_use_bo(dst->pDrawable, PREFER_GPU, &dst_box, &tmp->damage);
+	if (bo && !kgem_bo_can_blt(&sna->kgem, bo)) {
 		DBG(("%s: can not blit to dst, tiling? %d, pitch? %d\n",
-		     __FUNCTION__, priv->gpu_bo->tiling, priv->gpu_bo->pitch));
+		     __FUNCTION__, bo->tiling, bo->pitch));
 		return false;
 	}
 
@@ -1543,19 +1703,24 @@ sna_blt_composite(struct sna *sna,
 	tmp->dst.height = tmp->dst.pixmap->drawable.height;
 	get_drawable_deltas(dst->pDrawable, tmp->dst.pixmap,
 			    &tmp->dst.x, &tmp->dst.y);
-	tmp->dst.bo = priv->gpu_bo;
-	if (!sna_damage_is_all(&priv->gpu_damage,
-			       tmp->dst.width, tmp->dst.height))
-		tmp->damage = &priv->gpu_damage;
-	if (width && height)
-		reduce_damage(tmp, dst_x, dst_y, width, height);
+	tmp->dst.bo = bo;
 
 	if (op == PictOpClear) {
 clear:
 		if (was_clear)
 			return prepare_blt_nop(sna, tmp);
-		else
-			return prepare_blt_clear(sna, tmp);
+
+		if (!tmp->dst.bo) {
+			RegionRec region;
+
+			region.extents = dst_box;
+			region.data = NULL;
+
+			if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
+							     MOVE_INPLACE_HINT | MOVE_WRITE))
+				return false;
+		}
+		return prepare_blt_clear(sna, tmp);
 	}
 
 	if (is_solid(src)) {
@@ -1574,6 +1739,17 @@ clear:
 			return false;
 		}
 
+		if (!tmp->dst.bo) {
+			RegionRec region;
+
+			region.extents = dst_box;
+			region.data = NULL;
+
+			if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
+							MOVE_INPLACE_HINT | MOVE_WRITE))
+				return false;
+		}
+
 		return prepare_blt_fill(sna, tmp, src);
 	}
 
@@ -1659,15 +1835,44 @@ clear:
 	     tmp->dst.x, tmp->dst.y, tmp->u.blt.sx, tmp->u.blt.sy, alpha_fixup));
 
 	ret = false;
-	box.x1 = x;
-	box.y1 = y;
-	box.x2 = x + width;
-	box.y2 = y + height;
-	bo = __sna_render_pixmap_bo(sna, src_pixmap, &box, true);
-	if (bo)
-		ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup);
-	if (!ret && (bo == NULL || fallback))
+	src_box.x1 = x;
+	src_box.y1 = y;
+	src_box.x2 = x + width;
+	src_box.y2 = y + height;
+	bo = __sna_render_pixmap_bo(sna, src_pixmap, &src_box, true);
+	if (bo) {
+		if (!tmp->dst.bo)
+			tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable,
+							  FORCE_GPU | PREFER_GPU,
+							  &dst_box,
+							  &tmp->damage);
+
+		if (!tmp->dst.bo) {
+			DBG(("%s: fallback -- unaccelerated read back\n",
+			     __FUNCTION__));
+			kgem_bo_destroy(&sna->kgem, bo);
+		} else if (bo->snoop && tmp->dst.bo->snoop) {
+			DBG(("%s: fallback -- can not copy between snooped bo\n",
+			     __FUNCTION__));
+			kgem_bo_destroy(&sna->kgem, bo);
+		} else {
+			ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup);
+			if (fallback)
+				ret = prepare_blt_put(sna, tmp, alpha_fixup);
+		}
+	} else {
+		if (!tmp->dst.bo) {
+			RegionRec region;
+
+			region.extents = dst_box;
+			region.data = NULL;
+
+			if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
+							MOVE_INPLACE_HINT | MOVE_WRITE))
+				return false;
+		}
 		ret = prepare_blt_put(sna, tmp, alpha_fixup);
+	}
 
 	return ret;
 }
@@ -2264,7 +2469,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 				assert(box->y1 >= 0);
 
 				*(uint64_t *)&b[0] = hdr;
-				*(uint64_t *)&b[2] = *(uint64_t *)box;
+				*(uint64_t *)&b[2] = *(const uint64_t *)box;
 				b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
 						      I915_GEM_DOMAIN_RENDER << 16 |
 						      I915_GEM_DOMAIN_RENDER |
commit be940856c74fbedd27997dd61e2a85959b321193
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 21:23:03 2012 +0100

    sna: Consider sample wraparound in each direction independently
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 0f1fa4b..7b54f23 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -592,14 +592,10 @@ sna_render_pixmap_bo(struct sna *sna,
 			if (box.y2 > pixmap->drawable.height)
 				box.y2 = pixmap->drawable.height;
 		} else {
-			if (box.x1 < 0 ||
-			    box.y1 < 0 ||
-			    box.x2 > pixmap->drawable.width ||
-			    box.y2 > pixmap->drawable.height) {
-				box.x1 = box.y1 = 0;
-				box.x2 = pixmap->drawable.width;
-				box.y2 = pixmap->drawable.height;
-			}
+			if (box.x1 < 0 || box.x2 > pixmap->drawable.width)
+				box.x1 = 0, box.x2 = pixmap->drawable.width;
+			if (box.y1 < 0 || box.y2 > pixmap->drawable.height)
+				box.y1 = 0, box.y2 = pixmap->drawable.height;
 		}
 	}
 
@@ -681,25 +677,12 @@ static int sna_render_picture_downsample(struct sna *sna,
 		if (box.y2 > pixmap->drawable.height)
 			box.y2 = pixmap->drawable.height;
 	} else {
-		if (box.x1 < 0 ||
-		    box.y1 < 0 ||
-		    box.x2 > pixmap->drawable.width ||
-		    box.y2 > pixmap->drawable.height) {
-			/* XXX tiled repeats? */
-			box.x1 = box.y1 = 0;
-			box.x2 = pixmap->drawable.width;
-			box.y2 = pixmap->drawable.height;
+		/* XXX tiled repeats? */
+		if (box.x1 < 0 || box.x2 > pixmap->drawable.width)
+			box.x1 = 0, box.x2 = pixmap->drawable.width;
+		if (box.y1 < 0 || box.y2 > pixmap->drawable.height)
+			box.y1 = 0, box.y2 = pixmap->drawable.height;
 
-			if (!channel->is_affine) {
-				DBG(("%s: fallback -- repeating project transform too large for texture\n",
-				     __FUNCTION__));
-				return sna_render_picture_fixup(sna,
-								picture,
-								channel,
-								x, y, w, h,
-								dst_x, dst_y);
-			}
-		}
 	}
 
 	sw = box.x2 - box.x1;
@@ -964,17 +947,10 @@ sna_render_picture_partial(struct sna *sna,
 		if (box.y2 > pixmap->drawable.height)
 			box.y2 = pixmap->drawable.height;
 	} else {
-		if (box.x1 < 0 ||
-		    box.y1 < 0 ||
-		    box.x2 > pixmap->drawable.width ||
-		    box.y2 > pixmap->drawable.height) {
-			box.x1 = box.y1 = 0;
-			box.x2 = pixmap->drawable.width;
-			box.y2 = pixmap->drawable.height;
-
-			if (!channel->is_affine)
-				return 0;
-		}
+		if (box.x1 < 0 || box.x2 > pixmap->drawable.width)
+			box.x1 = 0, box.x2 = pixmap->drawable.width;
+		if (box.y1 < 0 || box.y2 > pixmap->drawable.height)
+			box.y1 = 0, box.y2 = pixmap->drawable.height;
 	}
 
 	if (use_cpu_bo(sna, pixmap, &box, false)) {
@@ -1124,25 +1100,11 @@ sna_render_picture_extract(struct sna *sna,
 		if (box.y2 > pixmap->drawable.height)
 			box.y2 = pixmap->drawable.height;
 	} else {
-		if (box.x1 < 0 ||
-		    box.y1 < 0 ||
-		    box.x2 > pixmap->drawable.width ||
-		    box.y2 > pixmap->drawable.height) {
-			/* XXX tiled repeats? */
-			box.x1 = box.y1 = 0;
-			box.x2 = pixmap->drawable.width;
-			box.y2 = pixmap->drawable.height;
-
-			if (!channel->is_affine) {
-				DBG(("%s: fallback -- repeating project transform too large for texture\n",
-				     __FUNCTION__));
-				return sna_render_picture_fixup(sna,
-								picture,
-								channel,
-								x, y, ow, oh,
-								dst_x, dst_y);
-			}
-		}
+		/* XXX tiled repeats? */
+		if (box.x1 < 0 || box.x2 > pixmap->drawable.width)
+			box.x1 = 0, box.x2 = pixmap->drawable.width;
+		if (box.y1 < 0 || box.y2 > pixmap->drawable.height)
+			box.y1 = 0, box.y2 = pixmap->drawable.height;
 	}
 
 	w = box.x2 - box.x1;
commit 110c7ef7f6c31929affa038918e6ce087bccddc6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 17:42:51 2012 +0100

    sna/damage: Replace the damage with a larger box if subsumed
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index ff76688..0390bf9 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -562,6 +562,12 @@ static void _pixman_region_union_box(RegionRec *region, const BoxRec *box)
 	pixman_region_union(region, region, &u);
 }
 
+static bool box_contains_region(const BoxRec *b, const RegionRec *r)
+{
+	return (b->x1 <= r->extents.x1 && b->x2 >= r->extents.x2 &&
+		b->y1 <= r->extents.y1 && b->y2 >= r->extents.y2);
+}
+
 static struct sna_damage *__sna_damage_add_box(struct sna_damage *damage,
 					       const BoxRec *box)
 {
@@ -581,7 +587,8 @@ static struct sna_damage *__sna_damage_add_box(struct sna_damage *damage,
 		break;
 	}
 
-	if (REGION_NUM_RECTS(&damage->region) <= 1) {
+	if (REGION_NUM_RECTS(&damage->region) <= 1 ||
+	    box_contains_region(box, &damage->region)) {
 		_pixman_region_union_box(&damage->region, box);
 		assert(damage->region.extents.x2 > damage->region.extents.x1);
 		assert(damage->region.extents.y2 > damage->region.extents.y1);
commit 75a2fab766d8aed180ef795919e503db22c0e0fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 17:28:08 2012 +0100

    sna: Avoid forcing an upload for an unblittable bo unless on a fallback path
    
    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 ecccbbb..31859b4 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1722,7 +1722,7 @@ gen2_render_composite(struct sna *sna,
 				 src, dst,
 				 src_x, src_y,
 				 dst_x, dst_y,
-				 width, height, tmp);
+				 width, height, tmp, true);
 #endif
 
 	/* Try to use the BLT engine unless it implies a
@@ -1735,7 +1735,7 @@ gen2_render_composite(struct sna *sna,
 			      src_x, src_y,
 			      dst_x, dst_y,
 			      width, height,
-			      tmp))
+			      tmp, false))
 		return true;
 
 	if (gen2_composite_fallback(sna, src, mask, dst))
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index c44359f..5b0894e 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2812,7 +2812,7 @@ gen3_render_composite(struct sna *sna,
 			      src_x, src_y,
 			      dst_x, dst_y,
 			      width, height,
-			      tmp))
+			      tmp, false))
 		return true;
 
 	if (gen3_composite_fallback(sna, op, src, mask, dst))
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index ab06295..a56ef79 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2271,7 +2271,8 @@ gen4_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	if (gen4_composite_fallback(sna, src, mask, dst))
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 488ac34..71e77a4 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2284,7 +2284,8 @@ gen5_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	if (gen5_composite_fallback(sna, src, mask, dst))
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index f8b1e71..710a35e 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2654,7 +2654,8 @@ gen6_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	if (gen6_composite_fallback(sna, src, mask, dst))
@@ -2679,7 +2680,8 @@ gen6_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 318cbef..8a281e5 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2756,7 +2756,8 @@ gen7_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	if (gen7_composite_fallback(sna, src, mask, dst))
@@ -2782,7 +2783,8 @@ gen7_render_composite(struct sna *sna,
 			      src, dst,
 			      src_x, src_y,
 			      dst_x, dst_y,
-			      width, height, tmp))
+			      width, height,
+			      tmp, false))
 		return true;
 
 	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 819d24a..9824202 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1494,7 +1494,8 @@ sna_blt_composite(struct sna *sna,
 		  int16_t x, int16_t y,
 		  int16_t dst_x, int16_t dst_y,
 		  int16_t width, int16_t height,
-		  struct sna_composite_op *tmp)
+		  struct sna_composite_op *tmp,
+		  bool fallback)
 {
 	PictFormat src_format = src->format;
 	PixmapPtr src_pixmap;
@@ -1665,7 +1666,7 @@ clear:
 	bo = __sna_render_pixmap_bo(sna, src_pixmap, &box, true);
 	if (bo)
 		ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup);
-	if (!ret)
+	if (!ret && (bo == NULL || fallback))
 		ret = prepare_blt_put(sna, tmp, alpha_fixup);
 
 	return ret;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 757b2f4..0f1fa4b 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -84,20 +84,19 @@ no_render_composite(struct sna *sna,
 {
 	DBG(("%s (op=%d, mask? %d)\n", __FUNCTION__, op, mask != NULL));
 
+	if (mask)
+		return false;
+
 	if (!is_gpu(dst->pDrawable) &&
 	    (src->pDrawable == NULL || !is_gpu(src->pDrawable)))
 		return false;
 
-	if (mask == NULL &&
-	    sna_blt_composite(sna,
-			      op, src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height,
-			      tmp))
-		return true;
-
-	return false;
+	return sna_blt_composite(sna,
+				 op, src, dst,
+				 src_x, src_y,
+				 dst_x, dst_y,
+				 width, height,
+				 tmp, true);
 	(void)mask_x;
 	(void)mask_y;
 }
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index b079178..442c78d 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -569,7 +569,8 @@ bool sna_blt_composite(struct sna *sna,
 		       int16_t src_x, int16_t src_y,
 		       int16_t dst_x, int16_t dst_y,
 		       int16_t width, int16_t height,
-		       struct sna_composite_op *tmp);
+		       struct sna_composite_op *tmp,
+		       bool fallback);
 bool sna_blt_composite__convert(struct sna *sna,
 				int x, int y,
 				int width, int height,
commit 110d5519f3523b1e2c50db637cdc4c5bc44c960a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 16:39:52 2012 +0100

    sna: Reduce subtracted damage earlier
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index c7fe4c6..ff76688 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -1019,6 +1019,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 		return NULL;
 
 	if (!RegionNotEmpty(&damage->region)) {
+no_damage:
 		__sna_damage_destroy(damage);
 		return NULL;
 	}
@@ -1029,15 +1030,17 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 		return damage;
 
 	if (region_is_singular(region) &&
-	    box_contains(&region->extents, &damage->extents)) {
-		__sna_damage_destroy(damage);
-		return NULL;
-	}
+	    box_contains(&region->extents, &damage->extents))
+		goto no_damage;
 
 	if (damage->mode == DAMAGE_ALL) {
 		pixman_region_subtract(&damage->region,
 				       &damage->region,
 				       region);
+		if (damage->region.extents.x2 <= damage->region.extents.x1 ||
+		    damage->region.extents.y2 <= damage->region.extents.y1)
+			goto no_damage;
+
 		damage->extents = damage->region.extents;
 		damage->mode = DAMAGE_ADD;
 		return damage;
@@ -1049,16 +1052,18 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 			assert(RegionNotEmpty(&damage->region));
 		}
 
-		if (pixman_region_equal(region, &damage->region)) {
-			__sna_damage_destroy(damage);
-			return NULL;
-		}
+		if (pixman_region_equal(region, &damage->region))
+			goto no_damage;
 
 		if (region_is_singular(&damage->region) &&
 		    region_is_singular(region)) {
 			pixman_region_subtract(&damage->region,
 					       &damage->region,
 					       region);
+			if (damage->region.extents.x2 <= damage->region.extents.x1 ||
+			    damage->region.extents.y2 <= damage->region.extents.y1)
+				goto no_damage;
+
 			damage->extents = damage->region.extents;
 			assert(pixman_region_not_empty(&damage->region));
 			return damage;
commit 8812e8b6e89e6432a6a768a0566ce4c153e9b256
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 16:21:13 2012 +0100

    sna: Reduce damage after a large composite operation
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 72a5a94..d47479b 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -412,7 +412,12 @@ static void apply_damage(struct sna_composite_op *op, RegionPtr region)
 		RegionTranslate(region, op->dst.x, op->dst.y);
 
 	assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region));
-	sna_damage_add(op->damage, region);
+	if (region->data == NULL &&
+	    region->extents.x2 - region->extents.x1 == op->dst.width &&
+	    region->extents.y2 - region->extents.y1 == op->dst.height)
+		sna_damage_all(op->damage, op->dst.width, op->dst.height);
+	else
+		sna_damage_add(op->damage, region);
 }
 
 static inline bool use_cpu(PixmapPtr pixmap, struct sna_pixmap *priv,
commit e361627b90ea6bf2f9a8c46cf8debe562fdf4f09
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 16:16:17 2012 +0100

    sna/damage: Add some more sanity checks for creating empty regions
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index 7d78372..c7fe4c6 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -552,6 +552,8 @@ static void damage_union(struct sna_damage *damage, const BoxRec *box)
 		if (damage->extents.y2 < box->y2)
 			damage->extents.y2 = box->y2;
 	}
+	assert(damage->extents.x2 > damage->extents.x1);
+	assert(damage->extents.y2 > damage->extents.y1);
 }
 
 static void _pixman_region_union_box(RegionRec *region, const BoxRec *box)
@@ -581,6 +583,8 @@ static struct sna_damage *__sna_damage_add_box(struct sna_damage *damage,
 
 	if (REGION_NUM_RECTS(&damage->region) <= 1) {
 		_pixman_region_union_box(&damage->region, box);
+		assert(damage->region.extents.x2 > damage->region.extents.x1);
+		assert(damage->region.extents.y2 > damage->region.extents.y1);
 		damage_union(damage, box);
 		return damage;
 	}
@@ -616,6 +620,8 @@ inline static struct sna_damage *__sna_damage_add(struct sna_damage *damage,
 
 	if (REGION_NUM_RECTS(&damage->region) <= 1) {
 		pixman_region_union(&damage->region, &damage->region, region);
+		assert(damage->region.extents.x2 > damage->region.extents.x1);
+		assert(damage->region.extents.y2 > damage->region.extents.y1);
 		damage_union(damage, &region->extents);
 		return damage;
 	}
@@ -645,6 +651,8 @@ fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage,
 
 	ErrorF("  = %s\n",
 	       _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
+	assert(damage->region.extents.x2 > damage->region.extents.x1);
+	assert(damage->region.extents.y2 > damage->region.extents.y1);
 
 	return damage;
 }
@@ -726,6 +734,8 @@ struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage,
 
 	ErrorF("  = %s\n",
 	       _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
+	assert(damage->region.extents.x2 > damage->region.extents.x1);
+	assert(damage->region.extents.y2 > damage->region.extents.y1);
 
 	return damage;
 }
@@ -811,6 +821,8 @@ struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage,
 
 	ErrorF("  = %s\n",
 	       _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
+	assert(damage->region.extents.x2 > damage->region.extents.x1);
+	assert(damage->region.extents.y2 > damage->region.extents.y1);
 
 	return damage;
 }
@@ -893,6 +905,8 @@ struct sna_damage *_sna_damage_add_points(struct sna_damage *damage,
 
 	ErrorF("  = %s\n",
 	       _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
+	assert(damage->region.extents.x2 > damage->region.extents.x1);
+	assert(damage->region.extents.y2 > damage->region.extents.y1);
 
 	return damage;
 }
@@ -919,6 +933,8 @@ fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage,
 
 	ErrorF("  = %s\n",
 	       _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
+	assert(damage->region.extents.x2 > damage->region.extents.x1);
+	assert(damage->region.extents.y2 > damage->region.extents.y1);
 
 	return damage;
 }
commit 10f334872e9dd190e18c768219e60815acabe4d3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Aug 18 15:49:02 2012 +0100

    sna: Add damage for the whole unaligned trapezoid not per component
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index e63981f..a1141f1 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -2739,18 +2739,14 @@ composite_unaligned_box(struct sna *sna,
 
 		pixman_region_init_rects(&region, box, 1);
 		RegionIntersect(&region, &region, clip);
-		if (REGION_NUM_RECTS(&region)) {
+		if (REGION_NUM_RECTS(&region))
 			tmp->boxes(sna, tmp,
 				   REGION_RECTS(&region),
 				   REGION_NUM_RECTS(&region),
 				   opacity);
-			apply_damage(&tmp->base, &region);
-		}
 		pixman_region_fini(&region);
-	} else {
+	} else
 		tmp->box(sna, tmp, box, opacity);
-		apply_damage_box(&tmp->base, box);
-	}
 }
 
 static void
@@ -2869,6 +2865,26 @@ composite_unaligned_trap(struct sna *sna,
 						     grid_coverage(SAMPLES_Y, trap->bottom),
 						     clip);
 	}
+
+	if (tmp->base.damage) {
+		BoxRec box;
+
+		box.x1 = dx + pixman_fixed_to_int(trap->left.p1.x);
+		box.x2 = dx + pixman_fixed_to_int(trap->right.p1.x);
+		box.y1 = y1;
+		box.y2 = y2 + (pixman_fixed_frac(trap->bottom) != 0);
+
+		if (clip) {
+			pixman_region16_t region;
+
+			pixman_region_init_rects(&region, &box, 1);
+			RegionIntersect(&region, &region, clip);
+			if (REGION_NUM_RECTS(&region))
+				apply_damage(&tmp->base, &region);
+			RegionUninit(&region);
+		} else
+			apply_damage_box(&tmp->base, &box);
+	}
 }
 
 inline static void


More information about the xorg-commit mailing list