xf86-video-intel: 10 commits - src/sna/gen3_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem_debug_gen7.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna_damage.h src/sna/sna_dri.c src/sna/sna_glyphs.c src/sna/sna.h src/sna/sna_io.c src/sna/sna_render.c src/sna/sna_tiling.c

Chris Wilson ickle at kemper.freedesktop.org
Thu May 3 14:44:52 PDT 2012


 src/sna/gen3_render.c     |    7 ++++++-
 src/sna/gen7_render.c     |    4 ++--
 src/sna/kgem.c            |   26 ++++++++++++--------------
 src/sna/kgem.h            |    2 +-
 src/sna/kgem_debug_gen7.c |   38 +++++++++++++++++++-------------------
 src/sna/sna.h             |    2 +-
 src/sna/sna_accel.c       |   29 ++++++++++++++++++++++-------
 src/sna/sna_damage.c      |   24 +++++-------------------
 src/sna/sna_damage.h      |   18 +++++++++++++++++-
 src/sna/sna_dri.c         |   18 +++++++++---------
 src/sna/sna_glyphs.c      |   16 +++++++++++-----
 src/sna/sna_io.c          |   28 +++++++++++++++++++++-------
 src/sna/sna_render.c      |   13 +++++++++----
 src/sna/sna_tiling.c      |   10 +++++++++-
 14 files changed, 144 insertions(+), 91 deletions(-)

New commits:
commit 61cac5c265279d45677262216a0ba56f548cd898
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 22:33:59 2012 +0100

    sna: Maintain a reference to the chain of proxies
    
    Rather than attempt to flatten the chain to the last link, we may need
    to hold a reference to the intermediate links in case of batch buffer
    submission.
    
    Fixes http://tnsp.org/~ccr/intel-gfx/test.html
    
    Reported-by: Matti Hamalainen <ccr at tnsp.org>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49436
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index ed2eaf1..680d36f 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2381,9 +2381,14 @@ gen3_composite_picture(struct sna *sna,
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
 						  x, y, w, h, dst_x, dst_y);
 
-	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
+	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
+		DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n",
+		     __FUNCTION__,
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     x, y, w, h));
 		return sna_render_picture_extract(sna, picture, channel,
 						  x, y, w, h, dst_x, dst_y);
+	}
 
 	return sna_render_pixmap_bo(sna, channel, pixmap,
 				    x, y, w, h, dst_x, dst_y);
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 49fa173..a116936 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2960,7 +2960,7 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 		if (bo->exec)
 			continue;
 
-		if (bo->proxy) {
+		while (bo->proxy) {
 			bo = bo->proxy;
 			if (bo->exec)
 				continue;
@@ -2989,7 +2989,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 {
 	uint32_t size;
 
-	if (bo->proxy)
+	while (bo->proxy)
 		bo = bo->proxy;
 	if (bo->exec) {
 		if (kgem->gen < 40 &&
@@ -3034,7 +3034,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 
 	va_start(ap, kgem);
 	while ((bo = va_arg(ap, struct kgem_bo *))) {
-		if (bo->proxy)
+		while (bo->proxy)
 			bo = bo->proxy;
 		if (bo->exec) {
 			if (kgem->gen >= 40 || bo->tiling == I915_TILING_NONE)
@@ -3098,10 +3098,10 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 		assert(bo->refcnt);
 		assert(!bo->purged);
 
-		delta += bo->delta;
-		if (bo->proxy) {
-			DBG(("%s: adding proxy for handle=%d\n",
-			     __FUNCTION__, bo->handle));
+		while (bo->proxy) {
+			DBG(("%s: adding proxy [delta=%d] for handle=%d\n",
+			     __FUNCTION__, bo->delta, bo->handle));
+			delta += bo->delta;
 			assert(bo->handle == bo->proxy->handle);
 			/* need to release the cache upon batch submit */
 			list_move(&bo->request, &kgem->next_request->buffers);
@@ -3527,8 +3527,9 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
 {
 	struct kgem_bo *bo;
 
-	DBG(("%s: target handle=%d, offset=%d, length=%d, io=%d\n",
-	     __FUNCTION__, target->handle, offset, length, target->io));
+	DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n",
+	     __FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1,
+	     offset, length, target->io));
 
 	bo = __kgem_bo_alloc(target->handle, length);
 	if (bo == NULL)
@@ -3537,15 +3538,11 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
 	bo->reusable = false;
 	bo->size.bytes = length;
 
-	bo->io = target->io;
+	bo->io = target->io && target->proxy == NULL;
 	bo->dirty = target->dirty;
 	bo->tiling = target->tiling;
 	bo->pitch = target->pitch;
 
-	if (target->proxy) {
-		offset += target->delta;
-		target = target->proxy;
-	}
 	bo->proxy = kgem_bo_reference(target);
 	bo->delta = offset;
 	return bo;
@@ -4079,6 +4076,7 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 	assert(_bo->proxy);
 
 	_bo = _bo->proxy;
+	assert(bo->proxy == NULL);
 	assert(_bo->exec == NULL);
 
 	bo = (struct kgem_partial_bo *)_bo;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 3072345..6430de8 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2138,7 +2138,8 @@ sna_pixmap_create_upload(ScreenPtr screen,
 	int bpp = BitsPerPixel(depth);
 	void *ptr;
 
-	DBG(("%s(%d, %d, %d)\n", __FUNCTION__, width, height, depth));
+	DBG(("%s(%d, %d, %d, flags=%x)\n", __FUNCTION__,
+	     width, height, depth, flags));
 	assert(width);
 	assert(height);
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 3d0f9e9..dee6608 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -957,6 +957,10 @@ sna_render_picture_partial(struct sna *sna,
 		kgem_get_tile_size(&sna->kgem, bo->tiling,
 				   &tile_width, &tile_height, &tile_size);
 
+		DBG(("%s: tiling=%d, size=%dx%d, chunk=%d\n",
+		     __FUNCTION__, 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);
@@ -989,8 +993,6 @@ sna_render_picture_partial(struct sna *sna,
 	if (channel->bo == NULL)
 		return 0;
 
-	channel->bo->pitch = bo->pitch;
-
 	if (channel->transform) {
 		memset(&channel->embedded_transform,
 		       0,
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index d0e5afc..d7e6d40 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -188,6 +188,14 @@ sna_tiling_composite_done(struct sna *sna,
 					if (y2 > y + height)
 						y2 = y + height;
 
+					DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d), delta=(%d,%d)\n",
+					     __FUNCTION__, n,
+					     r->dst.x, r->dst.y,
+					     r->width, r->height,
+					     x, y, width, height,
+					     x1, y1, x2, y2,
+					     dx, dy));
+
 					if (y2 > y1 && x2 > x1) {
 						struct sna_composite_rectangles rr;
 						rr.src.x = dx + r->src.x;
commit dea5d429f7a52dfc945b17a57ef79744cc796b0e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 17:35:24 2012 +0100

    sna: Remove extraneous SCANOUT flags
    
    These are now fixed by obeying a minimum alignment restriction.
    
    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 f239555..3d0f9e9 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1846,7 +1846,7 @@ sna_render_composite_redirect(struct sna *sna,
 			    width, height, bpp,
 			    kgem_choose_tiling(&sna->kgem, I915_TILING_X,
 					       width, height, bpp),
-			    CREATE_SCANOUT | CREATE_TEMPORARY);
+			    CREATE_TEMPORARY);
 	if (!bo)
 		return FALSE;
 
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index dcb4d1d..d0e5afc 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_TEMPORARY);
+					    CREATE_TEMPORARY);
 			if (bo) {
 				int16_t dx = this.extents.x1;
 				int16_t dy = this.extents.y1;
commit 19fd24a4db994bb5c5ce4a73f06d9394a758ea91
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 17:35:10 2012 +0100

    sna: Fix offset for combining damage
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index fb661b2..1196912 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -36,7 +36,8 @@ static inline void sna_damage_combine(struct sna_damage **l,
 				      struct sna_damage *r,
 				      int dx, int dy)
 {
-	*l = _sna_damage_combine(*l, r, dx, dy);
+	assert(!DAMAGE_IS_ALL(*l));
+	*l = _sna_damage_combine(*l, DAMAGE_PTR(r), dx, dy);
 }
 
 fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage,
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index ec2aaad..f239555 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1869,6 +1869,7 @@ sna_render_composite_redirect(struct sna *sna,
 	t->real_bo = op->dst.bo;
 	t->real_damage = op->damage;
 	if (op->damage) {
+		assert(!DAMAGE_IS_ALL(op->damage));
 		t->damage = sna_damage_create();
 		op->damage = &t->damage;
 	}
@@ -1899,8 +1900,10 @@ sna_render_composite_redirect_done(struct sna *sna,
 					   &t->box, 1);
 		}
 		if (t->damage) {
+			DBG(("%s: combining damage, offset=(%d, %d)\n",
+			     __FUNCTION__, t->box.x1, t->box.y1));
 			sna_damage_combine(t->real_damage, t->damage,
-					   -t->box.x1, -t->box.y1);
+					   t->box.x1, t->box.y1);
 			__sna_damage_destroy(t->damage);
 		}
 
commit 1376c81dbf3b789e04e6804df1b1fd32bcb2bd1d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 17:34:28 2012 +0100

    sna: Debug option to force particular upload/download paths
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 7cec3ff..3de164b 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -42,6 +42,8 @@
 
 #define PITCH(x, y) ALIGN((x)*(y), 4)
 
+#define FORCE_INPLACE 0
+
 /* XXX Need to avoid using GTT fenced access for I915_TILING_Y on 855GM */
 
 static Bool
@@ -109,6 +111,15 @@ static void read_boxes_inplace(struct kgem *kgem,
 	} while (--n);
 }
 
+static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (FORCE_INPLACE)
+		return FORCE_INPLACE > 0;
+
+	return !kgem_bo_map_will_stall(kgem, bo) ||
+		bo->tiling == I915_TILING_NONE;
+}
+
 void sna_read_boxes(struct sna *sna,
 		    struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
 		    PixmapPtr dst, int16_t dst_dx, int16_t dst_dy,
@@ -150,8 +161,7 @@ void sna_read_boxes(struct sna *sna,
 	 * this path.
 	 */
 
-	if (!kgem_bo_map_will_stall(kgem, src_bo) ||
-	    src_bo->tiling == I915_TILING_NONE) {
+	if (download_inplace(kgem, src_bo)) {
 fallback:
 		read_boxes_inplace(kgem,
 				   src_bo, src_dx, src_dy,
@@ -512,6 +522,9 @@ static bool upload_inplace(struct kgem *kgem,
 			   const BoxRec *box,
 			   int n, int bpp)
 {
+	if (FORCE_INPLACE)
+		return FORCE_INPLACE > 0;
+
 	/* If we are writing through the GTT, check first if we might be
 	 * able to almagamate a series of small writes into a single
 	 * operation.
commit f0d464d6b18855616fc43d9a25aa6853f86c8e2b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 16:17:35 2012 +0100

    sna/dri: Balance flush counting
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 308e329..424738a 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -129,7 +129,6 @@ struct sna_pixmap {
 
 	uint32_t stride;
 	uint32_t clear_color;
-	unsigned flush;
 
 #define SOURCE_BIAS 4
 	uint16_t source_count;
@@ -139,6 +138,7 @@ struct sna_pixmap {
 	uint8_t undamaged :1;
 	uint8_t create :3;
 	uint8_t header :1;
+	uint8_t flush :1;
 };
 
 struct sna_glyph {
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 1a7b6bd..1ad2ff1 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -163,7 +163,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	if (priv == NULL)
 		return NULL;
 
-	if (priv->flush++)
+	if (priv->flush)
 		return priv->gpu_bo;
 
 	tiling = color_tiling(sna, &pixmap->drawable);
@@ -181,6 +181,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 
 	/* Don't allow this named buffer to be replaced */
 	priv->pinned = 1;
+	priv->flush = true;
 
 	return priv->gpu_bo;
 }
@@ -322,12 +323,11 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 			struct sna_pixmap *priv = sna_pixmap(private->pixmap);
 
 			/* Undo the DRI markings on this pixmap */
-			assert(priv->flush > 0);
-			if (--priv->flush == 0) {
-				list_del(&priv->list);
-				sna_accel_watch_flush(sna, -1);
-				priv->pinned = private->pixmap == sna->front;
-			}
+			assert(priv->flush);
+			list_del(&priv->list);
+			sna_accel_watch_flush(sna, -1);
+			priv->pinned = private->pixmap == sna->front;
+			priv->flush = false;
 
 			screen->DestroyPixmap(private->pixmap);
 		}
@@ -649,13 +649,13 @@ sna_dri_copy_region(DrawablePtr draw,
 		     struct kgem_bo *, struct kgem_bo *, bool) = sna_dri_copy;
 
 	if (dst_buffer->attachment == DRI2BufferFrontLeft) {
-		dst = sna_pixmap_set_dri(sna, pixmap);
+		dst = sna_pixmap_get_bo(pixmap);
 		copy = sna_dri_copy_to_front;
 	} else
 		dst = get_private(dst_buffer)->bo;
 
 	if (src_buffer->attachment == DRI2BufferFrontLeft) {
-		src = sna_pixmap_set_dri(sna, pixmap);
+		src = sna_pixmap_get_bo(pixmap);
 		assert(copy == sna_dri_copy);
 		copy = sna_dri_copy_from_front;
 	} else
commit d47e98dd64c0b9fe2979db42622c5ee8168e8b35
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 14:54:17 2012 +0100

    sna: Minor glyph fallback fixes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index f4f115e..07b2a94 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1136,6 +1136,8 @@ glyphs_fallback(CARD8 op,
 		mask_image = dst_image;
 		src_x -= x;
 		src_y -= y;
+		x += dst->pDrawable->x;
+		y += dst->pDrawable->y;
 	}
 
 	do {
@@ -1152,7 +1154,7 @@ glyphs_fallback(CARD8 op,
 			glyph_image = sna_glyph(g)->image;
 			if (glyph_image == NULL) {
 				PicturePtr picture;
-				int dx, dy;
+				int gx, gy;
 
 				picture = GlyphPicture(g)[screen];
 				if (picture == NULL)
@@ -1160,11 +1162,11 @@ glyphs_fallback(CARD8 op,
 
 				glyph_image = image_from_pict(picture,
 							      FALSE,
-							      &dx, &dy);
+							      &gx, &gy);
 				if (!glyph_image)
 					goto next_glyph;
 
-				assert(dx == 0 && dy == 0);
+				assert(gx == 0 && gy == 0);
 				sna_glyph(g)->image = glyph_image;
 			}
 
@@ -1191,11 +1193,15 @@ glyphs_fallback(CARD8 op,
 				int xi = x - g->info.x;
 				int yi = y - g->info.y;
 
-				DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d), src (%d, %d) [op=%d]\n",
+				DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n",
 				     __FUNCTION__,
 				     dx, dy,
 				     xi, yi,
 				     g->info.width, g->info.height,
+				     dst->pDrawable->x,
+				     dst->pDrawable->y,
+				     dst->pDrawable->width,
+				     dst->pDrawable->height,
 				     src_x + xi,
 				     src_y + yi,
 				     op));
@@ -1261,7 +1267,7 @@ sna_glyphs(CARD8 op,
 	if (REGION_NUM_RECTS(dst->pCompositeClip) == 0)
 		return;
 
-	if (FALLBACK || DEBUG_NO_RENDER)
+	if (FALLBACK || !sna->have_render)
 		goto fallback;
 
 	if (wedged(sna)) {
commit a1f08b8850616952fb0babe2275eb36b13a380ec
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 14:53:29 2012 +0100

    sna: Don't discard GPU buffer if we only want to read back for the operation
    
    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 c84b23e..3072345 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1315,9 +1315,11 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 			      pixmap->drawable.width,
 			      pixmap->drawable.height)) {
 		sna_damage_destroy(&priv->gpu_damage);
-		sna_pixmap_free_gpu(sna, priv);
 		priv->undamaged = false;
 
+		if (flags & MOVE_WRITE)
+			sna_pixmap_free_gpu(sna, priv);
+
 		if (pixmap->devPrivate.ptr == NULL &&
 		    !sna_pixmap_alloc_cpu(sna, pixmap, priv, false))
 			return false;
@@ -1458,8 +1460,10 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL))
 		return false;
 
-	if (priv->gpu_bo == NULL)
+	if (priv->gpu_bo == NULL) {
+		assert(priv->gpu_damage == NULL);
 		goto done;
+	}
 
 	assert(priv->gpu_bo->proxy == NULL);
 	if (priv->clear) {
commit fcccc5528b8696fb4f9b3f9f528673b95d98a907
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 3 11:27:44 2012 +0100

    sna: Improve handling of inplace IO for large transfers
    
    If the transfer is large enough to obliterate the caches, then it is
    preferrable to do it inplace rather than upload a proxy texture and
    queue a blit. This helps prevent an inconsistency where one layer
    believes the operation should be done inplace only for the IO layer to
    perform an indirect upload.
    
    Testing show no significant impact upon the cairo-traces, but it does
    prevent x11perf -shmput from exploding.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 51025ea..9eac68e 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -462,7 +462,7 @@ static inline bool kgem_bo_map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
 	     __FUNCTION__, bo->handle,
 	     bo->domain, bo->presumed_offset, bo->size));
 
-	if (!kgem_bo_is_mappable(kgem, bo))
+	if (!kgem_bo_is_mappable(kgem, bo) && kgem_bo_is_busy(bo))
 		return true;
 
 	if (kgem->wedged)
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 2539518..7cec3ff 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -516,17 +516,16 @@ static bool upload_inplace(struct kgem *kgem,
 	 * able to almagamate a series of small writes into a single
 	 * operation.
 	 */
-	if (!bo->map) {
+	if (!bo->map || kgem_bo_map_will_stall(kgem, bo)) {
 		unsigned int bytes = 0;
 		while (n--) {
 			bytes += (box->x2 - box->x1) * (box->y2 - box->y1);
 			box++;
 		}
-		if (bytes * bpp >> 12 < kgem->half_cpu_cache_pages)
-			return false;
+		return bytes * bpp >> 12 >= kgem->half_cpu_cache_pages;
 	}
 
-	return !kgem_bo_map_will_stall(kgem, bo);
+	return true;
 }
 
 bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
@@ -570,7 +569,9 @@ fallback:
 	}
 
 	/* Try to avoid switching rings... */
-	if (!can_blt || kgem->ring == KGEM_RENDER ||
+	if (!can_blt ||
+	    kgem->ring == KGEM_RENDER ||
+	    (kgem->has_semaphores && kgem->mode == KGEM_NONE) ||
 	    upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
 		PixmapRec tmp;
 
commit 53568e8e49559094ce5b24b8709669f1f76fe2bf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 30 09:24:06 2012 +0100

    sna/gen7: Fix debug printing of primitives
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 327714f..6c9a833 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -898,7 +898,7 @@ gen7_emit_vertex_elements(struct sna *sna,
 
 	if (op->is_affine) {
 		src_format = GEN7_SURFACEFORMAT_R32G32_FLOAT;
-		w_component = GEN7_VFCOMPONENT_STORE_1_FLT;
+		w_component = GEN7_VFCOMPONENT_STORE_0;
 	} else {
 		src_format = GEN7_SURFACEFORMAT_R32G32B32_FLOAT;
 		w_component = GEN7_VFCOMPONENT_STORE_SRC;
@@ -930,7 +930,7 @@ gen7_emit_vertex_elements(struct sna *sna,
 		  0 << GEN7_VE0_OFFSET_SHIFT); /* offsets vb in bytes */
 	OUT_BATCH(GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT |
 		  GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT |
-		  GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_2_SHIFT |
+		  GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT |
 		  GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT);
 
 	/* u0, v0, w0 */
diff --git a/src/sna/kgem_debug_gen7.c b/src/sna/kgem_debug_gen7.c
index a7dbbf2..78eae01 100644
--- a/src/sna/kgem_debug_gen7.c
+++ b/src/sna/kgem_debug_gen7.c
@@ -287,8 +287,8 @@ static void primitive_out(struct kgem *kgem, uint32_t *data)
 
 	assert((data[0] & (1<<15)) == 0); /* XXX index buffers */
 
-	for (n = 0; n < data[1]; n++) {
-		int v = data[2] + n;
+	for (n = 0; n < data[2]; n++) {
+		int v = data[3] + n;
 		ErrorF("	[%d:%d] = ", n, v);
 		indirect_vertex_out(kgem, v);
 		ErrorF("\n");
@@ -358,7 +358,7 @@ get_965_depthformat(unsigned int depthformat)
 }
 
 static const char *
-get_965_element_component(uint32_t data, int component)
+get_element_component(uint32_t data, int component)
 {
 	uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7;
 
@@ -387,9 +387,9 @@ get_965_element_component(uint32_t data, int component)
 }
 
 static const char *
-get_965_prim_type(uint32_t data)
+get_prim_type(uint32_t data)
 {
-	uint32_t primtype = (data >> 10) & 0x1f;
+	uint32_t primtype = data & 0x1f;
 
 	switch (primtype) {
 	case 0x01: return "point list";
@@ -656,10 +656,10 @@ int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset)
 			i++;
 			kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), "
 				  "dst offset 0x%02x bytes\n",
-				  get_965_element_component(data[i], 0),
-				  get_965_element_component(data[i], 1),
-				  get_965_element_component(data[i], 2),
-				  get_965_element_component(data[i], 3),
+				  get_element_component(data[i], 0),
+				  get_element_component(data[i], 1),
+				  get_element_component(data[i], 2),
+				  get_element_component(data[i], 3),
 				  (data[i] & 0xff) * 4);
 			i++;
 		}
@@ -673,16 +673,16 @@ int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset)
 		return len;
 
 	case 0x7b00:
-		assert(len == 6);
-		kgem_debug_print(data, offset, 0,
-			  "3DPRIMITIVE: %s %s\n",
-			  get_965_prim_type(data[0]),
-			  (data[0] & (1 << 15)) ? "random" : "sequential");
-		kgem_debug_print(data, offset, 1, "vertex count\n");
-		kgem_debug_print(data, offset, 2, "start vertex\n");
-		kgem_debug_print(data, offset, 3, "instance count\n");
-		kgem_debug_print(data, offset, 4, "start instance\n");
-		kgem_debug_print(data, offset, 5, "index bias\n");
+		assert(len == 7);
+		kgem_debug_print(data, offset, 0, "3DPRIMITIVE\n");
+		kgem_debug_print(data, offset, 1, "type %s, %s\n",
+			  get_prim_type(data[1]),
+			  (data[1] & (1 << 15)) ? "random" : "sequential");
+		kgem_debug_print(data, offset, 2, "vertex count\n");
+		kgem_debug_print(data, offset, 3, "start vertex\n");
+		kgem_debug_print(data, offset, 4, "instance count\n");
+		kgem_debug_print(data, offset, 5, "start instance\n");
+		kgem_debug_print(data, offset, 6, "index bias\n");
 		primitive_out(kgem, data);
 		return len;
 	}
commit 01c26a44fdce761781908be11102e7a6a3db523c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 2 21:09:27 2012 +0100

    sna: Avoid reducing damage for synchronisation
    
    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 8b52a40..c84b23e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1523,9 +1523,10 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		priv->undamaged = true;
 	}
 
-	if (sna_damage_contains_box(priv->gpu_damage,
-				    &region->extents) != PIXMAN_REGION_OUT) {
-		DBG(("%s: region (%dx%d) intersects gpu damage\n",
+	if (priv->gpu_damage &&
+	    (DAMAGE_IS_ALL(priv->gpu_damage) ||
+	     sna_damage_overlaps_box(priv->gpu_damage, &region->extents))) {
+		DBG(("%s: region (%dx%d) overlaps gpu damage\n",
 		     __FUNCTION__,
 		     region->extents.x2 - region->extents.x1,
 		     region->extents.y2 - region->extents.y1));
@@ -1538,9 +1539,18 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				       priv->gpu_bo, 0, 0,
 				       pixmap, 0, 0,
 				       &region->extents, 1);
-		} else {
+			goto done;
+		}
+
+		if (sna_damage_contains_box(priv->gpu_damage,
+					    &region->extents) != PIXMAN_REGION_OUT) {
 			RegionRec want, *r = region;
 
+			DBG(("%s: region (%dx%d) intersects gpu damage\n",
+			     __FUNCTION__,
+			     region->extents.x2 - region->extents.x1,
+			     region->extents.y2 - region->extents.y1));
+
 			/* Expand the region to move 32x32 pixel blocks at a
 			 * time, as we assume that we will continue writing
 			 * afterwards and so aim to coallesce subsequent
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index f2d682d..b97edbe 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -984,20 +984,6 @@ static bool box_contains(const BoxRec *a, const BoxRec *b)
 	return true;
 }
 
-static inline Bool sna_damage_maybe_contains_box(const struct sna_damage *damage,
-						 const BoxRec *box)
-{
-	if (box->x2 <= damage->extents.x1 ||
-	    box->x1 >= damage->extents.x2)
-		return FALSE;
-
-	if (box->y2 <= damage->extents.y1 ||
-	    box->y1 >= damage->extents.y2)
-		return FALSE;
-
-	return TRUE;
-}
-
 static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 						RegionPtr region)
 {
@@ -1011,7 +997,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 
 	assert(RegionNotEmpty(region));
 
-	if (!sna_damage_maybe_contains_box(damage, &region->extents))
+	if (!sna_damage_overlaps_box(damage, &region->extents))
 		return damage;
 
 
@@ -1096,7 +1082,7 @@ inline static struct sna_damage *__sna_damage_subtract_box(struct sna_damage *da
 		return NULL;
 	}
 
-	if (!sna_damage_maybe_contains_box(damage, box))
+	if (!sna_damage_overlaps_box(damage, box))
 		return damage;
 
 	if (box_contains(box, &damage->extents)) {
@@ -1189,7 +1175,7 @@ static struct sna_damage *__sna_damage_subtract_boxes(struct sna_damage *damage,
 	extents.y1 += dy;
 	extents.y2 += dy;
 
-	if (!sna_damage_maybe_contains_box(damage, &extents))
+	if (!sna_damage_overlaps_box(damage, &extents))
 		return damage;
 
 	if (n == 1)
@@ -1248,7 +1234,7 @@ static int __sna_damage_contains_box(struct sna_damage *damage,
 	if (damage->mode == DAMAGE_ALL)
 		return PIXMAN_REGION_IN;
 
-	if (!sna_damage_maybe_contains_box(damage, box))
+	if (!sna_damage_overlaps_box(damage, box))
 		return PIXMAN_REGION_OUT;
 
 	ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
@@ -1297,7 +1283,7 @@ bool _sna_damage_contains_box__no_reduce(const struct sna_damage *damage,
 	if (damage->mode == DAMAGE_SUBTRACT)
 		return false;
 
-	if (!sna_damage_maybe_contains_box(damage, box))
+	if (!sna_damage_overlaps_box(damage, box))
 		return false;
 
 	return pixman_region_contains_rectangle((RegionPtr)&damage->region,
diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 422a124..fb661b2 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -190,6 +190,21 @@ static inline Bool sna_damage_intersect(struct sna_damage *damage,
 	return _sna_damage_intersect(damage, region, result);
 }
 
+static inline bool
+sna_damage_overlaps_box(const struct sna_damage *damage,
+			const BoxRec *box)
+{
+	if (box->x2 <= damage->extents.x1 ||
+	    box->x1 >= damage->extents.x2)
+		return FALSE;
+
+	if (box->y2 <= damage->extents.y1 ||
+	    box->y1 >= damage->extents.y2)
+		return FALSE;
+
+	return TRUE;
+}
+
 int _sna_damage_contains_box(struct sna_damage *damage,
 			     const BoxRec *box);
 static inline int sna_damage_contains_box(struct sna_damage *damage,


More information about the xorg-commit mailing list