xf86-video-intel: src/i830_batchbuffer.c src/i830.h src/i830_uxa.c uxa/uxa-accel.c uxa/uxa.c uxa/uxa-glyphs.c uxa/uxa.h uxa/uxa-priv.h uxa/uxa-render.c

Chris Wilson ickle at kemper.freedesktop.org
Mon May 31 10:08:32 PDT 2010


 src/i830.h             |    1 +
 src/i830_batchbuffer.c |    8 ++++++++
 src/i830_uxa.c         |    4 +++-
 uxa/uxa-accel.c        |   20 +++++++++++---------
 uxa/uxa-glyphs.c       |    1 +
 uxa/uxa-priv.h         |    1 +
 uxa/uxa-render.c       |    8 +++++---
 uxa/uxa.c              |    9 +++++++++
 uxa/uxa.h              |    1 +
 9 files changed, 40 insertions(+), 13 deletions(-)

New commits:
commit cd38b705be84901a38380dc2a1b90889b553d565
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 31 17:23:36 2010 +0100

    Disable acceleration if we detect a hardware error.
    
    This is wildly optimistic, but it should work in a surprising number of
    error situations and some output in those cases will be hopefully be
    better than none...
    
    If we submit a batchbuffer and the kernel reports the GPU is hung (which
    will be caused by an earlier execbuffer, and so the kernel should have
    had enough time to determine whether or not it could reset the GPU) then
    disable any further attempt to accelerate gfx and force fallbacks to map
    the buffers and use the CPU. We cannot normally map any more buffers if
    the GPU is hung, so only those already mapped prior to the hang can be
    written to, or those allocated in system memory. However, we can expect
    that the framebuffer is already mapped, and so have a reasonable
    expectation to continue to see the display update.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830.h b/src/i830.h
index d0628fe..e410ec1 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -384,6 +384,7 @@ typedef struct intel_screen_private {
 	char *deviceName;
 
 	Bool use_pageflipping;
+	Bool force_fallback;
 
 	/* Broken-out options. */
 	OptionInfoPtr Options;
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 54a85d6..2d47326 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -32,6 +32,7 @@
 
 #include <assert.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "xf86.h"
 #include "i830.h"
@@ -215,6 +216,13 @@ void intel_batch_submit(ScrnInfoPtr scrn)
 				   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;
+		}
 	}
 
 	while (!list_is_empty(&intel->batch_pixmaps)) {
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index eb21fb5..74cffc2 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -934,7 +934,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
-	if (depth == 1)
+	if (depth == 1 || intel->force_fallback)
 		return fbCreatePixmap(screen, w, h, depth, usage);
 
 	if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
@@ -1082,6 +1082,8 @@ Bool i830_uxa_init(ScreenPtr screen)
 
 	memset(intel->uxa_driver, 0, sizeof(*intel->uxa_driver));
 
+	intel->force_fallback = FALSE;
+
 	intel->bufferOffset = 0;
 	intel->uxa_driver->uxa_major = 1;
 	intel->uxa_driver->uxa_minor = 0;
diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c
index d4475c6..6ac3e88 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -70,7 +70,7 @@ uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n,
 	PicturePtr dst, src;
 	int error;
 
-	if (uxa_screen->swappedOut)
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback)
 		goto fallback;
 
 	if (pGC->fillStyle != FillSolid)
@@ -287,16 +287,18 @@ uxa_do_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 	if (format != ZPixmap || bpp < 8)
 		return FALSE;
 
-	/* Only accelerate copies: no rop or planemask. */
-	if (!UXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback)
 		return FALSE;
 
-	if (uxa_screen->swappedOut)
+	if (!uxa_screen->info->put_image)
 		return FALSE;
 
-	pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
+	/* Only accelerate copies: no rop or planemask. */
+	if (!UXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
+		return FALSE;
 
-	if (!pPix || !uxa_screen->info->put_image)
+	pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
+	if (!pPix)
 		return FALSE;
 
 	x += pDrawable->x;
@@ -694,7 +696,7 @@ uxa_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 {
 	uxa_screen_t *uxa_screen = uxa_get_screen(pDstDrawable->pScreen);
 
-	if (uxa_screen->swappedOut) {
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback) {
 		return uxa_check_copy_area(pSrcDrawable, pDstDrawable, pGC,
 					   srcx, srcy, width, height, dstx,
 					   dsty);
@@ -884,7 +886,7 @@ uxa_poly_fill_rect(DrawablePtr pDrawable,
 	if (!REGION_NUM_RECTS(pReg))
 		goto out;
 
-	if (uxa_screen->swappedOut)
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback)
 		goto fallback;
 
 	pPixmap = uxa_get_offscreen_pixmap (pDrawable, &xoff, &yoff);
@@ -1297,7 +1299,7 @@ uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
 	Box.x2 = Box.x1 + w;
 	Box.y2 = Box.y1 + h;
 
-	if (uxa_screen->swappedOut)
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback)
 		goto fallback;
 
 	pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index 10d9447..9e59658 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -1026,6 +1026,7 @@ uxa_glyphs(CARD8 op,
 
 	if (!uxa_screen->info->prepare_composite ||
 	    uxa_screen->swappedOut ||
+	    uxa_screen->force_fallback ||
 	    !uxa_drawable_is_offscreen(pDst->pDrawable) ||
 	    pDst->alphaMap || pSrc->alphaMap) {
 fallback:
diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h
index 36625de..9d99a73 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -141,6 +141,7 @@ typedef struct {
 #endif
 	EnableDisableFBAccessProcPtr SavedEnableDisableFBAccess;
 
+	Bool force_fallback;
 	Bool fallback_debug;
 	Bool swappedOut;
 	unsigned disableFbCount;
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index caa36ee..0e4fa91 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -167,6 +167,10 @@ uxa_print_composite_fallback(const char *func, CARD8 op,
 	if (! uxa_screen->fallback_debug)
 		return;
 
+	/* Limit the noise if fallbacks are expected. */
+	if (uxa_screen->force_fallback)
+		return;
+
 	uxa_composite_fallback_pict_desc(pSrc, srcdesc, 40);
 	uxa_composite_fallback_pict_desc(pMask, maskdesc, 40);
 	uxa_composite_fallback_pict_desc(pDst, dstdesc, 40);
@@ -1502,17 +1506,15 @@ uxa_composite(CARD8 op,
 	RegionRec region;
 	int tx, ty;
 
-	if (uxa_screen->swappedOut)
+	if (uxa_screen->swappedOut || uxa_screen->force_fallback)
 		goto fallback;
 
 	if (!uxa_drawable_is_offscreen(pDst->pDrawable))
 		goto fallback;
 
-
 	if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
 		goto fallback;
 
-
 	/* Remove repeat in source if useless */
 	if (pSrc->pDrawable && pSrc->repeat && pSrc->filter != PictFilterConvolution &&
 	    transform_is_integer_translation(pSrc->transform, &tx, &ty) &&
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 330b389..a9a705c 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -350,6 +350,13 @@ void uxa_set_fallback_debug(ScreenPtr screen, Bool enable)
 	uxa_screen->fallback_debug = enable;
 }
 
+void uxa_set_force_fallback(ScreenPtr screen, Bool value)
+{
+	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
+
+	uxa_screen->force_fallback = value;
+}
+
 /**
  * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's
  * screen private, before calling down to the next CloseSccreen.
@@ -473,6 +480,8 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver)
 
 	dixSetPrivate(&screen->devPrivates, &uxa_screen_index, uxa_screen);
 
+	uxa_screen->force_fallback = FALSE;
+
 	uxa_screen->solid_cache_size = 0;
 	uxa_screen->solid_clear = 0;
 	uxa_screen->solid_black = 0;
diff --git a/uxa/uxa.h b/uxa/uxa.h
index 23f9465..cb08665 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -570,6 +570,7 @@ uxa_get_color_for_pixmap (PixmapPtr	 pixmap,
 			  CARD32	*pixel);
 
 void uxa_set_fallback_debug(ScreenPtr screen, Bool enable);
+void uxa_set_force_fallback(ScreenPtr screen, Bool enable);
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the


More information about the xorg-commit mailing list