xf86-video-intel: 3 commits - src/i830_batchbuffer.c uxa/uxa-render.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 10 15:03:29 PDT 2010


 src/i830_batchbuffer.c |   22 +++++------
 uxa/uxa-render.c       |   90 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 11 deletions(-)

New commits:
commit 5a0a8a1cf6d9b0616d6a097e783f2aa318b45736
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 10 22:56:34 2010 +0100

    i830: Limit disabling acceleration following EIO to !i965
    
    Following a conversation with Owain G. Ainsworth, it was decided that
    the second best approach to handling a wedged GPU was to hope that the
    kernel could successfully reset it, which currently is only possible for
    i965 and later chipsets.
    
    The best approach is of course to prevent such hangs from ever occurring
    in the first place.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 8b6b7a6..ada5809 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -214,7 +214,7 @@ void intel_batch_submit(ScrnInfoPtr scrn)
 		ret = dri_bo_exec(intel->batch_bo, intel->batch_used*4,
 				  NULL, 0, 0xffffffff);
 	if (ret != 0) {
-		if (ret == -EIO) {
+		if (ret == -EIO && !IS_I965G(intel)) {
 			static int once;
 
 			/* The GPU has hung and unlikely to recover by this point. */
commit 3bf4ca2cdc2493e209bbb9c597bfa17ed7fcf5dc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 9 12:02:21 2010 +0100

    i830: Only emit the disabling GPU error message once.
    
    But emit the warning about rendering corruption every time for the
    transient errors like out-of-memory.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 26fade3..8b6b7a6 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -214,21 +214,21 @@ void intel_batch_submit(ScrnInfoPtr scrn)
 		ret = dri_bo_exec(intel->batch_bo, intel->batch_used*4,
 				  NULL, 0, 0xffffffff);
 	if (ret != 0) {
-		static int once;
-
-		if (!once) {
+		if (ret == -EIO) {
+			static int once;
+
+			/* The GPU has hung and unlikely to recover by this point. */
+			if (!once) {
+				xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Detected a hung GPU, disabling acceleration.\n");
+				uxa_set_force_fallback(screenInfo.screens[scrn->scrnIndex], TRUE);
+				intel->force_fallback = TRUE;
+				once = 1;
+			}
+		} else {
 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 				   "Failed to submit batch buffer, expect rendering corruption "
 				   "or even a frozen display: %s.\n",
 				   strerror(-ret));
-			once = 1;
-		}
-
-		if (ret == -EIO) {
-			/* The GPU is hung and unlikely to recover by this point. */
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Disabling acceleration.\n");
-			uxa_set_force_fallback(screenInfo.screens[scrn->scrnIndex], TRUE);
-			intel->force_fallback = TRUE;
 		}
 	}
 
commit 35a12f029005d8f432755fb78f10c9d48ea2f347
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 9 11:47:37 2010 +0100

    Fallback implementation for trapezoids for hung GPUs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index abfef8e..33fe9af 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -1740,6 +1740,90 @@ uxa_create_alpha_picture(ScreenPtr pScreen,
 	return pPicture;
 }
 
+static void
+uxa_check_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
+	       PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+	       int ntrap, xTrapezoid * traps)
+{
+	ScreenPtr screen = dst->pDrawable->pScreen;
+
+	if (maskFormat) {
+		PixmapPtr scratch = NULL;
+		PicturePtr mask;
+		INT16 xDst, yDst;
+		INT16 xRel, yRel;
+		BoxRec bounds;
+		int width, height;
+		pixman_image_t *image;
+		pixman_format_code_t format;
+		int error;
+
+		xDst = traps[0].left.p1.x >> 16;
+		yDst = traps[0].left.p1.y >> 16;
+
+		miTrapezoidBounds (ntrap, traps, &bounds);
+		if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+			return;
+
+		width  = bounds.x2 - bounds.x1;
+		height = bounds.y2 - bounds.y1;
+
+		format = maskFormat->format |
+			(BitsPerPixel(maskFormat->depth) << 24);
+		image =
+		    pixman_image_create_bits(format, width, height, NULL, 0);
+		if (!image)
+			return;
+
+		for (; ntrap; ntrap--, traps++)
+			pixman_rasterize_trapezoid(image,
+						   (pixman_trapezoid_t *) traps,
+						   -bounds.x1, -bounds.y1);
+
+
+		scratch = GetScratchPixmapHeader(screen, width, height,
+						 PIXMAN_FORMAT_DEPTH(format),
+						 PIXMAN_FORMAT_BPP(format),
+						 pixman_image_get_stride(image),
+						 pixman_image_get_data(image));
+		if (!scratch) {
+			pixman_image_unref(image);
+			return;
+		}
+
+		mask = CreatePicture(0, &scratch->drawable,
+				     PictureMatchFormat(screen,
+							PIXMAN_FORMAT_DEPTH(format),
+							format),
+				     0, 0, serverClient, &error);
+		if (!mask) {
+			FreeScratchPixmapHeader(scratch);
+			pixman_image_unref(image);
+			return;
+		}
+
+		xRel = bounds.x1 + xSrc - xDst;
+		yRel = bounds.y1 + ySrc - yDst;
+		CompositePicture(op, src, mask, dst,
+				 xRel, yRel,
+				 0, 0,
+				 bounds.x1, bounds.y1,
+				 width, height);
+		FreePicture(mask, 0);
+
+		FreeScratchPixmapHeader(scratch);
+		pixman_image_unref(image);
+	} else {
+		if (dst->polyEdge == PolyEdgeSharp)
+			maskFormat = PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			maskFormat = PictureMatchFormat(screen, 8, PICT_a8);
+
+		for (; ntrap; ntrap--, traps++)
+			uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, 1, traps);
+	}
+}
+
 /**
  * uxa_trapezoids is essentially a copy of miTrapezoids that uses
  * uxa_create_alpha_picture instead of miCreateAlphaPicture.
@@ -1759,9 +1843,15 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
 	       int ntrap, xTrapezoid * traps)
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
+	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
 	BoxRec bounds;
 	Bool direct;
 
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback) {
+		uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps);
+		return;
+	}
+
 	direct = op == PictOpAdd && miIsSolidAlpha(src);
 	if (maskFormat || direct) {
 		miTrapezoidBounds(ntrap, traps, &bounds);


More information about the xorg-commit mailing list