summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atimach64exa.c62
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;