xf86-video-intel: 13 commits - src/sna/fb src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna_display.c 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 src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Sep 27 03:12:45 PDT 2013


 src/sna/fb/fbclip.c      |    2 
 src/sna/gen4_render.c    |   10 -
 src/sna/gen5_render.c    |    7 
 src/sna/gen6_render.c    |    9 -
 src/sna/gen7_render.c    |   14 +
 src/sna/kgem.c           |   61 +++++-
 src/sna/sna.h            |   15 +
 src/sna/sna_accel.c      |  421 ++++++++++++++++++++++++++++++-----------------
 src/sna/sna_composite.c  |  207 ++++++++++++-----------
 src/sna/sna_display.c    |   86 ++++++---
 src/sna/sna_dri.c        |   19 +-
 src/sna/sna_glyphs.c     |  176 ++++++++++---------
 src/sna/sna_io.c         |  129 +++++++++-----
 src/sna/sna_render.c     |   79 +++++---
 src/sna/sna_tiling.c     |   30 ++-
 src/sna/sna_trapezoids.c |   37 ++--
 16 files changed, 805 insertions(+), 497 deletions(-)

New commits:
commit 4c9265ebff496a4d4f974768e264bd65babff97e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Sep 27 10:46:40 2013 +0100

    sna: Only flush the scanout if we successfully upload it to the GPU
    
    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 9a6f50b..fd77164 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -15476,9 +15476,9 @@ static void sna_accel_flush(struct sna *sna)
 		sna_accel_disarm_timer(sna, FLUSH_TIMER);
 	sna->kgem.busy = busy;
 
-	if (priv) {
-		sna_pixmap_force_to_gpu(priv->pixmap,
-					MOVE_READ | MOVE_ASYNC_HINT);
+	if (priv &&
+	    sna_pixmap_force_to_gpu(priv->pixmap,
+				    MOVE_READ | MOVE_ASYNC_HINT)) {
 		kgem_scanout_flush(&sna->kgem, priv->gpu_bo);
 		assert(!priv->cpu);
 	}
commit 47ac44159c0e3ea0c84510f1d58ac140344b5e69
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Sep 27 10:19:47 2013 +0100

    sna: Make sure we do not try to upload indirectly if the GPU is wedged
    
    Otherwise we trigger assertions and may end up with corruption.
    
    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 d66668c..0988d3d 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -729,6 +729,9 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
 				box, nbox))
 		return true;
 
+	if (wedged(sna))
+		return false;
+
 	can_blt = kgem_bo_can_blt(kgem, dst_bo) &&
 		(box[0].x2 - box[0].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4);
 	extents = box[0];
commit 7206d0bb916fa69690a5f4fdcc5e7e81787c6c16
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Sep 27 10:01:34 2013 +0100

    sna: Disable the promotion of large bo as flush
    
    We can rely on our aperture and idleness tracking to appropriate flush
    batches. Marking the large bo as flush interferes with the treatment of
    flush for externally named bo, such as DRI/PRIME.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4a82d4a..2a5820c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4019,7 +4019,6 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
 			assert_tiling(kgem, bo);
 			bo->refcnt = 1;
-			bo->flush = true;
 			return bo;
 		}
 
@@ -4387,12 +4386,6 @@ create:
 		return NULL;
 	}
 
-	if (bucket >= NUM_CACHE_BUCKETS) {
-		DBG(("%s: marking large bo for automatic flushing\n",
-		     __FUNCTION__));
-		bo->flush = true;
-	}
-
 	bo->unique_id = kgem_get_unique_id(kgem);
 	if (tiling == I915_TILING_NONE ||
 	    gem_set_tiling(kgem->fd, handle, tiling, pitch)) {
commit 6ac1ac98c28d38b539f465c5ac488d879f1c2ab6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 23:23:47 2013 +0000

    sna: Catch SIGBUS to prevent X death
    
    We know that when we access either a CPU or GTT mmap we are vulernable
    to receiving a SIGBUS. In fact, we can catch these and abort the
    operation preventing X and all of its clients from randomly dieing.
    
    This helps for instance if you try and use a 1GiB frontbuffer on a 2GiB
    machine...
    
    For complete protection, we also need to catch signals for all GTT maps,
    such as VBO and staging buffers. (TBD)
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index d389026..f7c5315 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -69,6 +69,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <libudev.h>
 #endif
 
+#include <signal.h>
+#include <setjmp.h>
+
 #include "compiler.h"
 
 #if HAS_DEBUG_FULL
@@ -973,4 +976,16 @@ void sna_image_composite(pixman_op_t        op,
 			 uint16_t           width,
 			 uint16_t           height);
 
+extern jmp_buf sigjmp;
+extern volatile sig_atomic_t sigtrap;
+
+#define sigtrap_assert() assert(sigtrap == 0)
+#define sigtrap_get() sigsetjmp(sigjmp, ++sigtrap)
+
+static inline void sigtrap_put(void)
+{
+	--sigtrap;
+	sigtrap_assert();
+}
+
 #endif /* _SNA_H */
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index d7a0828..9a6f50b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -397,6 +397,25 @@ static void assert_pixmap_damage(PixmapPtr p)
 #endif
 #endif
 
+jmp_buf sigjmp;
+volatile sig_atomic_t sigtrap;
+
+static int sigtrap_handler(int sig)
+{
+	if (sigtrap) {
+		/* XXX rate-limited squawk? */
+		sigtrap = 0;
+		siglongjmp(sigjmp, sig);
+	}
+
+	return 0;
+}
+
+static void sigtrap_init(void)
+{
+	OsRegisterSigWrapper(sigtrap_handler);
+}
+
 inline static bool
 sna_fill_init_blt(struct sna_fill_op *fill,
 		  struct sna *sna,
@@ -1837,6 +1856,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 
 	assert(flags & (MOVE_READ | MOVE_WRITE));
 	assert_pixmap_damage(pixmap);
+	sigtrap_assert();
 
 	priv = sna_pixmap(pixmap);
 	if (priv == NULL) {
@@ -2126,6 +2146,7 @@ done:
 	assert(pixmap->devKind);
 	assert_pixmap_damage(pixmap);
 	assert(has_coherent_ptr(sna, sna_pixmap(pixmap)));
+	sigtrap_assert();
 	return true;
 }
 
@@ -2256,6 +2277,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		assert_drawable_contains_box(drawable, &region->extents);
 	}
 	assert(flags & (MOVE_WRITE | MOVE_READ));
+	sigtrap_assert();
 
 	if (box_empty(&region->extents))
 		return true;
@@ -2744,6 +2766,7 @@ out:
 	assert(pixmap->devKind);
 	assert_pixmap_damage(pixmap);
 	assert(has_coherent_ptr(sna, sna_pixmap(pixmap)));
+	sigtrap_assert();
 	return true;
 }
 
@@ -2766,6 +2789,8 @@ sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags)
 	     drawable->width, drawable->height,
 	     dx, dy, flags));
 
+	sigtrap_assert();
+
 	region.extents.x1 = drawable->x + dx;
 	region.extents.y1 = drawable->y + dy;
 	region.extents.x2 = region.extents.x1 + drawable->width;
@@ -2841,6 +2866,7 @@ static inline struct sna_pixmap *
 sna_pixmap_mark_active(struct sna *sna, struct sna_pixmap *priv)
 {
 	assert(priv->gpu_bo);
+	sigtrap_assert();
 	DBG(("%s: pixmap=%ld, handle=%u\n", __FUNCTION__,
 	     priv->pixmap->drawable.serialNumber,
 	     priv->gpu_bo->handle));
@@ -2889,6 +2915,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 	     __FUNCTION__, pixmap->drawable.serialNumber,
 	     box->x1, box->y1, box->x2, box->y2, flags));
 
+	sigtrap_assert();
+
 	priv = __sna_pixmap_for_gpu(sna, pixmap, flags);
 	if (priv == NULL)
 		return NULL;
@@ -3606,6 +3634,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 	     pixmap->usage_hint,
 	     flags));
 
+	sigtrap_assert();
+
 	priv = __sna_pixmap_for_gpu(sna, pixmap, flags);
 	if (priv == NULL)
 		return NULL;
@@ -3830,6 +3860,8 @@ static bool must_check sna_gc_move_to_cpu(GCPtr gc,
 
 	DBG(("%s, changes=%lx\n", __FUNCTION__, changes));
 
+	sigtrap_assert();
+
 	assert(gc->ops == (GCOps *)&sna_gc_ops);
 	gc->ops = (GCOps *)&sna_gc_ops__cpu;
 
@@ -4091,12 +4123,16 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 	     __FUNCTION__, x, y, w, h,
 	     RegionNumRects(region)));
 
-	ok = sna->render.copy_boxes(sna, GXcopy,
-				    pixmap, src_bo, -x, -y,
-				    pixmap, priv->gpu_bo, 0, 0,
-				    RegionRects(region),
-				    RegionNumRects(region),
-				    COPY_LAST);
+	if (sigtrap_get() == 0) {
+		ok = sna->render.copy_boxes(sna, GXcopy,
+					    pixmap, src_bo, -x, -y,
+					    pixmap, priv->gpu_bo, 0, 0,
+					    RegionRects(region),
+					    RegionNumRects(region),
+					    COPY_LAST);
+		sigtrap_put();
+	} else
+		ok = false;
 
 	kgem_bo_sync__cpu(&sna->kgem, src_bo);
 	assert(src_bo->rq == NULL);
@@ -4201,6 +4237,9 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 
 	DBG(("%s: upload(%d, %d, %d, %d) x %d\n", __FUNCTION__, x, y, w, h, n));
 
+	if (sigtrap_get())
+		return false;
+
 	if (priv->gpu_bo->tiling) {
 		do {
 			memcpy_to_tiled_x(&sna->kgem, bits, dst,
@@ -4223,6 +4262,8 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 		} while (--n);
 	}
 
+	sigtrap_put();
+
 	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 		assert(!priv->clear);
 		if (replaces) {
@@ -4289,11 +4330,13 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 					     region, MOVE_WRITE))
 		return false;
 
-	DBG(("%s: upload(%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h));
+	if (sigtrap_get())
+		return false;
 
 	/* Region is pre-clipped and translated into pixmap space */
 	box = RegionRects(region);
 	n = RegionNumRects(region);
+	DBG(("%s: upload(%d, %d, %d, %d) x %d boxes\n", __FUNCTION__, x, y, w, h, n));
 	do {
 		DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n",
 		     __FUNCTION__,
@@ -4324,6 +4367,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		box++;
 	} while (--n);
 
+	sigtrap_put();
 	assert_pixmap_damage(pixmap);
 	return true;
 }
@@ -4698,10 +4742,13 @@ fallback:
 					      drawable_gc_flags(drawable, gc, false)))
 		goto out_gc;
 
-	DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
-	     __FUNCTION__, x, y, w, h));
-	fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
+		     __FUNCTION__, x, y, w, h));
+		fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -4941,30 +4988,36 @@ fallback:
 			goto out;
 
 		if (alu == GXcopy && pixmap->drawable.bitsPerPixel >= 8) {
-			FbBits *dst_bits, *src_bits;
-			int stride = pixmap->devKind;
-			int bpp = pixmap->drawable.bitsPerPixel;
-			int i;
-
-			dst_bits = (FbBits *)
-				((char *)pixmap->devPrivate.ptr +
-				 ty * stride + tx * bpp / 8);
-			src_bits = (FbBits *)
-				((char *)pixmap->devPrivate.ptr +
-				 dy * stride + dx * bpp / 8);
-
-			for (i = 0; i < n; i++)
-				memmove_box(src_bits, dst_bits,
-					    bpp, stride, box+i,
-					    dx, dy);
+			if (sigtrap_get() == 0) {
+				FbBits *dst_bits, *src_bits;
+				int stride = pixmap->devKind;
+				int bpp = pixmap->drawable.bitsPerPixel;
+				int i;
+
+				dst_bits = (FbBits *)
+					((char *)pixmap->devPrivate.ptr +
+					 ty * stride + tx * bpp / 8);
+				src_bits = (FbBits *)
+					((char *)pixmap->devPrivate.ptr +
+					 dy * stride + dx * bpp / 8);
+
+				for (i = 0; i < n; i++)
+					memmove_box(src_bits, dst_bits,
+						    bpp, stride, box+i,
+						    dx, dy);
+				sigtrap_put();
+			}
 		} else {
 			if (gc && !sna_gc_move_to_cpu(gc, dst, region))
 				goto out;
 
-			get_drawable_deltas(src, pixmap, &tx, &ty);
-			miCopyRegion(src, dst, gc,
-				     region, dx - tx, dy - ty,
-				     fbCopyNtoN, 0, NULL);
+			if (sigtrap_get() == 0) {
+				get_drawable_deltas(src, pixmap, &tx, &ty);
+				miCopyRegion(src, dst, gc,
+					     region, dx - tx, dy - ty,
+					     fbCopyNtoN, 0, NULL);
+				sigtrap_put();
+			}
 
 			if (gc)
 				sna_gc_move_to_gpu(gc);
@@ -5770,9 +5823,12 @@ fallback:
 			if (!sna_gc_move_to_cpu(gc, dst, region))
 				return;
 
-			miCopyRegion(src, dst, gc,
-				     region, dx, dy,
-				     fbCopyNtoN, 0, NULL);
+			if (sigtrap_get() == 0) {
+				miCopyRegion(src, dst, gc,
+					     region, dx, dy,
+					     fbCopyNtoN, 0, NULL);
+				sigtrap_put();
+			}
 
 			sna_gc_move_to_gpu(gc);
 		}
@@ -5943,10 +5999,13 @@ sna_fallback_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			goto out_gc;
 	}
 
-	miCopyRegion(src, dst, gc,
-		     region, dx, dy,
-		     fbCopyNtoN, 0, NULL);
-	FALLBACK_FLUSH(dst);
+	if (sigtrap_get() == 0) {
+		miCopyRegion(src, dst, gc,
+			     region, dx, dy,
+			     fbCopyNtoN, 0, NULL);
+		FALLBACK_FLUSH(dst);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 }
@@ -6978,9 +7037,12 @@ fallback:
 					     drawable_gc_flags(drawable, gc, n > 1)))
 		goto out_gc;
 
-	DBG(("%s: fbFillSpans\n", __FUNCTION__));
-	fbFillSpans(drawable, gc, n, pt, width, sorted);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbFillSpans\n", __FUNCTION__));
+		fbFillSpans(drawable, gc, n, pt, width, sorted);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -7018,9 +7080,12 @@ fallback:
 					     drawable_gc_flags(drawable, gc, n > 1)))
 		goto out_gc;
 
-	DBG(("%s: fbSetSpans\n", __FUNCTION__));
-	fbSetSpans(drawable, gc, src, pt, width, n, sorted);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbSetSpans\n", __FUNCTION__));
+		fbSetSpans(drawable, gc, src, pt, width, n, sorted);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -7514,13 +7579,16 @@ fallback:
 					     drawable_gc_flags(dst, gc, false)))
 		goto out_gc;
 
-	DBG(("%s: fbCopyPlane(%d, %d, %d, %d, %d,%d) %x\n",
-	     __FUNCTION__, src_x, src_y, w, h, dst_x, dst_y, (unsigned)bit));
-	ret = miDoCopy(src, dst, gc,
-		       src_x, src_y, w, h, dst_x, dst_y,
-		       src->bitsPerPixel > 1 ? fbCopyNto1 : fbCopy1toN,
-		       bit, 0);
-	FALLBACK_FLUSH(dst);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbCopyPlane(%d, %d, %d, %d, %d,%d) %x\n",
+		     __FUNCTION__, src_x, src_y, w, h, dst_x, dst_y, (unsigned)bit));
+		ret = miDoCopy(src, dst, gc,
+			       src_x, src_y, w, h, dst_x, dst_y,
+			       src->bitsPerPixel > 1 ? fbCopyNto1 : fbCopy1toN,
+			       bit, 0);
+		FALLBACK_FLUSH(dst);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -7725,9 +7793,12 @@ fallback:
 					     MOVE_READ | MOVE_WRITE))
 		goto out_gc;
 
-	DBG(("%s: fbPolyPoint\n", __FUNCTION__));
-	fbPolyPoint(drawable, gc, mode, n, pt, flags);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbPolyPoint\n", __FUNCTION__));
+		fbPolyPoint(drawable, gc, mode, n, pt, flags);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -8766,10 +8837,12 @@ fallback:
 							       !(data.flags & 4 && n == 2))))
 		goto out_gc;
 
-	DBG(("%s: fbPolyLine\n", __FUNCTION__));
-	fbPolyLine(drawable, gc, mode, n, pt);
-	FALLBACK_FLUSH(drawable);
-
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbPolyLine\n", __FUNCTION__));
+		fbPolyLine(drawable, gc, mode, n, pt);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -9616,10 +9689,12 @@ fallback:
 							       !(data.flags & 4 && n == 1))))
 		goto out_gc;
 
-	DBG(("%s: fbPolySegment\n", __FUNCTION__));
-	fbPolySegment(drawable, gc, n, seg);
-	FALLBACK_FLUSH(drawable);
-
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fbPolySegment\n", __FUNCTION__));
+		fbPolySegment(drawable, gc, n, seg);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -10225,9 +10300,12 @@ fallback:
 					     drawable_gc_flags(drawable, gc, true)))
 		goto out_gc;
 
-	DBG(("%s: miPolyRectangle\n", __FUNCTION__));
-	miPolyRectangle(drawable, gc, n, r);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: miPolyRectangle\n", __FUNCTION__));
+		miPolyRectangle(drawable, gc, n, r);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -10424,10 +10502,12 @@ fallback:
 					     drawable_gc_flags(drawable, gc, true)))
 		goto out_gc;
 
-	DBG(("%s -- fbPolyArc\n", __FUNCTION__));
-	fbPolyArc(drawable, gc, n, arc);
-	FALLBACK_FLUSH(drawable);
-
+	if (sigtrap_get() == 0) {
+		DBG(("%s -- fbPolyArc\n", __FUNCTION__));
+		fbPolyArc(drawable, gc, n, arc);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -10778,9 +10858,12 @@ fallback:
 					     drawable_gc_flags(draw, gc, true)))
 		goto out_gc;
 
-	DBG(("%s: fallback -- miFillPolygon -> sna_fill_spans__cpu\n",
-	     __FUNCTION__));
-	miFillPolygon(draw, gc, shape, mode, n, pt);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback -- miFillPolygon -> sna_fill_spans__cpu\n",
+		     __FUNCTION__));
+		miFillPolygon(draw, gc, shape, mode, n, pt);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -13051,9 +13134,12 @@ fallback:
 					     drawable_gc_flags(draw, gc, n > 1)))
 		goto out_gc;
 
-	DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
-	fbPolyFillRect(draw, gc, n, rect);
-	FALLBACK_FLUSH(draw);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
+		fbPolyFillRect(draw, gc, n, rect);
+		FALLBACK_FLUSH(draw);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -13220,10 +13306,12 @@ fallback:
 					     drawable_gc_flags(draw, gc, true)))
 		goto out_gc;
 
-	DBG(("%s: fallback -- miPolyFillArc -> sna_fill_spans__cpu\n",
-	     __FUNCTION__));
-
-	miPolyFillArc(draw, gc, n, arc);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback -- miPolyFillArc -> sna_fill_spans__cpu\n",
+		     __FUNCTION__));
+		miPolyFillArc(draw, gc, n, arc);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -13713,10 +13801,13 @@ fallback:
 						     MOVE_READ | MOVE_WRITE))
 			goto out_gc;
 
-		DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
-		fbPolyGlyphBlt(drawable, gc, x, y, n,
-			       info, FONTGLYPHS(gc->font));
-		FALLBACK_FLUSH(drawable);
+		if (sigtrap_get() == 0) {
+			DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
+			fbPolyGlyphBlt(drawable, gc, x, y, n,
+				       info, FONTGLYPHS(gc->font));
+			FALLBACK_FLUSH(drawable);
+			sigtrap_put();
+		}
 out_gc:
 		sna_gc_move_to_gpu(gc);
 	}
@@ -13788,10 +13879,13 @@ fallback:
 						     MOVE_READ | MOVE_WRITE))
 			goto out_gc;
 
-		DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
-		fbPolyGlyphBlt(drawable, gc, x, y, n,
-			       info, FONTGLYPHS(gc->font));
-		FALLBACK_FLUSH(drawable);
+		if (sigtrap_get() == 0) {
+			DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
+			fbPolyGlyphBlt(drawable, gc, x, y, n,
+				       info, FONTGLYPHS(gc->font));
+			FALLBACK_FLUSH(drawable);
+			sigtrap_put();
+		}
 out_gc:
 		sna_gc_move_to_gpu(gc);
 	}
@@ -13870,10 +13964,13 @@ fallback:
 		if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
 			goto out_gc;
 
-		DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
-		fbImageGlyphBlt(drawable, gc, x, y, n,
-				info, FONTGLYPHS(gc->font));
-		FALLBACK_FLUSH(drawable);
+		if (sigtrap_get() == 0) {
+			DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
+			fbImageGlyphBlt(drawable, gc, x, y, n,
+					info, FONTGLYPHS(gc->font));
+			FALLBACK_FLUSH(drawable);
+			sigtrap_put();
+		}
 out_gc:
 		sna_gc_move_to_gpu(gc);
 	}
@@ -13952,10 +14049,13 @@ fallback:
 		if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
 			goto out_gc;
 
-		DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
-		fbImageGlyphBlt(drawable, gc, x, y, n,
-				info, FONTGLYPHS(gc->font));
-		FALLBACK_FLUSH(drawable);
+		if (sigtrap_get() == 0) {
+			DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
+			fbImageGlyphBlt(drawable, gc, x, y, n,
+					info, FONTGLYPHS(gc->font));
+			FALLBACK_FLUSH(drawable);
+			sigtrap_put();
+		}
 out_gc:
 		sna_gc_move_to_gpu(gc);
 	}
@@ -14280,10 +14380,12 @@ fallback:
 	if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
 		goto out_gc;
 
-	DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
-	fbImageGlyphBlt(drawable, gc, x, y, n, info, base);
-	FALLBACK_FLUSH(drawable);
-
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
+		fbImageGlyphBlt(drawable, gc, x, y, n, info, base);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -14360,10 +14462,12 @@ fallback:
 					     MOVE_READ | MOVE_WRITE))
 		goto out_gc;
 
-	DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
-	fbPolyGlyphBlt(drawable, gc, x, y, n, info, base);
-	FALLBACK_FLUSH(drawable);
-
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
+		fbPolyGlyphBlt(drawable, gc, x, y, n, info, base);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -14545,10 +14649,13 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 					     drawable_gc_flags(drawable, gc, false)))
 		goto out_gc;
 
-	DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n",
-	     __FUNCTION__, w, h, x, y));
-	fbPushPixels(gc, bitmap, drawable, w, h, x, y);
-	FALLBACK_FLUSH(drawable);
+	if (sigtrap_get() == 0) {
+		DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n",
+		     __FUNCTION__, w, h, x, y));
+		fbPushPixels(gc, bitmap, drawable, w, h, x, y);
+		FALLBACK_FLUSH(drawable);
+		sigtrap_put();
+	}
 out_gc:
 	sna_gc_move_to_gpu(gc);
 out:
@@ -14967,8 +15074,11 @@ sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src)
 		if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE))
 			return;
 
-		miCopyRegion(&pixmap->drawable, &pixmap->drawable,
-			     0, &dst, dx, dy, fbCopyNtoN, 0, NULL);
+		if (sigtrap_get() == 0) {
+			miCopyRegion(&pixmap->drawable, &pixmap->drawable,
+				     0, &dst, dx, dy, fbCopyNtoN, 0, NULL);
+			sigtrap_put();
+		}
 	} else {
 		sna_self_copy_boxes(&pixmap->drawable, &pixmap->drawable, NULL,
 				    &dst, dx, dy, 0, NULL);
@@ -15285,41 +15395,44 @@ fallback:
 			if (!sna_pixmap_move_to_cpu(dst, MOVE_READ | MOVE_WRITE | MOVE_INPLACE_HINT))
 				goto skip;
 
-			assert(src->drawable.bitsPerPixel == dst->drawable.bitsPerPixel);
-			do {
-				DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n",
-				     __FUNCTION__,
-				     box->x1 + dirty->x, box->y1 + dirty->y,
-				     box->x1, box->y1,
-				     box->x2 - box->x1, box->y2 - box->y1));
-
-				assert(box->x2 > box->x1);
-				assert(box->y2 > box->y1);
-
-				assert(box->x1 + dirty->x >= 0);
-				assert(box->y1 + dirty->y >= 0);
-				assert(box->x2 + dirty->x <= src->drawable.width);
-				assert(box->y2 + dirty->y <= src->drawable.height);
-
-				assert(box->x1 >= 0);
-				assert(box->y1 >= 0);
-				assert(box->x2 <= src->drawable.width);
-				assert(box->y2 <= src->drawable.height);
-
-				assert(has_coherent_ptr(sna, sna_pixmap(src)));
-				assert(has_coherent_ptr(sna, sna_pixmap(dst)));
-				memcpy_blt(src->devPrivate.ptr,
-					   dst->devPrivate.ptr,
-					   src->drawable.bitsPerPixel,
-					   src->devKind, dst->devKind,
-					   box->x1 + dirty->x,
-					   box->y1 + dirty->y,
-					   box->x1,
-					   box->y1,
-					   box->x2 - box->x1,
-					   box->y2 - box->y1);
-				box++;
-			} while (--n);
+			if (sigtrap_get() == 0) {
+				assert(src->drawable.bitsPerPixel == dst->drawable.bitsPerPixel);
+				do {
+					DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n",
+					     __FUNCTION__,
+					     box->x1 + dirty->x, box->y1 + dirty->y,
+					     box->x1, box->y1,
+					     box->x2 - box->x1, box->y2 - box->y1));
+
+					assert(box->x2 > box->x1);
+					assert(box->y2 > box->y1);
+
+					assert(box->x1 + dirty->x >= 0);
+					assert(box->y1 + dirty->y >= 0);
+					assert(box->x2 + dirty->x <= src->drawable.width);
+					assert(box->y2 + dirty->y <= src->drawable.height);
+
+					assert(box->x1 >= 0);
+					assert(box->y1 >= 0);
+					assert(box->x2 <= src->drawable.width);
+					assert(box->y2 <= src->drawable.height);
+
+					assert(has_coherent_ptr(sna, sna_pixmap(src)));
+					assert(has_coherent_ptr(sna, sna_pixmap(dst)));
+					memcpy_blt(src->devPrivate.ptr,
+						   dst->devPrivate.ptr,
+						   src->drawable.bitsPerPixel,
+						   src->devKind, dst->devKind,
+						   box->x1 + dirty->x,
+						   box->y1 + dirty->y,
+						   box->x1,
+						   box->y1,
+						   box->x2 - box->x1,
+						   box->y2 - box->y1);
+					box++;
+				} while (--n);
+				sigtrap_put();
+			}
 		} else {
 			if (!sna_pixmap_move_to_gpu(src, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_FORCE))
 				goto fallback;
@@ -15725,6 +15838,7 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	     __FUNCTION__, backend, sna->render.prefer_gpu));
 
 	kgem_reset(&sna->kgem);
+	sigtrap_init();
 
 	xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 		   "SNA initialized with %s backend\n",
@@ -15796,6 +15910,8 @@ void sna_accel_close(struct sna *sna)
 
 void sna_accel_block_handler(struct sna *sna, struct timeval **tv)
 {
+	sigtrap_assert();
+
 	if (sna->kgem.need_retire)
 		kgem_retire(&sna->kgem);
 
@@ -15877,9 +15993,12 @@ void sna_accel_wakeup_handler(struct sna *sna)
 		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
 		_kgem_submit(&sna->kgem);
 	}
+
+	sigtrap_assert();
 }
 
 void sna_accel_free(struct sna *sna)
 {
 	DBG(("%s\n", __FUNCTION__));
+	sigtrap_assert();
 }
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 085a627..1feba4b 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -541,45 +541,49 @@ sna_composite_fb(CARD8 op,
 		    region->extents.y1 + sy >= 0 &&
 		    region->extents.x2 + sx <= src->pDrawable->width &&
 		    region->extents.y2 + sy <= src->pDrawable->height) {
-			BoxPtr box = RegionRects(region);
-			int nbox = RegionNumRects(region);
-
-			sx += src->pDrawable->x;
-			sy += src->pDrawable->y;
-			if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty))
-				sx += tx, sy += ty;
-
-			assert(region->extents.x1 + sx >= 0);
-			assert(region->extents.x2 + sx <= src_pixmap->drawable.width);
-			assert(region->extents.y1 + sy >= 0);
-			assert(region->extents.y2 + sy <= src_pixmap->drawable.height);
-
-			get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
-
-			assert(nbox);
-			do {
-				assert(box->x1 + sx >= 0);
-				assert(box->x2 + sx <= src_pixmap->drawable.width);
-				assert(box->y1 + sy >= 0);
-				assert(box->y2 + sy <= src_pixmap->drawable.height);
-
-				assert(box->x1 + tx >= 0);
-				assert(box->x2 + tx <= dst_pixmap->drawable.width);
-				assert(box->y1 + ty >= 0);
-				assert(box->y2 + ty <= dst_pixmap->drawable.height);
-
-				assert(box->x2 > box->x1 && box->y2 > box->y1);
-
-				memcpy_blt(src_pixmap->devPrivate.ptr,
-					   dst_pixmap->devPrivate.ptr,
-					   dst_pixmap->drawable.bitsPerPixel,
-					   src_pixmap->devKind,
-					   dst_pixmap->devKind,
-					   box->x1 + sx, box->y1 + sy,
-					   box->x1 + tx, box->y1 + ty,
-					   box->x2 - box->x1, box->y2 - box->y1);
-				box++;
-			} while (--nbox);
+			sigtrap_assert();
+			if (sigtrap_get() == 0) {
+				BoxPtr box = RegionRects(region);
+				int nbox = RegionNumRects(region);
+
+				sx += src->pDrawable->x;
+				sy += src->pDrawable->y;
+				if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty))
+					sx += tx, sy += ty;
+
+				assert(region->extents.x1 + sx >= 0);
+				assert(region->extents.x2 + sx <= src_pixmap->drawable.width);
+				assert(region->extents.y1 + sy >= 0);
+				assert(region->extents.y2 + sy <= src_pixmap->drawable.height);
+
+				get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
+
+				assert(nbox);
+				do {
+					assert(box->x1 + sx >= 0);
+					assert(box->x2 + sx <= src_pixmap->drawable.width);
+					assert(box->y1 + sy >= 0);
+					assert(box->y2 + sy <= src_pixmap->drawable.height);
+
+					assert(box->x1 + tx >= 0);
+					assert(box->x2 + tx <= dst_pixmap->drawable.width);
+					assert(box->y1 + ty >= 0);
+					assert(box->y2 + ty <= dst_pixmap->drawable.height);
+
+					assert(box->x2 > box->x1 && box->y2 > box->y1);
+
+					memcpy_blt(src_pixmap->devPrivate.ptr,
+						   dst_pixmap->devPrivate.ptr,
+						   dst_pixmap->drawable.bitsPerPixel,
+						   src_pixmap->devKind,
+						   dst_pixmap->devKind,
+						   box->x1 + sx, box->y1 + sy,
+						   box->x1 + tx, box->y1 + ty,
+						   box->x2 - box->x1, box->y2 - box->y1);
+					box++;
+				} while (--nbox);
+				sigtrap_put();
+			}
 
 			return;
 		}
@@ -589,12 +593,17 @@ sna_composite_fb(CARD8 op,
 	mask_image = image_from_pict(mask, FALSE, &msk_xoff, &msk_yoff);
 	dest_image = image_from_pict(dst, TRUE, &dst_xoff, &dst_yoff);
 
-	if (src_image && dest_image && !(mask && !mask_image))
-		sna_image_composite(op, src_image, mask_image, dest_image,
-				    src_x + src_xoff, src_y + src_yoff,
-				    msk_x + msk_xoff, msk_y + msk_yoff,
-				    dst_x + dst_xoff, dst_y + dst_yoff,
-				    width, height);
+	if (src_image && dest_image && !(mask && !mask_image)) {
+		sigtrap_assert();
+		if (sigtrap_get() == 0) {
+			sna_image_composite(op, src_image, mask_image, dest_image,
+					    src_x + src_xoff, src_y + src_yoff,
+					    msk_x + msk_xoff, msk_y + msk_yoff,
+					    dst_x + dst_xoff, dst_y + dst_yoff,
+					    width, height);
+			sigtrap_put();
+		}
+	}
 
 	free_pixman_pict(src, src_image);
 	free_pixman_pict(mask, mask_image);
@@ -739,6 +748,7 @@ fallback:
 			 width,  height);
 out:
 	REGION_UNINIT(NULL, &region);
+	sigtrap_assert();
 }
 
 static bool
@@ -1051,65 +1061,70 @@ fallback:
 
 	assert(pixmap->devPrivate.ptr);
 
-	if (op <= PictOpSrc) {
-		int nbox = RegionNumRects(&region);
-		BoxPtr box = RegionRects(&region);
-		uint32_t pixel;
-
-		if (op == PictOpClear)
-			pixel = 0;
-		else if (!sna_get_pixel_from_rgba(&pixel,
-						  color->red,
-						  color->green,
-						  color->blue,
-						  color->alpha,
-						  dst->format))
-			goto fallback_composite;
-
-		if (pixel == 0 &&
-		    box->x2 - box->x1 == pixmap->drawable.width &&
-		    box->y2 - box->y1 == pixmap->drawable.height) {
-			memset(pixmap->devPrivate.ptr, 0,
-			       pixmap->devKind*pixmap->drawable.height);
-		} else do {
-			DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
-			     __FUNCTION__,
-			     box->x1, box->y1,
-			     box->x2 - box->x1,
-			     box->y2 - box->y1,
-			     pixel));
-
-			pixman_fill(pixmap->devPrivate.ptr,
-				    pixmap->devKind/sizeof(uint32_t),
-				    pixmap->drawable.bitsPerPixel,
-				    box->x1, box->y1,
-				    box->x2 - box->x1,
-				    box->y2 - box->y1,
-				    pixel);
-			box++;
-		} while (--nbox);
-	} else {
-		PicturePtr src;
+	sigtrap_assert();
+	if (sigtrap_get() == 0) {
+		if (op <= PictOpSrc) {
+			int nbox = RegionNumRects(&region);
+			BoxPtr box = RegionRects(&region);
+			uint32_t pixel;
+
+			if (op == PictOpClear)
+				pixel = 0;
+			else if (!sna_get_pixel_from_rgba(&pixel,
+							  color->red,
+							  color->green,
+							  color->blue,
+							  color->alpha,
+							  dst->format))
+				goto fallback_composite;
+
+			if (pixel == 0 &&
+			    box->x2 - box->x1 == pixmap->drawable.width &&
+			    box->y2 - box->y1 == pixmap->drawable.height) {
+				memset(pixmap->devPrivate.ptr, 0,
+				       pixmap->devKind*pixmap->drawable.height);
+			} else do {
+				DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
+				     __FUNCTION__,
+				     box->x1, box->y1,
+				     box->x2 - box->x1,
+				     box->y2 - box->y1,
+				     pixel));
+
+				pixman_fill(pixmap->devPrivate.ptr,
+					    pixmap->devKind/sizeof(uint32_t),
+					    pixmap->drawable.bitsPerPixel,
+					    box->x1, box->y1,
+					    box->x2 - box->x1,
+					    box->y2 - box->y1,
+					    pixel);
+				box++;
+			} while (--nbox);
+		} else {
+			PicturePtr src;
 
 fallback_composite:
-		DBG(("%s: fallback -- fbComposite()\n", __FUNCTION__));
-		src = CreateSolidPicture(0, color, &error);
-		if (src) {
-			do {
-				fbComposite(op, src, NULL, dst,
-					    0, 0,
-					    0, 0,
-					    rects->x, rects->y,
-					    rects->width, rects->height);
-				rects++;
-			} while (--num_rects);
-			FreePicture(src, 0);
+			DBG(("%s: fallback -- fbComposite()\n", __FUNCTION__));
+			src = CreateSolidPicture(0, color, &error);
+			if (src) {
+				do {
+					fbComposite(op, src, NULL, dst,
+						    0, 0,
+						    0, 0,
+						    rects->x, rects->y,
+						    rects->width, rects->height);
+					rects++;
+				} while (--num_rects);
+				FreePicture(src, 0);
+			}
 		}
+		sigtrap_put();
 	}
 
 done:
 	DamageRegionProcessPending(&pixmap->drawable);
 
 	pixman_region_fini(&region);
+	sigtrap_assert();
 	return;
 }
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 032c776..28ddce5 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3855,8 +3855,7 @@ sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region)
 	PictFormatPtr format;
 	PicturePtr src, dst;
 	PixmapPtr pixmap;
-	BoxPtr b;
-	int n, error;
+	int error;
 	void *ptr;
 
 	DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__));
@@ -3907,25 +3906,29 @@ sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region)
 		goto free_src;
 
 	kgem_bo_sync__gtt(&sna->kgem, sna_crtc->bo);
-	n = REGION_NUM_RECTS(region);
-	b = REGION_RECTS(region);
-	do {
-		BoxRec box;
-
-		box = *b++;
-		transformed_box(&box, crtc);
-
-		DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
-		     __FUNCTION__,
-		     b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
-		     box.x1, box.y1, box.x2, box.y2));
 
-		fbComposite(PictOpSrc, src, NULL, dst,
-			    box.x1, box.y1,
-			    0, 0,
-			    box.x1, box.y1,
-			    box.x2 - box.x1, box.y2 - box.y1);
-	} while (--n);
+	if (sigtrap_get() == 0) { /* paranoia */
+		const BoxRec *b = REGION_RECTS(region);
+		int n = REGION_NUM_RECTS(region);
+		do {
+			BoxRec box;
+
+			box = *b++;
+			transformed_box(&box, crtc);
+
+			DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
+			     __FUNCTION__,
+			     b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
+			     box.x1, box.y1, box.x2, box.y2));
+
+			fbComposite(PictOpSrc, src, NULL, dst,
+				    box.x1, box.y1,
+				    0, 0,
+				    box.x1, box.y1,
+				    box.x2 - box.x1, box.y2 - box.y1);
+		} while (--n);
+		sigtrap_put();
+	}
 
 	FreePicture(dst, None);
 free_src:
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 56cb78f..a009d3e 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -611,14 +611,17 @@ sna_dri_copy_fallback(struct sna *sna, int bpp,
 	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
 	     __FUNCTION__, sx, sy, dx, dy, n));
 
-	do {
-		memcpy_blt(src, dst, bpp,
-			   src_bo->pitch, dst_bo->pitch,
-			   box->x1 + sx, box->y1 + sy,
-			   box->x1 + dx, box->y1 + dy,
-			   box->x2 - box->x1, box->y2 - box->y1);
-		box++;
-	} while (--n);
+	if (sigtrap_get() == 0) {
+		do {
+			memcpy_blt(src, dst, bpp,
+				   src_bo->pitch, dst_bo->pitch,
+				   box->x1 + sx, box->y1 + sy,
+				   box->x1 + dx, box->y1 + dy,
+				   box->x2 - box->x1, box->y2 - box->y1);
+			box++;
+		} while (--n);
+		sigtrap_put();
+	}
 }
 
 static struct kgem_bo *
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index b56c844..b7ccb88 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1627,21 +1627,25 @@ next:
 		if (dst_image == NULL)
 			goto out_free_src;
 
-		if (mask_format) {
-			pixman_composite_glyphs(op, src_image, dst_image,
-						mask_format->format | (mask_format->depth << 24),
-						src_x + src_dx + region.extents.x1 - dst_x,
-						src_y + src_dy + region.extents.y1 - dst_y,
-						region.extents.x1, region.extents.y1,
-						region.extents.x1 + dst_dx, region.extents.y1 + dst_dy,
-						region.extents.x2 - region.extents.x1,
-						region.extents.y2 - region.extents.y1,
-						cache, count, pglyphs);
-		} else {
-			pixman_composite_glyphs_no_mask(op, src_image, dst_image,
-							src_x + src_dx - dst_x, src_y + src_dy - dst_y,
-							dst_dx, dst_dy,
+		sigtrap_assert();
+		if (sigtrap_get() == 0) {
+			if (mask_format) {
+				pixman_composite_glyphs(op, src_image, dst_image,
+							mask_format->format | (mask_format->depth << 24),
+							src_x + src_dx + region.extents.x1 - dst_x,
+							src_y + src_dy + region.extents.y1 - dst_y,
+							region.extents.x1, region.extents.y1,
+							region.extents.x1 + dst_dx, region.extents.y1 + dst_dy,
+							region.extents.x2 - region.extents.x1,
+							region.extents.y2 - region.extents.y1,
 							cache, count, pglyphs);
+			} else {
+				pixman_composite_glyphs_no_mask(op, src_image, dst_image,
+								src_x + src_dx - dst_x, src_y + src_dy - dst_y,
+								dst_dx, dst_dy,
+								cache, count, pglyphs);
+			}
+			sigtrap_put();
 		}
 
 		free_pixman_pict(dst, dst_image);
@@ -1706,86 +1710,90 @@ out:
 			src_y -= y - dst->pDrawable->y;
 		}
 
-		do {
-			n = list->len;
-			x += list->xOff;
-			y += list->yOff;
-			while (n--) {
-				GlyphPtr g = *glyphs++;
-				pixman_image_t *glyph_image;
+		sigtrap_assert();
+		if (sigtrap_get() == 0) {
+			do {
+				n = list->len;
+				x += list->xOff;
+				y += list->yOff;
+				while (n--) {
+					GlyphPtr g = *glyphs++;
+					pixman_image_t *glyph_image;
 
-				if (!glyph_valid(g))
-					goto next_glyph;
+					if (!glyph_valid(g))
+						goto next_glyph;
 
-				glyph_image = sna_glyph_get_image(g, screen);
-				if (glyph_image == NULL)
-					goto next_glyph;
+					glyph_image = sna_glyph_get_image(g, screen);
+					if (glyph_image == NULL)
+						goto next_glyph;
 
-				if (mask_format) {
-					DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n",
-					     __FUNCTION__,
-					     x - g->info.x,
-					     y - g->info.y,
-					     g->info.width,
-					     g->info.height));
-
-					if (list->format == mask_format) {
-						assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
-						pixman_image_composite(PictOpAdd,
-								       glyph_image,
-								       NULL,
-								       mask_image,
-								       0, 0,
-								       0, 0,
-								       x - g->info.x,
-								       y - g->info.y,
-								       g->info.width,
-								       g->info.height);
+					if (mask_format) {
+						DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n",
+						     __FUNCTION__,
+						     x - g->info.x,
+						     y - g->info.y,
+						     g->info.width,
+						     g->info.height));
+
+						if (list->format == mask_format) {
+							assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
+							pixman_image_composite(PictOpAdd,
+									       glyph_image,
+									       NULL,
+									       mask_image,
+									       0, 0,
+									       0, 0,
+									       x - g->info.x,
+									       y - g->info.y,
+									       g->info.width,
+									       g->info.height);
+						} else {
+							pixman_image_composite(PictOpAdd,
+									       sna->render.white_image,
+									       glyph_image,
+									       mask_image,
+									       0, 0,
+									       0, 0,
+									       x - g->info.x,
+									       y - g->info.y,
+									       g->info.width,
+									       g->info.height);
+						}
 					} else {
-						pixman_image_composite(PictOpAdd,
-								       sna->render.white_image,
+						int xi = x - g->info.x;
+						int yi = y - g->info.y;
+
+						DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n",
+						     __FUNCTION__,
+						     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));
+
+						pixman_image_composite(op,
+								       src_image,
 								       glyph_image,
-								       mask_image,
+								       dst_image,
+								       src_x + xi,
+								       src_y + yi,
 								       0, 0,
-								       0, 0,
-								       x - g->info.x,
-								       y - g->info.y,
+								       xi, yi,
 								       g->info.width,
 								       g->info.height);
 					}
-				} else {
-					int xi = x - g->info.x;
-					int yi = y - g->info.y;
-
-					DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n",
-					     __FUNCTION__,
-					     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));
-
-					pixman_image_composite(op,
-							       src_image,
-							       glyph_image,
-							       dst_image,
-							       src_x + xi,
-							       src_y + yi,
-							       0, 0,
-							       xi, yi,
-							       g->info.width,
-							       g->info.height);
-				}
 next_glyph:
-				x += g->info.xOff;
-				y += g->info.yOff;
-			}
-			list++;
-		} while (--nlist);
+					x += g->info.xOff;
+					y += g->info.yOff;
+				}
+				list++;
+			} while (--nlist);
+			sigtrap_put();
+		}
 
 		if (mask_format) {
 			DBG(("%s: glyph mask composite src=(%d+%d,%d+%d) dst=(%d, %d)x(%d, %d)\n",
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 746b122..d66668c 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -113,6 +113,11 @@ read_boxes_inplace__cpu(struct kgem *kgem,
 		return false;
 
 	kgem_bo_sync__cpu_full(kgem, bo, 0);
+
+	sigtrap_assert();
+	if (sigtrap_get())
+		return false;
+
 	if (bo->tiling == I915_TILING_X) {
 		assert(kgem->memcpy_from_tiled_x);
 		do {
@@ -132,6 +137,7 @@ read_boxes_inplace__cpu(struct kgem *kgem,
 		} while (--n);
 	}
 
+	sigtrap_put();
 	return true;
 }
 
@@ -158,6 +164,10 @@ static void read_boxes_inplace(struct kgem *kgem,
 	if (src == NULL)
 		return;
 
+	sigtrap_assert();
+	if (sigtrap_get())
+		return;
+
 	assert(src != dst);
 	do {
 		DBG(("%s: copying box (%d, %d), (%d, %d)\n",
@@ -183,6 +193,8 @@ static void read_boxes_inplace(struct kgem *kgem,
 			   box->x2 - box->x1, box->y2 - box->y1);
 		box++;
 	} while (--n);
+
+	sigtrap_put();
 }
 
 static bool download_inplace(struct kgem *kgem,
@@ -578,6 +590,11 @@ write_boxes_inplace__tiled(struct kgem *kgem,
 		return false;
 
 	kgem_bo_sync__cpu(kgem, bo);
+
+	sigtrap_assert();
+	if (sigtrap_get())
+		return false;
+
 	do {
 		memcpy_to_tiled_x(kgem, src, dst, bpp, stride, bo->pitch,
 				  box->x1 + src_dx, box->y1 + src_dy,
@@ -586,6 +603,7 @@ write_boxes_inplace__tiled(struct kgem *kgem,
 		box++;
 	} while (--n);
 
+	sigtrap_put();
 	return true;
 }
 
@@ -615,6 +633,10 @@ static bool write_boxes_inplace(struct kgem *kgem,
 
 	assert(dst != src);
 
+	sigtrap_assert();
+	if (sigtrap_get())
+		return false;
+
 	do {
 		DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d) [bpp=%d, src_pitch=%d, dst_pitch=%d]\n", __FUNCTION__,
 		     box->x1 + src_dx, box->y1 + src_dy,
@@ -641,6 +663,8 @@ static bool write_boxes_inplace(struct kgem *kgem,
 			   box->x2 - box->x1, box->y2 - box->y1);
 		box++;
 	} while (--n);
+
+	sigtrap_put();
 	return true;
 }
 
@@ -794,37 +818,41 @@ tile:
 						goto fallback;
 					}
 
-					c = clipped;
-					for (n = 0; n < nbox; n++) {
-						*c = box[n];
-						if (!box_intersect(c, &tile))
-							continue;
-
-						DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n",
-						     __FUNCTION__,
-						     c->x1, c->y1,
-						     c->x2, c->y2,
-						     src_dx, src_dy,
-						     c->x1 - tile.x1,
-						     c->y1 - tile.y1));
-						memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel,
-							   stride, src_bo->pitch,
-							   c->x1 + src_dx,
-							   c->y1 + src_dy,
-							   c->x1 - tile.x1,
-							   c->y1 - tile.y1,
-							   c->x2 - c->x1,
-							   c->y2 - c->y1);
-						c++;
-					}
-
-					if (c != clipped)
-						n = sna->render.copy_boxes(sna, GXcopy,
-									   &tmp, src_bo, -tile.x1, -tile.y1,
-									   dst, dst_bo, dst_dx, dst_dy,
-									   clipped, c - clipped, 0);
-					else
-						n = 1;
+					if (sigtrap_get() == 0) {
+						c = clipped;
+						for (n = 0; n < nbox; n++) {
+							*c = box[n];
+							if (!box_intersect(c, &tile))
+								continue;
+
+							DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n",
+							     __FUNCTION__,
+							     c->x1, c->y1,
+							     c->x2, c->y2,
+							     src_dx, src_dy,
+							     c->x1 - tile.x1,
+							     c->y1 - tile.y1));
+							memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel,
+								   stride, src_bo->pitch,
+								   c->x1 + src_dx,
+								   c->y1 + src_dy,
+								   c->x1 - tile.x1,
+								   c->y1 - tile.y1,
+								   c->x2 - c->x1,
+								   c->y2 - c->y1);
+							c++;
+						}
+
+						if (c != clipped)
+							n = sna->render.copy_boxes(sna, GXcopy,
+										   &tmp, src_bo, -tile.x1, -tile.y1,
+										   dst, dst_bo, dst_dx, dst_dy,
+										   clipped, c - clipped, 0);
+						else
+							n = 1;
+						sigtrap_put();
+					} else
+						n = 0;
 
 					kgem_bo_destroy(&sna->kgem, src_bo);
 
@@ -1408,21 +1436,26 @@ indirect_replace(struct sna *sna,
 	if (!src_bo)
 		return false;
 
-	memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
-		   stride, src_bo->pitch,
-		   0, 0,
-		   0, 0,
-		   pixmap->drawable.width,
-		   pixmap->drawable.height);
+	sigtrap_assert();
+	if (sigtrap_get() == 0) {
+		memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
+			   stride, src_bo->pitch,
+			   0, 0,
+			   0, 0,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height);
 
-	box.x1 = 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;
 
-	ret = sna->render.copy_boxes(sna, GXcopy,
-				     pixmap, src_bo, 0, 0,
-				     pixmap, bo, 0, 0,
-				     &box, 1, 0);
+		ret = sna->render.copy_boxes(sna, GXcopy,
+					     pixmap, src_bo, 0, 0,
+					     pixmap, bo, 0, 0,
+					     &box, 1, 0);
+		sigtrap_put();
+	} else
+		ret = false;
 
 	kgem_bo_destroy(kgem, src_bo);
 
@@ -1485,14 +1518,17 @@ bool sna_replace(struct sna *sna,
 			goto done;
 	}
 
+	sigtrap_assert();
 	if (kgem_bo_is_mappable(kgem, bo) &&
-	    (dst = kgem_bo_map(kgem, bo)) != NULL) {
+	    (dst = kgem_bo_map(kgem, bo)) != NULL &&
+	    sigtrap_get() == 0) {
 		memcpy_blt(src, dst, pixmap->drawable.bitsPerPixel,
 			   stride, bo->pitch,
 			   0, 0,
 			   0, 0,
 			   pixmap->drawable.width,
 			   pixmap->drawable.height);
+		sigtrap_put();
 	} else {
 		BoxRec box;
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 84275c4..73d53ba 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1676,11 +1676,14 @@ do_fixup:
 
 	DBG(("%s: compositing tmp=(%d+%d, %d+%d)x(%d, %d)\n",
 	     __FUNCTION__, x, dx, y, dy, w, h));
-	sna_image_composite(PictOpSrc, src, NULL, dst,
-			    x + dx, y + dy,
-			    0, 0,
-			    0, 0,
-			    w, h);
+	if (sigtrap_get() == 0) {
+		sna_image_composite(PictOpSrc, src, NULL, dst,
+				    x + dx, y + dy,
+				    0, 0,
+				    0, 0,
+				    w, h);
+		sigtrap_put();
+	}
 	free_pixman_pict(picture, src);
 
 	/* Then convert to card format */
@@ -1883,11 +1886,14 @@ sna_render_picture_convert(struct sna *sna,
 			return 0;
 		}
 
-		pixman_image_composite(PictOpSrc, src, NULL, dst,
-				       box.x1, box.y1,
-				       0, 0,
-				       0, 0,
-				       w, h);
+		if (sigtrap_get() == 0) {
+			pixman_image_composite(PictOpSrc, src, NULL, dst,
+					       box.x1, box.y1,
+					       0, 0,
+					       0, 0,
+					       w, h);
+			sigtrap_put();
+		}
 		pixman_image_unref(dst);
 		pixman_image_unref(src);
 	}
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index aa5fe8f..925ba14 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -249,12 +249,15 @@ sna_tiling_composite_done(struct sna *sna,
 							      MOVE_READ))
 					goto done;
 
-				fbComposite(tile->op,
-					    tile->src, tile->mask, tile->dst,
-					    tile->src_x + x,  tile->src_y + y,
-					    tile->mask_x + x, tile->mask_y + y,
-					    tile->dst_x + x,  tile->dst_y + y,
-					    width, height);
+				if (sigtrap_get() == 0) {
+					fbComposite(tile->op,
+						    tile->src, tile->mask, tile->dst,
+						    tile->src_x + x,  tile->src_y + y,
+						    tile->mask_x + x, tile->mask_y + y,
+						    tile->dst_x + x,  tile->dst_y + y,
+						    width, height);
+					sigtrap_put();
+				}
 			}
 		}
 	}
@@ -499,12 +502,15 @@ sna_tiling_composite_spans_done(struct sna *sna,
 						if (!mask)
 							goto done;
 
-						fbComposite(tile->op,
-							    tile->src, mask, tile->dst,
-							    tile->src_x + x,  tile->src_y + y,
-							    0, 0,
-							    tile->dst_x + x,  tile->dst_y + y,
-							    width, height);
+						if (sigtrap_get() == 0) {
+							fbComposite(tile->op,
+								    tile->src, mask, tile->dst,
+								    tile->src_x + x,  tile->src_y + y,
+								    0, 0,
+								    tile->dst_x + x,  tile->dst_y + y,
+								    width, height);
+							sigtrap_put();
+						}
 
 						FreePicture(mask, 0);
 					}
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index ce2c075..3f41400 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -2411,10 +2411,13 @@ trapezoids_inplace_fallback(struct sna *sna,
 		dx += dst->pDrawable->x;
 		dy += dst->pDrawable->y;
 
-		for (; ntrap; ntrap--, traps++)
-			pixman_rasterize_trapezoid(image,
-						   (pixman_trapezoid_t *)traps,
-						   dx, dy);
+		if (sigtrap_get() == 0) {
+			for (; ntrap; ntrap--, traps++)
+				pixman_rasterize_trapezoid(image,
+							   (pixman_trapezoid_t *)traps,
+							   dx, dy);
+			sigtrap_put();
+		}
 
 		pixman_image_unref(image);
 	}
@@ -2800,15 +2803,18 @@ composite_aligned_boxes(struct sna *sna,
 			pixman_region_init_rects(&region, boxes, num_boxes);
 			RegionIntersect(&region, &region, &clip);
 
-			b = REGION_RECTS(&region);
-			count = REGION_NUM_RECTS(&region);
-			for (i = 0; i < count; i++) {
-				fbComposite(op, src, NULL, dst,
-					    src_x + b[i].x1 - boxes[0].x1,
-					    src_y + b[i].y1 - boxes[0].y1,
-					    0, 0,
-					    b[i].x1, b[i].y1,
-					    b[i].x2 - b[i].x1, b[i].y2 - b[i].y1);
+			if (sigtrap_get() == 0) {
+				b = REGION_RECTS(&region);
+				count = REGION_NUM_RECTS(&region);
+				for (i = 0; i < count; i++) {
+					fbComposite(op, src, NULL, dst,
+						    src_x + b[i].x1 - boxes[0].x1,
+						    src_y + b[i].y1 - boxes[0].y1,
+						    0, 0,
+						    b[i].x1, b[i].y1,
+						    b[i].x2 - b[i].x1, b[i].y2 - b[i].y1);
+				}
+				sigtrap_put();
 			}
 			pixman_region_fini(&region);
 		} else {
@@ -6954,7 +6960,10 @@ sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t)
 		if (!(image = image_from_pict(picture, false, &dx, &dy)))
 			return;
 
-		pixman_add_traps(image, x + dx, y + dy, n, (pixman_trap_t *)t);
+		if (sigtrap_get() == 0) {
+			pixman_add_traps(image, x + dx, y + dy, n, (pixman_trap_t *)t);
+			sigtrap_put();
+		}
 
 		free_pixman_pict(picture, image);
 	}
commit 7025956558cfc391b553c9adb39d2a38fe494946
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 16:20:06 2013 +0100

    sna: Mark all large cached buffers as purgeable
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index d68bda5..4a82d4a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2019,7 +2019,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	assert(bo->exec == NULL);
 	assert(list_is_empty(&bo->request));
 
-	if (bo->map__cpu == NULL) {
+	if (bo->map__cpu == NULL || bucket(bo) >= NUM_CACHE_BUCKETS) {
 		if (!kgem_bo_set_purgeable(kgem, bo))
 			goto destroy;
 
@@ -3897,7 +3897,6 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	if (tiling < 0)
 		exact = true, tiling = -tiling;
 
-
 	DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, prime?=%d, temp?=%d)\n", __FUNCTION__,
 	     width, height, bpp, tiling, exact,
 	     !!(flags & CREATE_INACTIVE),
commit 455754ca8d2762c6294e6db6b405da7959ab8a0f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 15:41:36 2013 +0100

    sna: Make sure the transformed CRTC box is clipped correctly.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c7806ce..032c776 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3827,6 +3827,25 @@ void sna_mode_reset(struct sna *sna)
 	}
 }
 
+static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
+{
+	box->x1 -= crtc->filter_width >> 1;
+	box->x2 += crtc->filter_width >> 1;
+	box->y1 -= crtc->filter_height >> 1;
+	box->y2 += crtc->filter_height >> 1;
+
+	pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box);
+
+	if (box->x1 < 0)
+		box->x1 = 0;
+	if (box->y1 < 0)
+		box->y1 = 0;
+	if (box->x2 > crtc->mode.HDisplay)
+		box->x2 = crtc->mode.HDisplay;
+	if (box->y2 > crtc->mode.VDisplay)
+		box->y2 = crtc->mode.VDisplay;
+}
+
 static void
 sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region)
 {
@@ -3894,11 +3913,7 @@ sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region)
 		BoxRec box;
 
 		box = *b++;
-		box.x1 -= crtc->filter_width >> 1;
-		box.x2 += crtc->filter_width >> 1;
-		box.y1 -= crtc->filter_height >> 1;
-		box.y2 += crtc->filter_height >> 1;
-		pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, & box);
+		transformed_box(&box, crtc);
 
 		DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
 		     __FUNCTION__,
@@ -3993,11 +4008,7 @@ sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region)
 		BoxRec box;
 
 		box = *b++;
-		box.x1 -= crtc->filter_width >> 1;
-		box.x2 += crtc->filter_width >> 1;
-		box.y1 -= crtc->filter_height >> 1;
-		box.y2 += crtc->filter_height >> 1;
-		pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, & box);
+		transformed_box(&box, crtc);
 
 		DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
 		     __FUNCTION__,
commit ec9ffc9e41e05bc6aef10e25ff82bb99b5f92267
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 14:54:18 2013 +0100

    sna: Trigger fallback after intermediate pixmap allocation failure
    
    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 655e6d9..d7a0828 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1230,6 +1230,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 	if (wedged(sna))
 		flags &= ~KGEM_CAN_CREATE_GTT;
 
+	DBG(("%s: usage=%d, flags=%x\n", __FUNCTION__, usage, flags));
 	switch (usage) {
 	case CREATE_PIXMAP_USAGE_SCRATCH:
 		if (flags & KGEM_CAN_CREATE_GPU)
@@ -3804,6 +3805,9 @@ active:
 
 static bool must_check sna_validate_pixmap(DrawablePtr draw, PixmapPtr pixmap)
 {
+	DBG(("%s: target bpp=%d, source bpp=%d\n",
+	     __FUNCTION__, draw->bitsPerPixel, pixmap->drawable.bitsPerPixel));
+
 	if (draw->bitsPerPixel == pixmap->drawable.bitsPerPixel &&
 	    FbEvenTile(pixmap->drawable.width *
 		       pixmap->drawable.bitsPerPixel)) {
@@ -3873,9 +3877,11 @@ static bool must_check sna_gc_move_to_cpu(GCPtr gc,
 
 	switch (gc->fillStyle) {
 	case FillTiled:
+		DBG(("%s: moving tile to cpu\n", __FUNCTION__));
 		return sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, MOVE_READ);
 	case FillStippled:
 	case FillOpaqueStippled:
+		DBG(("%s: moving stipple to cpu\n", __FUNCTION__));
 		return sna_drawable_move_to_cpu(&gc->stipple->drawable, MOVE_READ);
 	default:
 		return true;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 738cca4..84275c4 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -763,21 +763,27 @@ static int sna_render_picture_downsample(struct sna *sna,
 	DBG(("%s: creating temporary GPU bo %dx%d\n",
 	     __FUNCTION__, width, height));
 
-	if (!sna_pixmap_force_to_gpu(pixmap, MOVE_SOURCE_HINT | MOVE_READ))
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h,
-						dst_x, dst_y);
-
 	tmp = screen->CreatePixmap(screen,
 				   width, height,
 				   pixmap->drawable.depth,
 				   SNA_CREATE_SCRATCH);
-	if (!tmp)
-		return 0;
+	if (tmp == NULL)
+		goto fixup;
 
 	priv = sna_pixmap(tmp);
-	if (!priv)
-		goto cleanup_tmp;
+	if (priv == NULL) {
+		screen->DestroyPixmap(tmp);
+		goto fixup;
+	}
+
+	if (!sna_pixmap_force_to_gpu(pixmap, MOVE_SOURCE_HINT | MOVE_READ)) {
+fixup:
+		DBG(("%s: unable to create GPU bo for target or temporary pixmaps\n",
+		     __FUNCTION__));
+		return sna_render_picture_fixup(sna, picture, channel,
+						x, y, w, h,
+						dst_x, dst_y);
+	}
 
 	format = PictureMatchFormat(screen,
 				    pixmap->drawable.depth,
@@ -958,8 +964,11 @@ sna_render_pixmap_partial(struct sna *sna,
 	channel->bo = kgem_create_proxy(&sna->kgem, bo,
 					box.y1 * bo->pitch + offset,
 					h * bo->pitch);
-	if (channel->bo == NULL)
+	if (channel->bo == NULL) {
+		DBG(("%s: failed to create proxy for partial (offset=%d, size=%d)\n",
+		     __FUNCTION__, box.y1 * bo->pitch + offset, h * bo->pitch));
 		return false;
+	}
 
 	channel->bo->pitch = bo->pitch;
 
@@ -1029,8 +1038,10 @@ sna_render_picture_partial(struct sna *sna,
 		bo = priv->gpu_bo;
 	}
 
-	if (bo->pitch > sna->render.max_3d_pitch)
-		return 0;
+	if (bo->pitch > sna->render.max_3d_pitch) {
+		DBG(("%s: pitch too great %d > %d\n", __FUNCTION__, bo->pitch, sna->render.max_3d_pitch));
+		return -1;
+	}
 
 	if (bo->tiling) {
 		int tile_width, tile_height, tile_size;
@@ -1330,15 +1341,17 @@ sna_render_picture_convolve(struct sna *sna,
 	}
 
 	pixmap = screen->CreatePixmap(screen, w, h, depth, SNA_CREATE_SCRATCH);
-	if (pixmap == NullPixmap)
-		return 0;
+	if (pixmap == NullPixmap) {
+		DBG(("%s: pixmap allocation failed\n", __FUNCTION__));
+		return -1;
+	}
 
 	tmp = CreatePicture(0, &pixmap->drawable,
 			    PictureMatchFormat(screen, depth, channel->pict_format),
 			    0, NULL, serverClient, &error);
 	screen->DestroyPixmap(pixmap);
 	if (tmp == NULL)
-		return 0;
+		return -1;
 
 	ValidatePicture(tmp);
 
@@ -1413,15 +1426,17 @@ sna_render_picture_flatten(struct sna *sna,
 	DBG(("%s: %dx%d\n", __FUNCTION__, w, h));
 
 	pixmap = screen->CreatePixmap(screen, w, h, 32, SNA_CREATE_SCRATCH);
-	if (pixmap == NullPixmap)
-		return 0;
+	if (pixmap == NullPixmap) {
+		DBG(("%s: pixmap allocation failed\n", __FUNCTION__));
+		return -1;
+	}
 
 	tmp = CreatePicture(0, &pixmap->drawable,
 			    PictureMatchFormat(screen, 32, PICT_a8r8g8b8),
 			    0, NULL, serverClient, &error);
 	screen->DestroyPixmap(pixmap);
 	if (tmp == NULL)
-		return 0;
+		return -1;
 
 	ValidatePicture(tmp);
 
@@ -1789,7 +1804,7 @@ sna_render_picture_convert(struct sna *sna,
 
 		tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0);
 		if (tmp == NULL)
-			return 0;
+			return -1;
 
 		dst = CreatePicture(0, &tmp->drawable,
 				    PictureMatchFormat(screen,
commit bbfbe229542cc3278fea3c1865f28d65d3c154e8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 15:14:29 2013 +0100

    sna/gen4+: Handle very large copies more gracefully
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index b0feb9f..416452b 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2413,8 +2413,12 @@ fallback_blt:
 
 	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
 		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
-			goto fallback_tiled_src;
+		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
+			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+			if (tmp.redirect.real_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
+			goto fallback_blt;
+		}
 	}
 
 	dst_dx += tmp.dst.x;
@@ -2440,8 +2444,6 @@ fallback_blt:
 	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 	return true;
 
-fallback_tiled_src:
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 fallback_tiled_dst:
 	if (tmp.redirect.real_bo)
 		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index c625639..f6eec6a 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2370,7 +2370,10 @@ fallback_blt:
 		kgem_submit(&sna->kgem);
 		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
 			DBG(("%s: aperture check failed\n", __FUNCTION__));
-			goto fallback_tiled_src;
+			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+			if (tmp.redirect.real_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
+			goto fallback_blt;
 		}
 	}
 
@@ -2417,8 +2420,6 @@ fallback_blt:
 	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 	return true;
 
-fallback_tiled_src:
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 fallback_tiled_dst:
 	if (tmp.redirect.real_bo)
 		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index b014e9e..123bb15 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2907,7 +2907,11 @@ fallback_blt:
 		if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
 			DBG(("%s: too large for a single operation\n",
 			     __FUNCTION__));
-			goto fallback_tiled_src;
+			if (tmp.src.bo != src_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+			if (tmp.redirect.real_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
+			goto fallback_blt;
 		}
 		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	}
@@ -2950,9 +2954,6 @@ fallback_blt:
 		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 	return true;
 
-fallback_tiled_src:
-	if (tmp.src.bo != src_bo)
-		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 fallback_tiled_dst:
 	if (tmp.redirect.real_bo)
 		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 1b5e607..d0cdc79 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3004,6 +3004,7 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
 
 	if (!(alu == GXcopy || alu == GXclear)) {
 fallback_blt:
+		DBG(("%s: fallback blt\n", __FUNCTION__));
 		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
 			return false;
 
@@ -3126,8 +3127,13 @@ fallback_blt:
 	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo);
 	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
 		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL))
-			goto fallback_tiled_src;
+		if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
+			if (tmp.src.bo != src_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+			if (tmp.redirect.real_bo)
+				kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
+			goto fallback_blt;
+		}
 		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	}
 
@@ -3169,13 +3175,11 @@ fallback_blt:
 		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 	return true;
 
-fallback_tiled_src:
-	if (tmp.src.bo != src_bo)
-		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
 fallback_tiled_dst:
 	if (tmp.redirect.real_bo)
 		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
 fallback_tiled:
+	DBG(("%s: fallback tiled\n", __FUNCTION__));
 	if (sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy_boxes(sna, alu,
 			       src_bo, src_dx, src_dy,
commit 4d2840919fd00e4ae0bf1957f66009f55a01eb7b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 15:30:58 2013 +0100

    sna: In desperation, query the actual available aperture space
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 6946361..d68bda5 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1367,6 +1367,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 	/* Convert the aperture thresholds to pages */
 	kgem->aperture_low /= PAGE_SIZE;
 	kgem->aperture_high /= PAGE_SIZE;
+	kgem->aperture_total /= PAGE_SIZE;
 
 	kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
 	if ((int)kgem->fence_max < 0)
@@ -2923,6 +2924,14 @@ void _kgem_submit(struct kgem *kgem)
 					       (int)kgem->reloc[i].presumed_offset);
 				}
 
+				{
+					struct drm_i915_gem_get_aperture aperture;
+					if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) == 0)
+						ErrorF("Aperture size %lld, available %lld\n",
+						       (long long)aperture.aper_size,
+						       (long long)aperture.aper_available_size);
+				}
+
 				if (DEBUG_SYNC) {
 					int fd = open("/tmp/batchbuffer", O_WRONLY | O_CREAT | O_APPEND, 0666);
 					if (fd != -1) {
@@ -4567,6 +4576,31 @@ inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
 	return kgem->nreloc && bo->rq && RQ_RING(bo->rq) != kgem->ring;
 }
 
+static bool aperture_check(struct kgem *kgem, unsigned num_pages)
+{
+	if (kgem->aperture) {
+		struct drm_i915_gem_get_aperture aperture;
+
+		VG_CLEAR(aperture);
+		aperture.aper_available_size = kgem->aperture_high;
+		aperture.aper_available_size *= PAGE_SIZE;
+		(void)drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+
+		DBG(("%s: aperture required %ld bytes, available %ld bytes\n",
+		     __FUNCTION__,
+		     (long)num_pages * PAGE_SIZE,
+		     (long)aperture.aper_available_size));
+
+		/* Leave some space in case of alignment issues */
+		aperture.aper_available_size -= 4 * 1024 * 1024;
+
+		if (num_pages < aperture.aper_available_size / PAGE_SIZE)
+			return true;
+	}
+
+	return false;
+}
+
 bool kgem_check_bo(struct kgem *kgem, ...)
 {
 	va_list ap;
@@ -4615,7 +4649,7 @@ bool kgem_check_bo(struct kgem *kgem, ...)
 	if (num_pages + kgem->aperture > kgem->aperture_high) {
 		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
 		     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
-		return false;
+		return aperture_check(kgem, num_pages);
 	}
 
 	if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) {
@@ -4676,8 +4710,11 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 		return false;
 	}
 
-	if (kgem->aperture + num_pages(bo) > kgem->aperture_high)
-		return false;
+	if (kgem->aperture + num_pages(bo) > kgem->aperture_high) {
+		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
+		     __FUNCTION__, num_pages(bo) + kgem->aperture, kgem->aperture_high));
+		return aperture_check(kgem, num_pages(bo));
+	}
 
 	assert_tiling(kgem, bo);
 	if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) {
@@ -4767,8 +4804,11 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 			return false;
 		}
 
-		if (num_pages + kgem->aperture > kgem->aperture_high)
-			return false;
+		if (num_pages + kgem->aperture > kgem->aperture_high) {
+			DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
+			     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
+			return aperture_check(kgem, num_pages);
+		}
 
 		if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
 			return false;
commit bf1268838a30cca6a181c7804b0d2640dcf94981
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 14:48:31 2013 +0100

    sna: Drop the REPLACES hint for a pinned target bo
    
    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 9f0a4e4..655e6d9 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3192,6 +3192,8 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
 		flags |= PREFER_GPU;
 	if (priv->shm)
 		flags &= ~PREFER_GPU;
+	if (priv->pinned)
+		flags &= ~REPLACES;
 	if (priv->cpu && (flags & (FORCE_GPU | IGNORE_CPU)) == 0)
 		flags &= ~PREFER_GPU;
 
commit 50bd37cf7fb811001e79a27b35e5cd0544391cd9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 14:09:54 2013 +0100

    sna: Simplify the clearing of a transformed frontbuffer
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index f54f4de..c7806ce 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4021,6 +4021,7 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region)
 {
 	struct sna *sna = to_sna(crtc->scrn);
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct sna_pixmap *priv = sna_pixmap(sna->front);
 	int16_t tx, ty;
 
 	DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %ld\n",
@@ -4031,6 +4032,17 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region)
 
 	assert(!wedged(sna));
 
+	if (priv->clear) {
+		DBG(("%s: clear damage boxes\n", __FUNCTION__));
+
+		RegionTranslate(region, -crtc->bounds.x1, -crtc->bounds.y1);
+		sna_blt_fill_boxes(sna, GXcopy,
+				   sna_crtc->bo, sna->front->drawable.bitsPerPixel,
+				   priv->clear_color,
+				   REGION_RECTS(region), REGION_NUM_RECTS(region));
+		return;
+	}
+
 	if (crtc->filter == NULL &&
 	    sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
 						 &tx, &ty)) {
@@ -4048,7 +4060,7 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region)
 		 */
 
 		if (sna->render.copy_boxes(sna, GXcopy,
-					   sna->front, __sna_pixmap_get_bo(sna->front), 0, 0,
+					   sna->front, priv->gpu_bo, 0, 0,
 					   &tmp, sna_crtc->bo, -tx, -ty,
 					   REGION_RECTS(region), REGION_NUM_RECTS(region), 0))
 			return;
commit c9445af34a091f85d63f40982762fb58b267004d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 11:43:14 2013 +0100

    sna: Remove a bogus assert
    
    We keep active/inactive scanouts in the same cache, so drop the assert
    that they are all inactive - as it is handled a couple of lines later!
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7811615..6946361 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3021,7 +3021,6 @@ void kgem_clean_scanout_cache(struct kgem *kgem)
 		assert(bo->scanout);
 		assert(bo->delta);
 		assert(!bo->refcnt);
-		assert(bo->exec == NULL);
 		assert(bo->proxy == NULL);
 
 		if (bo->exec || __kgem_busy(kgem, bo->handle))
commit 17f47afcbc5bbbebd2dfb97f7423514104da750d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 26 11:42:05 2013 +0100

    sna: Eliminate a DBG compile warn for 32-bit builds
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/fb/fbclip.c b/src/sna/fb/fbclip.c
index 37011a7..d231dd2 100644
--- a/src/sna/fb/fbclip.c
+++ b/src/sna/fb/fbclip.c
@@ -85,7 +85,7 @@ fbClipBoxes(const RegionRec *region, const BoxRec *box, const BoxRec **end)
 	}
 
 	DBG(("%s: c0=(%d, %d),(%d, %d) x %ld\n",
-	     __FUNCTION__, c0->x1, c0->y1, c0->x2, c0->y2, c1 - c0));
+	     __FUNCTION__, c0->x1, c0->y1, c0->x2, c0->y2, (long)(c1 - c0)));
 
 	*end = c1;
 	return c0;


More information about the xorg-commit mailing list