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> 2006-03-29 Eric Anholt <anholt@FreeBSD.org>
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrDownloadFromScreen), * hw/kdrive/ephyr/ephyr_draw.c: (ephyrDownloadFromScreen),

View File

@ -132,6 +132,103 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
exaMarkSync(pScreen); 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 static Bool inline
exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
@ -689,7 +786,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
const GCOps exaOps = { const GCOps exaOps = {
exaFillSpans, exaFillSpans,
ExaCheckSetSpans, ExaCheckSetSpans,
ExaCheckPutImage, exaPutImage,
exaCopyArea, exaCopyArea,
ExaCheckCopyPlane, ExaCheckCopyPlane,
ExaCheckPolyPoint, ExaCheckPolyPoint,
@ -992,7 +1089,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
yoff += pDrawable->y; yoff += pDrawable->y;
ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d, ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d,
PixmapBytePad(pDrawable, w)); PixmapBytePad(w, pDrawable->depth));
if (ok) { if (ok) {
exaWaitSync(pDrawable->pScreen); exaWaitSync(pDrawable->pScreen);
return; return;