summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830.h2
-rw-r--r--src/i830_batchbuffer.c8
-rw-r--r--src/i830_uxa.c4
-rw-r--r--uxa/uxa-accel.c20
-rw-r--r--uxa/uxa-glyphs.c1
-rw-r--r--uxa/uxa-priv.h1
-rw-r--r--uxa/uxa-render.c8
-rw-r--r--uxa/uxa.c9
-rw-r--r--uxa/uxa.h1
9 files changed, 41 insertions, 13 deletions
diff --git a/src/i830.h b/src/i830.h
index ed5d5fde..4d441b24 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -636,6 +636,8 @@ typedef struct intel_screen_private {
#endif
char *deviceName;
+ Bool force_fallback;
+
/* Broken-out options. */
OptionInfoPtr Options;
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 2ef89f24..540fe1d7 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"
@@ -202,6 +203,13 @@ void intel_batch_submit(ScrnInfoPtr scrn, int flush)
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 5d7399b3..79e84952 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -939,7 +939,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)
@@ -1099,6 +1099,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 ce2013e1..2b4c16c7 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -71,7 +71,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)
@@ -288,16 +288,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;
@@ -652,7 +654,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);
@@ -842,7 +844,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);
@@ -1255,7 +1257,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 823cf82f..68d1c228 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -1040,6 +1040,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 9b76d12b..92536cc0 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -132,6 +132,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 4e301516..6189fe24 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);
@@ -1508,17 +1512,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 8b6b5f27..4a5907e8 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -354,6 +354,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.
@@ -488,6 +495,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 efadfdaa..e001c53d 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -571,6 +571,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