xf86-video-intel: 6 commits - src/sna/compiler.h src/sna/kgem.h src/sna/Makefile.am src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_damage.c src/sna/sna.h src/sna/sna_reg.h src/sna/sna_render.h src/sna/sna_render_inline.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 19 05:54:24 PDT 2011


 src/sna/Makefile.am         |    1 
 src/sna/compiler.h          |   43 +++++
 src/sna/kgem.h              |   10 -
 src/sna/sna.h               |   12 +
 src/sna/sna_accel.c         |  374 ++++++++++++++++++++------------------------
 src/sna/sna_blt.c           |  114 +++++++++----
 src/sna/sna_composite.c     |    4 
 src/sna/sna_damage.c        |   12 +
 src/sna/sna_reg.h           |    2 
 src/sna/sna_render.h        |    4 
 src/sna/sna_render_inline.h |    2 
 src/sna/sna_trapezoids.c    |    4 
 12 files changed, 329 insertions(+), 253 deletions(-)

New commits:
commit 5515f75647bb148d9e720dcc4713a93b59ffbd49
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 13:49:55 2011 +0100

    sna: Enlarge the minimum pixmap size to migrate for Render
    
    This is to workaround a ping-pong issue involving small icons. The
    horrible sequence of operations appears to use a tiled FillRect to copy
    from the scanout onto to a temporary pixmap, which causes us to
    readback from the scanout. We are destined to hit the fallback path there
    anyway until we implement stippling...
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=41718
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index a2bee0c..fe6d5b8 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -87,7 +87,7 @@ is_dirty_gpu(DrawablePtr drawable)
 static inline Bool
 too_small(DrawablePtr drawable)
 {
-	return (drawable->width * drawable->height <= 256) &&
+	return (drawable->width * drawable->height * drawable->bitsPerPixel <= 8*4096) &&
 		!is_dirty_gpu(drawable);
 }
 
commit 87ba33bc0bcaf3c5160edfc61cff3ba0d28d3fd8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 13:09:19 2011 +0100

    sna/damage: Avoid reducing the damage for simple tests
    
    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 efb1cfe..f6ffef0 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -480,7 +480,7 @@ struct sna_damage *_sna_damage_is_all(struct sna_damage *damage,
 	BoxRec box;
 
 	if (damage->mode == SUBTRACT)
-		__sna_damage_reduce(damage);
+		return damage;
 
 	box.x1 = box.y1 = 0;
 	box.x2 = width;
@@ -658,8 +658,16 @@ static int _sna_damage_contains_box(struct sna_damage *damage,
 	if (!sna_damage_maybe_contains_box(damage, box))
 		return PIXMAN_REGION_OUT;
 
-	if (damage->n)
+	if (damage->n) {
+		if (damage->mode != SUBTRACT) {
+			int ret = pixman_region_contains_rectangle(&damage->region,
+								   (BoxPtr)box);
+			if (ret == PIXMAN_REGION_IN)
+				return PIXMAN_REGION_IN;
+		}
+
 		__sna_damage_reduce(damage);
+	}
 
 	return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
 }
commit 63aa84ef57ff1e55d2df6d680d6bbf88be0619a6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 19 13:08:50 2011 +0100

    sna/gen6: Apply the unknown blitter death workaround
    
    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 0148785..3b2c0b9 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -102,7 +102,21 @@ static void blt_done(struct sna *sna, const struct sna_composite_op *op)
 {
 	struct kgem *kgem = &sna->kgem;
 
-	DBG(("%s: nbatch=%d\n", __FUNCTION__, kgem->nbatch));
+	_kgem_set_mode(kgem, KGEM_BLT);
+	(void)op;
+}
+
+static void gen6_blt_copy_done(struct sna *sna, const struct sna_composite_op *op)
+{
+	struct kgem *kgem = &sna->kgem;
+
+	if (kgem_check_batch(kgem, 3)) {
+		uint32_t *b = kgem->batch + kgem->nbatch;
+		b[0] = XY_SETUP_CLIP;
+		b[1] = b[2] = 0;
+		kgem->nbatch += 3;
+	}
+
 	_kgem_set_mode(kgem, KGEM_BLT);
 	(void)op;
 }
@@ -815,7 +829,10 @@ prepare_blt_copy(struct sna *sna,
 	op->blt   = blt_copy_composite;
 	op->box   = blt_copy_composite_box;
 	op->boxes = blt_copy_composite_boxes;
-	op->done  = blt_done;
+	if (sna->kgem.gen >= 60)
+		op->done  = gen6_blt_copy_done;
+	else
+		op->done  = blt_done;
 
 	return sna_blt_copy_init(sna, &op->u.blt,
 				 priv->gpu_bo,
@@ -1297,6 +1314,12 @@ static void sna_blt_copy_op_done(struct sna *sna,
 	blt_done(sna, &op->base);
 }
 
+static void gen6_blt_copy_op_done(struct sna *sna,
+				  const struct sna_copy_op *op)
+{
+	gen6_blt_copy_done(sna, &op->base);
+}
+
 bool sna_blt_copy(struct sna *sna, uint8_t alu,
 		  struct kgem_bo *src,
 		  struct kgem_bo *dst,
@@ -1319,7 +1342,10 @@ bool sna_blt_copy(struct sna *sna, uint8_t alu,
 		return FALSE;
 
 	op->blt  = sna_blt_copy_op_blt;
-	op->done = sna_blt_copy_op_done;
+	if (sna->kgem.gen >= 60)
+		op->done = gen6_blt_copy_op_done;
+	else
+		op->done = sna_blt_copy_op_done;
 	return TRUE;
 }
 
@@ -1539,6 +1565,13 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 			_kgem_submit(kgem);
 	} while (nbox);
 
+	if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
+		uint32_t *b = kgem->batch + kgem->nbatch;
+		b[0] = XY_SETUP_CLIP;
+		b[1] = b[2] = 0;
+		kgem->nbatch += 3;
+	}
+
 	_kgem_set_mode(kgem, KGEM_BLT);
 	return TRUE;
 }
diff --git a/src/sna/sna_reg.h b/src/sna/sna_reg.h
index 8ca9089..75f35c4 100644
--- a/src/sna/sna_reg.h
+++ b/src/sna/sna_reg.h
@@ -46,7 +46,7 @@
 #define XY_COLOR_BLT_WRITE_RGB		(1<<20)
 #define XY_COLOR_BLT_TILED		(1<<11)
 
-#define XY_SETUP_CLIP_BLT_CMD		((2<<29)|(3<<22)|1)
+#define XY_SETUP_CLIP			((2<<29)|(3<<22)|1)
 
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
 #define XY_SRC_COPY_BLT_WRITE_ALPHA	(1<<21)
commit 25f2d181946738d1ac2deb724eb48453c8692ed1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 18 23:03:10 2011 +0100

    sna: Compute region extents in place to eliminate redundant stack space
    
    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 201a92a..07132bf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1177,10 +1177,10 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	RegionRec region, *clip;
-	BoxRec box;
 	int16_t dx, dy;
 
-	DBG(("%s((%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
+	DBG(("%s((%d, %d)x(%d, %d), depth=%d, format=%d)\n",
+	     __FUNCTION__, x, y, w, h, depth, format));
 
 	if (w == 0 || h == 0)
 		return;
@@ -1194,24 +1194,16 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 
-	box.x1 = x + drawable->x + dx;
-	box.y1 = y + drawable->y + dy;
-	box.x2 = box.x1 + w;
-	box.y2 = box.y1 + h;
-
-	if (box.x1 < 0)
-		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;
-	if (box_empty(&box))
-		return;
+	region.extents.x1 = x + drawable->x + dx;
+	region.extents.y1 = y + drawable->y + dy;
+	region.extents.x2 = region.extents.x1 + w;
+	region.extents.y2 = region.extents.y1 + h;
 
-	region_set(&region, &box);
+	trim_box(&region.extents, &pixmap->drawable);
+	if (box_empty(&region.extents))
+		return;
 
+	region.data = NULL;
 	clip = fbGetCompositeClip(gc);
 	if (clip) {
 		RegionTranslate(clip, dx, dy);
@@ -1688,7 +1680,6 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	     __FUNCTION__, src_x, src_y, width, height, dst_x, dst_y));
 
 	if (wedged(sna) || !PM_IS_SOLID(dst, gc->planemask)) {
-		BoxRec box;
 		RegionRec region;
 
 		DBG(("%s: -- fallback, wedged=%d, solid=%d [%x]\n",
@@ -1696,11 +1687,11 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		     PM_IS_SOLID(dst, gc->planemask),
 		     (unsigned)gc->planemask));
 
-		box.x1 = dst_x + dst->x;
-		box.y1 = dst_y + dst->y;
-		box.x2 = box.x1 + width;
-		box.y2 = box.y1 + height;
-		region_set(&region, &box);
+		region.extents.x1 = dst_x + dst->x;
+		region.extents.y1 = dst_y + dst->y;
+		region.extents.x2 = region.extents.x1 + width;
+		region.extents.y2 = region.extents.y1 + height;
+		region.data = NULL;
 		if (gc->pCompositeClip)
 			RegionIntersect(&region, &region, gc->pCompositeClip);
 
@@ -2046,16 +2037,16 @@ static void
 sna_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	      DDXPointPtr pt, int *width, int n, int sorted)
 {
-	BoxRec extents;
 	RegionRec region;
 
-	if (sna_spans_extents(drawable, gc, n, pt, width, &extents))
+	if (sna_spans_extents(drawable, gc, n, pt, width, &region.extents))
 		return;
 
 	DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -2073,18 +2064,16 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	       int dst_x, int dst_y,
 	       unsigned long bit)
 {
-	BoxRec box;
 	RegionRec region;
 
 	DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d\n", __FUNCTION__,
 	     src_x, src_y, dst_x, dst_y, w, h));
 
-	box.x1 = dst_x + dst->x;
-	box.y1 = dst_y + dst->y;
-	box.x2 = box.x1 + w;
-	box.y2 = box.y1 + h;
-
-	region_set(&region, &box);
+	region.extents.x1 = dst_x + dst->x;
+	region.extents.y1 = dst_y + dst->y;
+	region.extents.x2 = region.extents.x1 + w;
+	region.extents.y2 = region.extents.y1 + h;
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 
 	sna_drawable_move_region_to_cpu(dst, &region, true);
@@ -2182,17 +2171,17 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 	       int mode, int n, DDXPointPtr pt)
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(mode=%d, n=%d, pt[0]=(%d, %d)\n",
 	     __FUNCTION__, mode, n, pt[0].x, pt[0].y));
 
-	if (sna_poly_point_extents(drawable, gc, mode, n, pt, &extents))
+	if (sna_poly_point_extents(drawable, gc, mode, n, pt, &region.extents))
 		return;
 
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -2209,14 +2198,14 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 		DBG(("%s: trying solid fill [%08lx] blt paths\n",
 		     __FUNCTION__, gc->fgPixel));
 
-		if (sna_drawable_use_gpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
 		    sna_poly_point_blt(drawable,
 				       priv->gpu_bo,
 				       priv->gpu_only ? NULL : &priv->gpu_damage,
 				       gc, mode, n, pt))
 			return;
 
-		if (sna_drawable_use_cpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_cpu_bo(drawable, &region.extents) &&
 		    sna_poly_point_blt(drawable,
 				       priv->cpu_bo,
 				       &priv->cpu_damage,
@@ -2226,7 +2215,7 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 
 fallback:
 	DBG(("%s: fallback\n", __FUNCTION__));
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -2403,17 +2392,17 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	      int mode, int n, DDXPointPtr pt)
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(mode=%d, n=%d, pt[0]=(%d, %d), lineWidth=%d\n",
 	     __FUNCTION__, mode, n, pt[0].x, pt[0].y, gc->lineWidth));
 
-	if (sna_poly_line_extents(drawable, gc, mode, n, pt, &extents))
+	if (sna_poly_line_extents(drawable, gc, mode, n, pt, &region.extents))
 		return;
 
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -2433,14 +2422,14 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 		DBG(("%s: trying solid fill [%08lx]\n",
 		     __FUNCTION__, gc->fgPixel));
 
-		if (sna_drawable_use_gpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
 		    sna_poly_line_blt(drawable,
 				      priv->gpu_bo,
 				      priv->gpu_only ? NULL : &priv->gpu_damage,
 				      gc, mode, n, pt))
 			return;
 
-		if (sna_drawable_use_cpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_cpu_bo(drawable, &region.extents) &&
 		    sna_poly_line_blt(drawable,
 				      priv->cpu_bo,
 				      &priv->cpu_damage,
@@ -2449,7 +2438,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	}
 
 	if (USE_SPANS && can_fill_spans(drawable, gc) &&
-	    sna_drawable_use_gpu_bo(drawable, &extents)) {
+	    sna_drawable_use_gpu_bo(drawable, &region.extents)) {
 		DBG(("%s: converting line into spans\n", __FUNCTION__));
 		switch (gc->lineStyle) {
 		case LineSolid:
@@ -2476,7 +2465,7 @@ fallback:
 		return;
 	}
 
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -2707,7 +2696,6 @@ static void
 sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(n=%d, first=((%d, %d), (%d, %d)), lineWidth=%d\n",
@@ -2715,11 +2703,12 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	     n, seg->x1, seg->y1, seg->x2, seg->y2,
 	     gc->lineWidth));
 
-	if (sna_poly_segment_extents(drawable, gc, n, seg, &extents))
+	if (sna_poly_segment_extents(drawable, gc, n, seg, &region.extents))
 		return;
 
 	DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -2739,24 +2728,24 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 		DBG(("%s: trying blt solid fill [%08lx] paths\n",
 		     __FUNCTION__, gc->fgPixel));
 
-		if (sna_drawable_use_gpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
 		    sna_poly_segment_blt(drawable,
 					 priv->gpu_bo,
-					 priv->gpu_only ? NULL : reduce_damage(drawable, &priv->gpu_damage, &extents),
-					 gc, n, seg, &extents))
+					 priv->gpu_only ? NULL : reduce_damage(drawable, &priv->gpu_damage, &region.extents),
+					 gc, n, seg, &region.extents))
 			return;
 
-		if (sna_drawable_use_cpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_cpu_bo(drawable, &region.extents) &&
 		    sna_poly_segment_blt(drawable,
 					 priv->cpu_bo,
-					 reduce_damage(drawable, &priv->cpu_damage, &extents),
-					 gc, n, seg, &extents))
+					 reduce_damage(drawable, &priv->cpu_damage, &region.extents),
+					 gc, n, seg, &region.extents))
 			return;
 	}
 
 	/* XXX Do we really want to base this decision on the amalgam ? */
 	if (USE_SPANS && can_fill_spans(drawable, gc) &&
-	    sna_drawable_use_gpu_bo(drawable, &extents)) {
+	    sna_drawable_use_gpu_bo(drawable, &region.extents)) {
 		void (*line)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
 		int i;
 
@@ -2789,7 +2778,7 @@ fallback:
 		return;
 	}
 
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -2867,16 +2856,16 @@ static void
 sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(n=%d, lineWidth=%d\n", __FUNCTION__, n, gc->lineWidth));
 
-	if (sna_poly_arc_extents(drawable, gc, n, arc, &extents))
+	if (sna_poly_arc_extents(drawable, gc, n, arc, &region.extents))
 		return;
 
 	DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -2888,7 +2877,7 @@ sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
 
 	/* For "simple" cases use the miPolyArc to spans path */
 	if (USE_SPANS && arc_to_spans(gc, n) && can_fill_spans(drawable, gc) &&
-	    sna_drawable_use_gpu_bo(drawable, &extents)) {
+	    sna_drawable_use_gpu_bo(drawable, &region.extents)) {
 		DBG(("%s: converting arcs into spans\n", __FUNCTION__));
 		miPolyArc(drawable, gc, n, arc);
 		return;
@@ -2901,7 +2890,7 @@ fallback:
 		return;
 	}
 
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -2993,16 +2982,16 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 	} else {
 		while (n--) {
 			RegionRec region;
-			BoxRec r,*box;
+			BoxRec *box;
 			int nbox;
 
-			r.x1 = rect->x + drawable->x;
-			r.y1 = rect->y + drawable->y;
-			r.x2 = bound(r.x1, rect->width);
-			r.y2 = bound(r.y1, rect->height);
+			region.extents.x1 = rect->x + drawable->x;
+			region.extents.y1 = rect->y + drawable->y;
+			region.extents.x2 = bound(region.extents.x1, rect->width);
+			region.extents.y2 = bound(region.extents.y1, rect->height);
 			rect++;
 
-			region_set(&region, &r);
+			region.data = NULL;
 			RegionIntersect(&region, &region, clip);
 
 			nbox = REGION_NUM_RECTS(&region);
@@ -3101,16 +3090,16 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 		} else {
 			while (n--) {
 				RegionRec region;
-				BoxRec r,*box;
+				BoxRec *box;
 				int nbox;
 
-				r.x1 = rect->x + drawable->x;
-				r.y1 = rect->y + drawable->y;
-				r.x2 = bound(r.x1, rect->width);
-				r.y2 = bound(r.y1, rect->height);
+				region.extents.x1 = rect->x + drawable->x;
+				region.extents.y1 = rect->y + drawable->y;
+				region.extents.x2 = bound(region.extents.x1, rect->width);
+				region.extents.y2 = bound(region.extents.y1, rect->height);
 				rect++;
 
-				region_set(&region, &r);
+				region.data = NULL;
 				RegionIntersect(&region, &region, clip);
 
 				nbox = REGION_NUM_RECTS(&region);
@@ -3204,16 +3193,16 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 		} else {
 			while (n--) {
 				RegionRec region;
-				BoxRec r,*box;
+				BoxRec *box;
 				int nbox;
 
-				r.x1 = rect->x + drawable->x;
-				r.y1 = rect->y + drawable->y;
-				r.x2 = bound(r.x1, rect->width);
-				r.y2 = bound(r.y1, rect->height);
+				region.extents.x1 = rect->x + drawable->x;
+				region.extents.y1 = rect->y + drawable->y;
+				region.extents.x2 = bound(region.extents.x1, rect->width);
+				region.extents.y2 = bound(region.extents.y1, rect->height);
 				rect++;
 
-				region_set(&region, &r);
+				region.data = NULL;
 				RegionIntersect(&region, &region, clip);
 
 				nbox = REGION_NUM_RECTS(&region);
@@ -3301,7 +3290,6 @@ static void
 sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 {
 	struct sna *sna = to_sna_from_drawable(draw);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(n=%d, PlaneMask: %lx (solid %d), solid fill: %d [style=%d, tileIsPixel=%d], alu=%d)\n", __FUNCTION__,
@@ -3311,7 +3299,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 	     gc->fillStyle, gc->tileIsPixel,
 	     gc->alu));
 
-	if (sna_poly_fill_rect_extents(draw, gc, n, rect, &extents)) {
+	if (sna_poly_fill_rect_extents(draw, gc, n, rect, &region.extents)) {
 		DBG(("%s, nothing to do\n", __FUNCTION__));
 		return;
 	}
@@ -3335,17 +3323,17 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 		     __FUNCTION__,
 		     gc->fillStyle == FillSolid ? gc->fgPixel : gc->tile.pixel));
 
-		if (sna_drawable_use_gpu_bo(draw, &extents) &&
+		if (sna_drawable_use_gpu_bo(draw, &region.extents) &&
 		    sna_poly_fill_rect_blt(draw,
 					   priv->gpu_bo,
-					   priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, &extents),
+					   priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, &region.extents),
 					   gc, n, rect))
 			return;
 
-		if (sna_drawable_use_cpu_bo(draw, &extents) &&
+		if (sna_drawable_use_cpu_bo(draw, &region.extents) &&
 		    sna_poly_fill_rect_blt(draw,
 					   priv->cpu_bo,
-					   reduce_damage(draw, &priv->cpu_damage, &extents),
+					   reduce_damage(draw, &priv->cpu_damage, &region.extents),
 					   gc, n, rect))
 			return;
 	} else if (gc->fillStyle == FillTiled) {
@@ -3353,25 +3341,26 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 
 		DBG(("%s: tiled fill, testing for blt\n", __FUNCTION__));
 
-		if (sna_drawable_use_gpu_bo(draw, &extents) &&
+		if (sna_drawable_use_gpu_bo(draw, &region.extents) &&
 		    sna_poly_fill_rect_tiled(draw,
 					     priv->gpu_bo,
-					     priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, &extents),
+					     priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, &region.extents),
 					     gc, n, rect))
 			return;
 
-		if (sna_drawable_use_cpu_bo(draw, &extents) &&
+		if (sna_drawable_use_cpu_bo(draw, &region.extents) &&
 		    sna_poly_fill_rect_tiled(draw,
 					     priv->cpu_bo,
-					     reduce_damage(draw, &priv->cpu_damage, &extents),
+					     reduce_damage(draw, &priv->cpu_damage, &region.extents),
 					     gc, n, rect))
 			return;
 	}
 
 fallback:
 	DBG(("%s: fallback (%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
-	region_set(&region, &extents);
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region)) {
 		DBG(("%s: nothing to do, all clipped\n", __FUNCTION__));
@@ -3590,28 +3579,26 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
 	ExtentInfoRec extents;
-	BoxRec box;
 	RegionRec region;
 
 	if (n == 0)
 		return;
 
 	QueryGlyphExtents(gc->font, info, n, &extents);
-	box.x1 = x + extents.overallLeft;
-	box.y1 = y - extents.overallAscent;
-	box.x2 = x + extents.overallRight;
-	box.y2 = y + extents.overallDescent;
-
-	trim_box(&box, drawable);
-	if (box_empty(&box))
-		return;
-	translate_box(&box, drawable);
-	clip_box(&box, gc);
-	if (box_empty(&box))
+	region.extents.x1 = x + extents.overallLeft;
+	region.extents.y1 = y - extents.overallAscent;
+	region.extents.x2 = x + extents.overallRight;
+	region.extents.y2 = y + extents.overallDescent;
+
+	trim_box(&region.extents, drawable);
+	translate_box(&region.extents, drawable);
+	clip_box(&region.extents, gc);
+	if (box_empty(&region.extents))
 		return;
 
-	DBG(("%s: extents(%d, %d), (%d, %d)\n",
-	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+	DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -3621,12 +3608,12 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 		goto fallback;
 	}
 
-	if (sna_drawable_use_gpu_bo(drawable, &box) &&
-	    sna_glyph_blt(drawable, gc, x, y, n, info, base, false, &box))
+	if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
+	    sna_glyph_blt(drawable, gc, x, y, n, info, base, false, &region.extents))
 		return;
 
 fallback:
-	region_set(&region, &box);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -3646,28 +3633,26 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
 	ExtentInfoRec extents;
-	BoxRec box;
 	RegionRec region;
 
 	if (n == 0)
 		return;
 
 	QueryGlyphExtents(gc->font, info, n, &extents);
-	box.x1 = x + extents.overallLeft;
-	box.y1 = y - extents.overallAscent;
-	box.x2 = x + extents.overallRight;
-	box.y2 = y + extents.overallDescent;
-
-	trim_box(&box, drawable);
-	if (box_empty(&box))
-		return;
-	translate_box(&box, drawable);
-	clip_box(&box, gc);
-	if (box_empty(&box))
+	region.extents.x1 = x + extents.overallLeft;
+	region.extents.y1 = y - extents.overallAscent;
+	region.extents.x2 = x + extents.overallRight;
+	region.extents.y2 = y + extents.overallDescent;
+
+	trim_box(&region.extents, drawable);
+	translate_box(&region.extents, drawable);
+	clip_box(&region.extents, gc);
+	if (box_empty(&region.extents))
 		return;
 
-	DBG(("%s: extents(%d, %d), (%d, %d)\n",
-	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+	DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
@@ -3677,12 +3662,12 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 		goto fallback;
 	}
 
-	if (sna_drawable_use_gpu_bo(drawable, &box) &&
-	    sna_glyph_blt(drawable, gc, x, y, n, info, base, true, &box))
+	if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
+	    sna_glyph_blt(drawable, gc, x, y, n, info, base, true, &region.extents))
 		return;
 
 fallback:
-	region_set(&region, &box);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -3700,7 +3685,6 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 		int w, int h,
 		int x, int y)
 {
-	BoxRec box;
 	RegionRec region;
 
 	if (w == 0 || h == 0)
@@ -3708,23 +3692,24 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 
 	DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
 
-	box.x1 = x;
-	box.y1 = y;
+	region.extents.x1 = x;
+	region.extents.y1 = y;
 	if (!gc->miTranslate) {
-		box.x1 += drawable->x;
-		box.y1 += drawable->y;
+		region.extents.x1 += drawable->x;
+		region.extents.y1 += drawable->y;
 	}
-	box.x2 = box.x1 + w;
-	box.y2 = box.y1 + h;
+	region.extents.x2 = region.extents.x1 + w;
+	region.extents.y2 = region.extents.y1 + h;
 
-	clip_box(&box, gc);
-	if (box_empty(&box))
+	clip_box(&region.extents, gc);
+	if (box_empty(&region.extents))
 		return;
 
-	DBG(("%s: extents(%d, %d), (%d, %d)\n",
-	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+	DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
-	region_set(&region, &box);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
@@ -3814,36 +3799,31 @@ sna_get_image(DrawablePtr drawable,
 	      unsigned int format, unsigned long mask,
 	      char *dst)
 {
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s (%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h));
 
-	extents.x1 = x + drawable->x;
-	extents.y1 = y + drawable->y;
-	extents.x2 = extents.x1 + w;
-	extents.y2 = extents.y1 + h;
-	region_set(&region, &extents);
+	region.extents.x1 = x + drawable->x;
+	region.extents.y1 = y + drawable->y;
+	region.extents.x2 = region.extents.x1 + w;
+	region.extents.y2 = region.extents.y1 + h;
+	region.data = NULL;
 
 	sna_drawable_move_region_to_cpu(drawable, &region, false);
 	fbGetImage(drawable, x, y, w, h, format, mask, dst);
-
-	RegionUninit(&region);
 }
 
 static void
 sna_get_spans(DrawablePtr drawable, int wMax,
 	      DDXPointPtr pt, int *width, int n, char *start)
 {
-	BoxRec extents;
 	RegionRec region;
 
-	if (sna_spans_extents(drawable, NULL, n, pt, width, &extents))
+	if (sna_spans_extents(drawable, NULL, n, pt, width, &region.extents))
 		return;
 
-	region_set(&region, &extents);
+	region.data = NULL;
 	sna_drawable_move_region_to_cpu(drawable, &region, false);
-	RegionUninit(&region);
 
 	fbGetSpans(drawable, wMax, pt, width, n, start);
 }
commit 1a43b2a46a67fdea215719c4446224c9d2e26a20
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 18 17:52:56 2011 +0100

    sna: Use the unlikely wedged() throughout
    
    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 6101fb6..201a92a 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -842,7 +842,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap)
 	DBG(("%s: CPU damage? %d\n", __FUNCTION__, priv->cpu_damage != NULL));
 
 	if (priv->gpu_bo == NULL) {
-		if (!sna->kgem.wedged)
+		if (!wedged(sna))
 			priv->gpu_bo =
 				kgem_create_2d(&sna->kgem,
 					       pixmap->drawable.width,
@@ -1687,7 +1687,7 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	DBG(("%s: src=(%d, %d)x(%d, %d) -> dst=(%d, %d)\n",
 	     __FUNCTION__, src_x, src_y, width, height, dst_x, dst_y));
 
-	if (sna->kgem.wedged || !PM_IS_SOLID(dst, gc->planemask)) {
+	if (wedged(sna) || !PM_IS_SOLID(dst, gc->planemask)) {
 		BoxRec box;
 		RegionRec region;
 
@@ -2197,7 +2197,7 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -2418,7 +2418,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -2724,7 +2724,7 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -2881,7 +2881,7 @@ sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -3319,7 +3319,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -3616,7 +3616,7 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -3672,7 +3672,7 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -3858,7 +3858,7 @@ sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src)
 
 	DBG(("%s origin=(%d, %d)\n", __FUNCTION__, origin.x, origin.y));
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		sna_pixmap_move_to_cpu(pixmap, true);
 		fbCopyWindow(win, origin, src);
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index e0b1ca3..3962d75 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -434,7 +434,7 @@ sna_composite(CARD8 op,
 					  width,  height))
 		return;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -641,7 +641,7 @@ sna_composite_rectangles(CARD8		 op,
 	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
 	     RegionExtents(&region)->x2, RegionExtents(&region)->y2));
 
-	if (sna->kgem.wedged)
+	if (wedged(sna))
 		goto fallback;
 
 	if (dst->alphaMap) {
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 9801121..80b4733 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -3010,7 +3010,7 @@ sna_composite_trapezoids(CARD8 op,
 	if (NO_ACCEL)
 		goto fallback;
 
-	if (sna->kgem.wedged || !sna->have_render) {
+	if (wedged(sna) || !sna->have_render) {
 		DBG(("%s: fallback -- wedged=%d, have_render=%d\n",
 		     __FUNCTION__, sna->kgem.wedged, sna->have_render));
 		goto fallback;
commit 7a9c76e1812d106fedf160c959e6e502998e4ce8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 18 15:51:33 2011 +0100

    sna: Micro-optimise fill-spans
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index bacb98f..2a10801 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -32,6 +32,7 @@ NULL:=#
 
 libsna_la_SOURCES = \
 	blt.c \
+	compiler.h \
 	kgem.c \
 	kgem.h \
 	sna.h \
diff --git a/src/sna/compiler.h b/src/sna/compiler.h
new file mode 100644
index 0000000..0b11310
--- /dev/null
+++ b/src/sna/compiler.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Chris Wilson <chris at chris-wilson.co.uk>
+ *
+ */
+
+#ifndef _SNA_COMPILER_H_
+#define _SNA_COMPILER_H_
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define likely(expr) (__builtin_expect (!!(expr), 1))
+#define unlikely(expr) (__builtin_expect (!!(expr), 0))
+#define noinline __attribute__((noinline))
+#define fastcall __attribute__((regparm(3)))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#define noinline
+#define fastcall
+#endif
+
+#endif /* _SNA_COMPILER_H_ */
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index a43a712..43e126b 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -25,14 +25,16 @@
  *
  */
 
+#ifndef KGEM_H
+#define KGEM_H
+
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdarg.h>
 
 #include <i915_drm.h>
 
-#ifndef KGEM_H
-#define KGEM_H
+#include "compiler.h"
 
 #if DEBUG_KGEM
 #define DBG_HDR(x) ErrorF x
@@ -249,12 +251,12 @@ static inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 
 static inline bool kgem_check_batch(struct kgem *kgem, int num_dwords)
 {
-	return kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface;
+	return likely(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface);
 }
 
 static inline bool kgem_check_reloc(struct kgem *kgem, int num_reloc)
 {
-	return kgem->nreloc + num_reloc <= KGEM_RELOC_SIZE(kgem);
+	return likely(kgem->nreloc + num_reloc <= KGEM_RELOC_SIZE(kgem));
 }
 
 static inline bool kgem_check_batch_with_surfaces(struct kgem *kgem,
diff --git a/src/sna/sna.h b/src/sna/sna.h
index ae043ed..e67e227 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -34,15 +34,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
+#ifndef _SNA_H_
+#define _SNA_H_
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <stdint.h>
 
-#ifndef _SNA_H_
-#define _SNA_H_
-
 #include "xf86_OSproc.h"
 #include "compiler.h"
 #include "xf86PciInfo.h"
@@ -67,6 +67,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <libudev.h>
 #endif
 
+#include "compiler.h"
+
 #define DBG(x)
 
 #define DEBUG_ALL (HAS_DEBUG_FULL || 0)
@@ -474,6 +476,10 @@ Bool sna_transform_is_integer_translation(const PictTransform *t,
 Bool sna_transform_is_translation(const PictTransform *t,
 				  pixman_fixed_t *tx, pixman_fixed_t *ty);
 
+static inline bool wedged(struct sna *sna)
+{
+	return unlikely(sna->kgem.wedged);
+}
 
 static inline uint32_t pixmap_size(PixmapPtr pixmap)
 {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 4f5c152..6101fb6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1772,7 +1772,6 @@ sna_fill_spans_blt(DrawablePtr drawable,
 	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
 	RegionRec clip;
-	int need_translation = !gc->miTranslate;
 	int16_t dx, dy;
 	struct sna_fill_op fill;
 
@@ -1788,17 +1787,21 @@ sna_fill_spans_blt(DrawablePtr drawable,
 	     extents->x1, extents->y1, extents->x2, extents->y2,
 	     n, pt->x, pt->y));
 
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
-	while (n--) {
-		int X1 = pt->x;
-		int y = pt->y;
-		int X2 = X1 + (int)*width;
+	if (!gc->miTranslate) {
+		int i;
 
-		if (need_translation) {
-			X1 += drawable->x;
-			X2 += drawable->x;
-			y += drawable->y;
+		for (i = 0; i < n; i++) {
+			/* XXX overflow? */
+			pt->x += drawable->x;
+			pt->y += drawable->y;
 		}
+	}
+
+	get_drawable_deltas(drawable, pixmap, &dx, &dy);
+	do {
+		int16_t X1 = pt->x;
+		int16_t y = pt->y;
+		int16_t X2 = X1 + (int)*width;
 
 		pt++;
 		width++;
@@ -1817,22 +1820,17 @@ sna_fill_spans_blt(DrawablePtr drawable,
 
 		y += dy;
 		if (clip.data == NULL) {
-			X1 += dx;
-			X2 += dx;
-			assert(X1 >= 0 && X2 <= pixmap->drawable.width);
-			if (X2 > X1) {
-				fill.blt(sna, &fill, X1, y, X2-X1, 1);
-				if (damage) {
-					BoxRec box;
+			fill.blt(sna, &fill, X1 + dx, y, X2-X1, 1);
+			if (damage) {
+				BoxRec box;
 
-					box.x1 = X1;
-					box.x2 = X2;
-					box.y1 = y;
-					box.y2 = box.y1 + 1;
+				box.x1 = X1 + dx;
+				box.x2 = X2 + dx;
+				box.y1 = y;
+				box.y2 = box.y1 + 1;
 
-					assert_pixmap_contains_box(pixmap, &box);
-					sna_damage_add_box(damage, &box);
-				}
+				assert_pixmap_contains_box(pixmap, &box);
+				sna_damage_add_box(damage, &box);
 			}
 		} else {
 			int nc = clip.data->numRects;
@@ -1872,7 +1870,7 @@ sna_fill_spans_blt(DrawablePtr drawable,
 				b++;
 			}
 		}
-	}
+	} while (--n);
 	fill.done(sna, &fill);
 	RegionUninit(&clip);
 	return TRUE;
@@ -1960,22 +1958,22 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 	       DDXPointPtr pt, int *width, int sorted)
 {
 	struct sna *sna = to_sna_from_drawable(drawable);
-	BoxRec extents;
 	RegionRec region;
 
 	DBG(("%s(n=%d, pt[0]=(%d, %d)\n",
 	     __FUNCTION__, n, pt[0].x, pt[0].y));
 
-	if (sna_spans_extents(drawable, gc, n, pt, width, &extents))
+	if (sna_spans_extents(drawable, gc, n, pt, width, &region.extents))
 		return;
 
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
-	     extents.x1, extents.y1, extents.x2, extents.y2));
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	if (FORCE_FALLBACK)
 		goto fallback;
 
-	if (sna->kgem.wedged) {
+	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
 		goto fallback;
 	}
@@ -1992,20 +1990,20 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 		DBG(("%s: trying solid fill [alu=%d, pixel=%08lx] blt paths\n",
 		     __FUNCTION__, gc->alu, gc->fgPixel));
 
-		if (sna_drawable_use_gpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents) &&
 		    sna_fill_spans_blt(drawable,
 				       priv->gpu_bo,
-				       priv->gpu_only ? NULL : reduce_damage(drawable, &priv->gpu_damage, &extents),
+				       priv->gpu_only ? NULL : reduce_damage(drawable, &priv->gpu_damage, &region.extents),
 				       gc, n, pt, width, sorted,
-				       &extents))
+				       &region.extents))
 			return;
 
-		if (sna_drawable_use_cpu_bo(drawable, &extents) &&
+		if (sna_drawable_use_cpu_bo(drawable, &region.extents) &&
 		    sna_fill_spans_blt(drawable,
 				       priv->cpu_bo,
-				       reduce_damage(drawable, &priv->cpu_damage, &extents),
+				       reduce_damage(drawable, &priv->cpu_damage, &region.extents),
 				       gc, n, pt, width, sorted,
-				       &extents))
+				       &region.extents))
 			return;
 	} else if (gc->fillStyle == FillTiled) {
 		xRectangle *rect;
@@ -2032,7 +2030,7 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 
 fallback:
 	DBG(("%s: fallback\n", __FUNCTION__));
-	region_set(&region, &extents);
+	region.data = NULL;
 	region_maybe_clip(&region, gc->pCompositeClip);
 	if (!RegionNotEmpty(&region))
 		return;
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 1597b1f..0148785 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -141,7 +141,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_bo_fenced(kgem, bo, NULL) ||
-	    !kgem_check_batch(kgem, 9)) {
+	    !kgem_check_batch(kgem, 12)) {
 		_kgem_submit(kgem);
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
@@ -151,7 +151,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 	{
 		uint32_t *b;
 
-		if (kgem->nreloc + 1 > KGEM_RELOC_SIZE(kgem)) {
+		if (!kgem_check_reloc(kgem, 1)) {
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
 		}
@@ -181,10 +181,38 @@ static bool sna_blt_fill_init(struct sna *sna,
 	return TRUE;
 }
 
+noinline static void sna_blt_fill_begin(struct sna *sna,
+					const struct sna_blt_state *blt)
+{
+	struct kgem *kgem = &sna->kgem;
+	uint32_t *b;
+
+	_kgem_submit(kgem);
+	_kgem_set_mode(kgem, KGEM_BLT);
+
+	b = kgem->batch + kgem->nbatch;
+	b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
+	if (blt->bpp == 32)
+		b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+	b[1] = blt->br13;
+	b[2] = 0;
+	b[3] = 0;
+	b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, blt->bo[0],
+			      I915_GEM_DOMAIN_RENDER << 16 |
+			      I915_GEM_DOMAIN_RENDER |
+			      KGEM_RELOC_FENCED,
+			      0);
+	b[5] = blt->pixel;
+	b[6] = blt->pixel;
+	b[7] = 0;
+	b[8] = 0;
+	kgem->nbatch += 9;
+}
+
 static void sna_blt_fill_one(struct sna *sna,
 			     const struct sna_blt_state *blt,
-			     int x, int y,
-			     int width, int height)
+			     int16_t x, int16_t y,
+			     int16_t width, int16_t height)
 {
 	struct kgem *kgem = &sna->kgem;
 	uint32_t *b;
@@ -196,33 +224,13 @@ static void sna_blt_fill_one(struct sna *sna,
 	assert(y >= 0);
 	assert((y+height) * blt->bo[0]->pitch <= blt->bo[0]->size);
 
-	if (!kgem_check_batch(kgem, 3)) {
-		_kgem_submit(kgem);
-		_kgem_set_mode(kgem, KGEM_BLT);
-
-		b = kgem->batch + kgem->nbatch;
-		b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
-		if (blt->bpp == 32)
-			b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
-		b[1] = blt->br13;
-		b[2] = 0;
-		b[3] = 0;
-		b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, blt->bo[0],
-				      I915_GEM_DOMAIN_RENDER << 16 |
-				      I915_GEM_DOMAIN_RENDER |
-				      KGEM_RELOC_FENCED,
-				      0);
-		b[5] = blt->pixel;
-		b[6] = blt->pixel;
-		b[7] = 0;
-		b[8] = 0;
-		kgem->nbatch += 9;
-	}
+	if (!kgem_check_batch(kgem, 3))
+		sna_blt_fill_begin(sna, blt);
 
 	b = kgem->batch + kgem->nbatch;
 	b[0] = blt->cmd;
-	b[1] = (y << 16) | x;
-	b[2] = ((y + height) << 16) | (x + width);
+	b[1] = y << 16 | x;
+	b[2] = b[1] + (height << 16 | width);
 	kgem->nbatch += 3;
 }
 
@@ -318,8 +326,7 @@ static void sna_blt_copy_one(struct sna *sna,
 		return;
 	}
 
-	if (kgem->nbatch + 8 + KGEM_BATCH_RESERVED > kgem->surface ||
-	    kgem->nreloc + 2 > KGEM_RELOC_SIZE(kgem))
+	if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2))
 		_kgem_submit(kgem);
 
 	b = kgem->batch + kgem->nbatch;
@@ -1377,8 +1384,8 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_batch(kgem, 6) ||
-	    !kgem_check_bo_fenced(kgem, bo, NULL) ||
-	    kgem->nreloc + 1 > KGEM_RELOC_SIZE(kgem))
+	    !kgem_check_reloc(kgem, 1) ||
+	    !kgem_check_bo_fenced(kgem, bo, NULL))
 		_kgem_submit(kgem);
 
 	do {
@@ -1478,8 +1485,8 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_batch(kgem, 8) ||
-	    !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL) ||
-	    kgem->nreloc + 2 > KGEM_RELOC_SIZE(kgem))
+	    !kgem_check_reloc(kgem, 2) ||
+	    !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL))
 		_kgem_submit(kgem);
 
 	do {
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index b4b4085..0f174f6 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -1,9 +1,9 @@
 #ifndef SNA_RENDER_H
 #define SNA_RENDER_H
 
-#define GRADIENT_CACHE_SIZE 16
+#include "compiler.h"
 
-#define fastcall __attribute__((regparm(3)))
+#define GRADIENT_CACHE_SIZE 16
 
 struct sna;
 struct sna_glyph;
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 1549ef5..9801121 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -52,8 +52,6 @@
 
 /* TODO: Emit unantialiased and MSAA triangles. */
 
-#define unlikely(x) x
-
 #ifndef MAX
 #define MAX(x,y) ((x) >= (y) ? (x) : (y))
 #endif


More information about the xorg-commit mailing list