diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2007-09-26 07:47:29 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil> | 2007-09-26 07:47:29 -0400 |
commit | 27612748e0ec20f3a23839f0a12e39f598dd722c (patch) | |
tree | f7780ffd4d1284e76a17166f28211cfb88796de7 /exa | |
parent | b61461425eb15fcff2a58330d74fe5a5a1f226fc (diff) | |
parent | 3b114f2603fc2adeec7f5f8f20fe4870afb8dff1 (diff) |
Merge branch 'master' into XACE-SELINUX
Conflicts:
dix/devices.c
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa.c | 67 | ||||
-rw-r--r-- | exa/exa.h | 33 | ||||
-rw-r--r-- | exa/exa_accel.c | 45 | ||||
-rw-r--r-- | exa/exa_priv.h | 15 | ||||
-rw-r--r-- | exa/exa_render.c | 29 |
5 files changed, 146 insertions, 43 deletions
@@ -277,6 +277,26 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) REGION_NULL(pScreen, &pExaPixmap->validSys); REGION_NULL(pScreen, &pExaPixmap->validFB); + /* Check whether this pixmap can be used for acceleration. */ + pExaPixmap->accel_blocked = 0; + + if (pExaScr->info->maxPitchPixels) { + int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8; + + if (pExaPixmap->fb_pitch > max_pitch) + pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; + } + + if (pExaScr->info->maxPitchBytes && + pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes) + pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; + + if (w > pExaScr->info->maxX) + pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH; + + if (h > pExaScr->info->maxY) + pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT; + return pPixmap; } @@ -659,6 +679,17 @@ exaDriverInit (ScreenPtr pScreen, if (!pScreenInfo) return FALSE; + if (pScreenInfo->exa_major != EXA_VERSION_MAJOR || + pScreenInfo->exa_minor > EXA_VERSION_MINOR) + { + LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements " + "(%d.%d) are incompatible with EXA version (%d.%d)\n", + pScreen->myNum, + pScreenInfo->exa_major, pScreenInfo->exa_minor, + EXA_VERSION_MAJOR, EXA_VERSION_MINOR); + return FALSE; + } + if (!pScreenInfo->memoryBase) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be " "non-zero\n", pScreen->myNum); @@ -695,14 +726,36 @@ exaDriverInit (ScreenPtr pScreen, return FALSE; } - if (pScreenInfo->exa_major != EXA_VERSION_MAJOR || - pScreenInfo->exa_minor > EXA_VERSION_MINOR) + /* If the driver doesn't set any max pitch values, we'll just assume + * that there's a limitation by pixels, and that it's the same as + * maxX. + */ + if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes) { - LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements " - "(%d.%d) are incompatible with EXA version (%d.%d)\n", - pScreen->myNum, - pScreenInfo->exa_major, pScreenInfo->exa_minor, - EXA_VERSION_MAJOR, EXA_VERSION_MINOR); + pScreenInfo->maxPitchPixels = pScreenInfo->maxX; + } + + /* If set, maxPitchPixels must not be smaller than maxX. */ + if (pScreenInfo->maxPitchPixels && + pScreenInfo->maxPitchPixels < pScreenInfo->maxX) + { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchPixels " + "is smaller than ExaDriverRec::maxX\n", + pScreen->myNum); + return FALSE; + } + + /* If set, maxPitchBytes must not be smaller than maxX * 4. + * This is to ensure that a 32bpp pixmap with the maximum width + * can be handled wrt the pitch. + */ + if (pScreenInfo->maxPitchBytes && + pScreenInfo->maxPitchBytes < (pScreenInfo->maxX * 4)) + { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchBytes " + "doesn't allow a 32bpp pixmap with width equal to " + "ExaDriverRec::maxX\n", + pScreen->myNum); return FALSE; } @@ -39,7 +39,7 @@ #include "fb.h" #define EXA_VERSION_MAJOR 2 -#define EXA_VERSION_MINOR 2 +#define EXA_VERSION_MINOR 3 #define EXA_VERSION_RELEASE 0 typedef struct _ExaOffscreenArea ExaOffscreenArea; @@ -671,6 +671,37 @@ typedef struct _ExaDriver { */ #define EXA_PREPARE_MASK 2 /** @} */ + + /** + * maxPitchPixels controls the pitch limitation for rendering from + * the card. + * The driver should never receive a request for rendering a pixmap + * that has a pitch (in pixels) beyond maxPitchPixels. + * + * Setting this field is optional -- if your hardware doesn't have + * a pitch limitation in pixels, don't set this. If neither this value + * nor maxPitchBytes is set, then maxPitchPixels is set to maxX. + * If set, it must not be smaller than maxX. + * + * @sa maxPitchBytes + */ + int maxPitchPixels; + + /** + * maxPitchBytes controls the pitch limitation for rendering from + * the card. + * The driver should never receive a request for rendering a pixmap + * that has a pitch (in bytes) beyond maxPitchBytes. + * + * Setting this field is optional -- if your hardware doesn't have + * a pitch limitation in bytes, don't set this. + * If set, it must not be smaller than maxX * 4. + * There's no default value for maxPitchBytes. + * + * @sa maxPitchPixels + */ + int maxPitchBytes; + /** @} */ } ExaDriverRec, *ExaDriverPtr; diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 2acade263..028d93644 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -43,7 +43,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv (pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); - PixmapPtr pPixmap; + PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); + ExaPixmapPriv (pPixmap); BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; @@ -54,13 +55,12 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); + pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; if (pExaScr->swappedOut || pGC->fillStyle != FillSolid || - pPixmap->drawable.width > pExaScr->info->maxX || - pPixmap->drawable.height > pExaScr->info->maxY) + pExaPixmap->accel_blocked) { ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); return; @@ -480,6 +480,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, { ExaScreenPriv (pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; + ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; ExaMigrationRec pixmaps[2]; @@ -527,14 +528,14 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, pixmaps[1].pPix = pSrcPixmap; pixmaps[1].pReg = NULL; - /* Respect maxX/maxY in a trivial way: don't set up drawing when we might - * violate the limits. The proper solution would be a temporary pixmap - * adjusted so that the drawing happened within limits. + pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap); + pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); + + /* Check whether the accelerator can use this pixmap. + * FIXME: If it cannot, use temporary pixmaps so that the drawing + * happens within limits. */ - if (pSrcPixmap->drawable.width > pExaScr->info->maxX || - pSrcPixmap->drawable.height > pExaScr->info->maxY || - pDstPixmap->drawable.width > pExaScr->info->maxX || - pDstPixmap->drawable.height > pExaScr->info->maxY) + if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { goto fallback; } else { @@ -760,6 +761,7 @@ exaPolyFillRect(DrawablePtr pDrawable, ExaScreenPriv (pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); + ExaPixmapPriv (pPixmap); register BoxPtr pbox; BoxPtr pextent; int extentX1, extentX2, extentY1, extentY2; @@ -786,9 +788,7 @@ exaPolyFillRect(DrawablePtr pDrawable, exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - if (pExaScr->swappedOut || - pPixmap->drawable.width > pExaScr->info->maxX || - pPixmap->drawable.height > pExaScr->info->maxY) + if (pExaScr->swappedOut || pExaPixmap->accel_blocked) { goto fallback; } @@ -1102,21 +1102,21 @@ exaFillRegionSolid (DrawablePtr pDrawable, CARD32 alu) { ExaScreenPriv(pDrawable->pScreen); - PixmapPtr pPixmap; + PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); + ExaPixmapPriv (pPixmap); int xoff, yoff; ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); + pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, alu) ? NULL : pRegion; exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); - if (pPixmap->drawable.width > pExaScr->info->maxX || - pPixmap->drawable.height > pExaScr->info->maxY) + if (pExaPixmap->accel_blocked) { goto fallback; } else { @@ -1193,6 +1193,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPixmap; + ExaPixmapPrivPtr pExaPixmap; + ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile); int xoff, yoff, tileXoff, tileYoff; int tileWidth, tileHeight; ExaMigrationRec pixmaps[2]; @@ -1223,10 +1225,9 @@ exaFillRegionTiled (DrawablePtr pDrawable, exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); - if (pPixmap->drawable.width > pExaScr->info->maxX || - pPixmap->drawable.height > pExaScr->info->maxY || - tileWidth > pExaScr->info->maxX || - tileHeight > pExaScr->info->maxY) + pExaPixmap = ExaGetPixmapPriv (pPixmap); + + if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) { goto fallback; } else { diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 27749d7c4..b1023a67e 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -154,6 +154,10 @@ extern DevPrivateKey exaPixmapPrivateKey; #define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a) #define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) +#define EXA_RANGE_PITCH (1 << 0) +#define EXA_RANGE_WIDTH (1 << 1) +#define EXA_RANGE_HEIGHT (1 << 2) + typedef struct { ExaOffscreenArea *area; int score; /**< score for the move-in vs move-out heuristic */ @@ -167,6 +171,17 @@ typedef struct { unsigned int fb_size; /**< size of pixmap in framebuffer memory */ /** + * Holds information about whether this pixmap can be used for + * acceleration (== 0) or not (> 0). + * + * Contains a OR'ed combination of the following values: + * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range + * EXA_RANGE_WIDTH - set if the pixmap's width is out of range + * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range + */ + unsigned int accel_blocked; + + /** * The damage record contains the areas of the pixmap's current location * (framebuffer or system) that have been damaged compared to the other * location. diff --git a/exa/exa_render.c b/exa/exa_render.c index 943a4c8f6..2ad53041a 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -336,24 +336,28 @@ exaTryDriverComposite(CARD8 op, int nbox; int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; + ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix; struct _Pixmap scratch; ExaMigrationRec pixmaps[3]; pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); + pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + pDstPix = exaGetDrawablePixmap(pDst->pDrawable); - if (pMask) + pDstExaPix = ExaGetPixmapPriv(pDstPix); + + if (pMask) { pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); + pMaskExaPix = ExaGetPixmapPriv(pMaskPix); + } - /* Bail if we might exceed coord limits by rendering from/to these. We - * should really be making some scratch pixmaps with offsets and coords - * adjusted to deal with this, but it hasn't been done yet. + /* Check whether the accelerator can use these pixmaps. + * FIXME: If it cannot, use temporary pixmaps so that the drawing + * happens within limits. */ - if (pSrcPix->drawable.width > pExaScr->info->maxX || - pSrcPix->drawable.height > pExaScr->info->maxY || - pDstPix->drawable.width > pExaScr->info->maxX || - pDstPix->drawable.height > pExaScr->info->maxY || - (pMask && (pMaskPix->drawable.width > pExaScr->info->maxX || - pMaskPix->drawable.height > pExaScr->info->maxY))) + if (pSrcExaPix->accel_blocked || + pDstExaPix->accel_blocked || + (pMask && (pMaskExaPix->accel_blocked))) { return -1; } @@ -380,7 +384,6 @@ exaTryDriverComposite(CARD8 op, width, height)) return 1; - pDstPix = exaGetDrawablePixmap (pDst->pDrawable); exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); @@ -391,12 +394,12 @@ exaTryDriverComposite(CARD8 op, pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable); + pixmaps[1].pPix = pSrcPix; pixmaps[1].pReg = NULL; if (pMask) { pixmaps[2].as_dst = FALSE; pixmaps[2].as_src = TRUE; - pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable); + pixmaps[2].pPix = pMaskPix; pixmaps[2].pReg = NULL; exaDoMigration(pixmaps, 3, TRUE); } else { |