Bug #2986: Add PutImage acceleration for the ZPixmap, planeMask ~=

FB_ALLONES, bitsPerPixel >= 8, GXcopy cases. With the radeon driver on
    my machine, this gives about 10% speedup in PutImage
10x10 and 500x500, and 40% speedup for 10x10 ShmPutImage, up to 65%
    improvement in 500x500 ShmPutImage. Also fixes a crasher in GetImage
    that slipped in at the last minute.
This commit is contained in:
Eric Anholt 2006-03-30 05:24:27 +00:00
parent 3cf46cc1e3
commit 2153fa9748
2 changed files with 109 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2006-03-29 Eric Anholt <anholt@FreeBSD.org>
* exa/exa_accel.c: (exaPutImage), (exaGetImage):
Bug #2986: Add PutImage acceleration for the ZPixmap,
planeMask ~= FB_ALLONES, bitsPerPixel >= 8, GXcopy cases. With the
radeon driver on my machine, this gives about 10% speedup in PutImage
10x10 and 500x500, and 40% speedup for 10x10 ShmPutImage, up to 65%
improvement in 500x500 ShmPutImage. Also fixes a crasher in GetImage
that slipped in at the last minute.
2006-03-29 Eric Anholt <anholt@FreeBSD.org>
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrDownloadFromScreen),

View File

@ -132,6 +132,103 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
exaMarkSync(pScreen);
}
static void
exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *bits)
{
ExaScreenPriv (pDrawable->pScreen);
PixmapPtr pPix;
ExaMigrationRec pixmaps[1];
RegionPtr pClip;
BoxPtr pbox;
int nbox;
int xoff, yoff;
int src_stride, bpp = pDrawable->bitsPerPixel;
if (pExaScr->swappedOut || pExaScr->info->UploadToScreen == NULL)
goto migrate_and_fallback;
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
goto migrate_and_fallback;
/* Only accelerate copies: no rop or planemask. */
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
goto migrate_and_fallback;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, TRUE);
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
goto fallback;
pClip = fbGetCompositeClip(pGC);
src_stride = PixmapBytePad(w, pDrawable->depth);
for (nbox = REGION_NUM_RECTS(pClip),
pbox = REGION_RECTS(pClip);
nbox--;
pbox++)
{
int x1 = x;
int y1 = y;
int x2 = x + w;
int y2 = y + h;
char *src;
Bool ok;
if (x1 < pbox->x1)
x1 = pbox->x1;
if (y1 < pbox->y1)
y1 = pbox->y1;
if (x2 > pbox->x2)
x2 = pbox->x2;
if (y2 > pbox->y2)
y2 = pbox->y2;
if (x1 >= x2 || y1 >= y2)
continue;
src = bits + (y1 - y + yoff) * src_stride + (x1 - x + xoff) * (bpp / 8);
ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
x2 - x1, y2 - y1, src, src_stride);
/* If we fail to accelerate the upload, fall back to using unaccelerated
* fb calls.
*/
if (!ok) {
FbStip *dst;
FbStride dst_stride;
int dstBpp;
int dstXoff, dstYoff;
fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
dstXoff, dstYoff);
fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
src_stride / sizeof(FbStip),
(x1 - x) * bpp,
dst + (y1 + yoff) * dst_stride,
dst_stride,
(x1 + xoff) * bpp,
(x2 - x1) * bpp,
y2 - y1,
GXcopy, FB_ALLONES, bpp);
}
}
return;
migrate_and_fallback:
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, FALSE);
fallback:
ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
}
static Bool inline
exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
@ -689,7 +786,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
const GCOps exaOps = {
exaFillSpans,
ExaCheckSetSpans,
ExaCheckPutImage,
exaPutImage,
exaCopyArea,
ExaCheckCopyPlane,
ExaCheckPolyPoint,
@ -992,7 +1089,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
yoff += pDrawable->y;
ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d,
PixmapBytePad(pDrawable, w));
PixmapBytePad(w, pDrawable->depth));
if (ok) {
exaWaitSync(pDrawable->pScreen);
return;