diff options
-rw-r--r-- | src/atimach64exa.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/atimach64exa.c b/src/atimach64exa.c index c68495b5..90cc2af9 100644 --- a/src/atimach64exa.c +++ b/src/atimach64exa.c @@ -56,6 +56,8 @@ #include "config.h" #endif +#include <string.h> + #include "ati.h" #include "atichip.h" #include "atidri.h" @@ -385,6 +387,60 @@ Mach64Solid static void Mach64DoneSolid(PixmapPtr pPixmap) { } +/* + * Memcpy-based UTS. + */ +static Bool +Mach64UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + char *dst = pDst->devPrivate.ptr; + int dst_pitch = exaGetPixmapPitch(pDst); + + int bpp = pDst->drawable.bitsPerPixel; + int cpp = (bpp + 7) / 8; + int wBytes = w * cpp; + + exaWaitSync(pDst->drawable.pScreen); + + dst += (x * cpp) + (y * dst_pitch); + + while (h--) { + memcpy(dst, src, wBytes); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +/* + * Memcpy-based DFS. + */ +static Bool +Mach64DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + char *src = pSrc->devPrivate.ptr; + int src_pitch = exaGetPixmapPitch(pSrc); + + int bpp = pSrc->drawable.bitsPerPixel; + int cpp = (bpp + 7) / 8; + int wBytes = w * cpp; + + exaWaitSync(pSrc->drawable.pScreen); + + src += (x * cpp) + (y * src_pitch); + + while (h--) { + memcpy(dst, src, wBytes); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + /* Compute log base 2 of val. */ static __inline__ int Mach64Log2(int val) { @@ -611,6 +667,12 @@ Bool ATIMach64ExaInit(ScreenPtr pScreen) pExa->Copy = Mach64Copy; pExa->DoneCopy = Mach64DoneCopy; + /* EXA hits more optimized paths when it does not have to fallback because + * of missing UTS/DFS, hook memcpy-based UTS/DFS. + */ + pExa->UploadToScreen = Mach64UploadToScreen; + pExa->DownloadFromScreen = Mach64DownloadFromScreen; + if (!exaDriverInit(pScreen, pATI->pExa)) { xfree(pATI->pExa); pATI->pExa = NULL; |