Without hardware acceleration my PowerBook G4 12'' with a NVIDIA
GeForce FX Go 5200 is unusable.  Since XAA is no longer supported,
here's a simple EXA backend for nv(4) based on the XAA sources and
Nouveau.  It only implements Solid and Copy but that already makes
a huge difference.

To test it you need to regenerate configure scripts for xf86-video-nv
as described in /usr/xenocara/README.

I can provide a diff for upstream it the driver is still maintained.

I'd like to hear from people using NVidia cards.

Index: nv_driver.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_driver.c,v
retrieving revision 1.17
diff -u -p -r1.17 nv_driver.c
--- nv_driver.c 30 May 2014 06:42:00 -0000      1.17
+++ nv_driver.c 10 Dec 2015 18:31:09 -0000
@@ -637,6 +637,7 @@ typedef enum {
     OPTION_SW_CURSOR,
     OPTION_HW_CURSOR,
     OPTION_NOACCEL,
+    OPTION_ACCEL_METHOD,
     OPTION_SHADOW_FB,
     OPTION_FBDEV,
     OPTION_ROTATE,
@@ -654,6 +655,7 @@ static const OptionInfoRec NVOptions[] =
     { OPTION_SW_CURSOR,         "SWcursor",     OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_HW_CURSOR,         "HWcursor",     OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_NOACCEL,           "NoAccel",      OPTV_BOOLEAN,   {0}, FALSE },
+    { OPTION_ACCEL_METHOD,      "AccelMethod",  OPTV_STRING,    {0}, FALSE },
     { OPTION_SHADOW_FB,         "ShadowFB",     OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_FBDEV,             "UseFBDev",     OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_ROTATE,           "Rotate",       OPTV_ANYSTR,    {0}, FALSE },
@@ -1346,7 +1348,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
     int i, max_width, max_height;
     ClockRangePtr clockRanges;
     const char *s;
-    Bool config_mon_rates;
+    Bool rc, config_mon_rates;
 
     if (flags & PROBE_DETECT) {
         EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
@@ -1599,6 +1601,20 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
                "Using framebuffer device\n");
     }
+    if (!pNv->NoAccel) {
+        from = X_DEFAULT;
+        pNv->useEXA = TRUE;
+        if((s = (char *)xf86GetOptValString(pNv->Options, 
OPTION_ACCEL_METHOD))) {
+            if(!xf86NameCmp(s,"XAA")) {
+                from = X_CONFIG;
+                pNv->useEXA = FALSE;
+            } else if(!xf86NameCmp(s,"EXA")) {
+                from = X_CONFIG;
+                pNv->useEXA = TRUE;
+            }
+        }
+       xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration method\n", 
pNv->useEXA ? "EXA" : "XAA");
+    }
     if (pNv->FBDev) {
        /* check for linux framebuffer device */
        if (!xf86LoadSubModule(pScrn, "fbdevhw")) {
@@ -2051,12 +2067,12 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        return FALSE;
     }
 
-    /* Load XAA if needed */
+    /* Load XAA/EXA if needed */
     if (!pNv->NoAccel) {
-       if (!xf86LoadSubModule(pScrn, "xaa")) {
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadwwfb\n");
-           pNv->NoAccel = 1;
-           pNv->ShadowFB = 1;
+       if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) {
+           xf86FreeInt10(pNv->pInt);
+           NVFreeRec(pScrn);
+           return FALSE;
        }
     }
 
@@ -2584,15 +2600,26 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
     if(offscreenHeight > 32767)
         offscreenHeight = 32767;
 
+    if (!pNv->useEXA) {
     AvailFBArea.x1 = 0;
     AvailFBArea.y1 = 0;
     AvailFBArea.x2 = pScrn->displayWidth;
     AvailFBArea.y2 = offscreenHeight;
     xf86InitFBManager(pScreen, &AvailFBArea);
-    
-    if (!pNv->NoAccel)
-       NVAccelInit(pScreen);
-    
+    }
+
+    if (!pNv->NoAccel) {
+        if (pNv->useEXA) {
+            if(!NVExaInit(pScreen, pScrn)) {
+                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                           "EXA hardware acceleration initialization 
failed\n");
+                return FALSE;
+            }
+       } else /* XAA */
+           NVAccelInit(pScreen);
+    }
+    NVResetGraphics(pScrn);
+
     xf86SetBackingStore(pScreen);
     xf86SetSilkenMouse(pScreen);
 
Index: nv_exa.c
===================================================================
RCS file: nv_exa.c
diff -N nv_exa.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ nv_exa.c    10 Dec 2015 18:31:09 -0000
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2003 NVIDIA, Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "nv_include.h"
+#include "exa.h"
+#include "nv_dma.h"
+
+Bool
+NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
+{
+       switch (pPix->drawable.bitsPerPixel) {
+       case 32:
+               *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
+               break;
+       case 24:
+               *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
+               break;
+       case 16:
+               *fmt_ret = SURFACE_FORMAT_R5G6B5;
+               break;
+       case 8:
+               *fmt_ret = SURFACE_FORMAT_Y8;
+               break;
+       default:
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+Bool
+NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
+{
+       switch (pPict->format) {
+       case PICT_a8r8g8b8:
+               *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
+               break;
+       case PICT_x8r8g8b8:
+               *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
+               break;
+       case PICT_r5g6b5:
+               *fmt_ret = SURFACE_FORMAT_R5G6B5;
+               break;
+       case PICT_a8:
+               *fmt_ret = SURFACE_FORMAT_Y8;
+               break;
+       default:
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+Bool
+NVAccelSetCtxSurf2D(NVPtr pNv, PixmapPtr psPix, PixmapPtr pdPix, int format)
+{
+       NVDmaStart(pNv, SURFACE_FORMAT, 4);
+       NVDmaNext(pNv, format);
+       NVDmaNext(pNv, ((uint32_t)exaGetPixmapPitch(pdPix) << 16) |
+                        (uint32_t)exaGetPixmapPitch(psPix));
+       NVDmaNext(pNv, exaGetPixmapOffset(psPix));
+       NVDmaNext(pNv, exaGetPixmapOffset(pdPix));
+
+       return TRUE;
+}
+
+static CARD32
+rectFormat(DrawablePtr pDrawable)
+{
+       switch (pDrawable->bitsPerPixel) {
+       case 32:
+       case 24:
+               return RECT_FORMAT_DEPTH24;
+               break;
+       case 16:
+               return RECT_FORMAT_DEPTH16;
+               break;
+       default:
+               return RECT_FORMAT_DEPTH8;
+               break;
+       }
+}
+
+static void
+NVExaWaitMarker(ScreenPtr pScreen, int marker)
+{
+       NVSync(xf86ScreenToScrn(pScreen));
+}
+
+static Bool
+NVExaPrepareSolid(PixmapPtr pPix, int alu, Pixel planemask, Pixel fg)
+{
+       ScrnInfoPtr     pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
+       NVPtr           pNv = NVPTR(pScrn);
+       int             fmt;
+
+       /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
+        * alpha channel gets forced to 0xFF for some reason.  We're using
+        * SURFACE_FORMAT_Y32 as a workaround
+        */
+       if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPix, &fmt))
+               return FALSE;
+       if (fmt == SURFACE_FORMAT_A8R8G8B8)
+               fmt = 0xb;
+
+       planemask |= ~0 << pPix->drawable.bitsPerPixel;
+       if (planemask != ~0 || alu != GXcopy) {
+               if (pPix->drawable.bitsPerPixel == 32)
+                       return FALSE;
+               NVSetRopSolid(pScrn, alu, planemask);
+               NVDmaStart(pNv, 0xC2FC, 1);
+               NVDmaNext(pNv, 1 /* ROP_AND */);
+       } else {
+               NVDmaStart(pNv, 0xC2FC, 1);
+               NVDmaNext(pNv, 3 /* SRCCOPY */);
+       }
+
+       if (!NVAccelSetCtxSurf2D(pNv, pPix, pPix, fmt))
+               return FALSE;
+
+       NVDmaStart(pNv, RECT_FORMAT, 1);
+       NVDmaNext(pNv, rectFormat(&pPix->drawable));
+       NVDmaStart(pNv, RECT_SOLID_COLOR, 1);
+       NVDmaNext(pNv, fg);
+
+       pNv->DMAKickoffCallback = NVDMAKickoffCallback;
+
+       return TRUE;
+}
+
+static void
+NVExaSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
+{
+       ScrnInfoPtr     pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
+       NVPtr           pNv = NVPTR(pScrn);
+       int             width = x2 - x1;
+       int             height = y2 - y1;
+
+       NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2);
+       NVDmaNext(pNv, (x1 << 16) | y1);
+       NVDmaNext(pNv, (width << 16) | height);
+
+       if ((width * height) >= 512)
+               NVDmaKickoff(pNv);
+}
+
+static void
+NVExaDoneSolid(PixmapPtr pPix)
+{
+}
+
+static Bool
+NVExaPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy, int alu,
+    Pixel planemask)
+{
+       ScrnInfoPtr     pScrn = xf86ScreenToScrn(psPix->drawable.pScreen);
+       NVPtr           pNv = NVPTR(pScrn);
+       int             fmt;
+
+       if (psPix->drawable.bitsPerPixel !=
+                       pdPix->drawable.bitsPerPixel)
+               return FALSE;
+
+       if (!NVAccelGetCtxSurf2DFormatFromPixmap(pdPix, &fmt))
+               return FALSE;
+
+       planemask |= ~0 << pdPix->drawable.bitsPerPixel;
+       if (planemask != ~0 || alu != GXcopy) {
+               if (pdPix->drawable.bitsPerPixel == 32)
+                       return FALSE;
+               NVSetRopSolid(pScrn, alu, planemask);
+               NVDmaStart(pNv, 0xA2FC, 1);
+               NVDmaNext(pNv, 1 /* ROP_AND */);
+       } else {
+               NVDmaStart(pNv, 0xA2FC, 1);
+               NVDmaNext(pNv, 3 /* SRCCOPY */);
+       }
+
+       if (!NVAccelSetCtxSurf2D(pNv, psPix, pdPix, fmt))
+               return FALSE;
+
+       pNv->DMAKickoffCallback = NVDMAKickoffCallback;
+       return TRUE;
+}
+
+static void
+NVExaCopy(PixmapPtr pdPix, int srcX, int srcY, int dstX,  int dstY, int width,
+    int height)
+{
+       ScrnInfoPtr     pScrn = xf86ScreenToScrn(pdPix->drawable.pScreen);
+       NVPtr           pNv = NVPTR(pScrn);
+
+       NVDmaStart(pNv, BLIT_POINT_SRC, 3);
+       NVDmaNext(pNv, (srcY << 16) | srcX);
+       NVDmaNext(pNv, (dstY << 16) | dstX);
+       NVDmaNext(pNv, (height  << 16) | width);
+
+       if ((width * height) >= 512)
+               NVDmaKickoff(pNv);
+}
+
+static void
+NVExaDoneCopy(PixmapPtr pdPix)
+{
+}
+
+Bool
+NVExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
+{
+       NVPtr           pNv = NVPTR(pScrn);
+
+       if (!(pNv->EXADriverPtr = exaDriverAlloc())) {
+               pNv->NoAccel = TRUE;
+               return FALSE;
+       }
+
+       pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
+       pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
+
+       pNv->EXADriverPtr->memoryBase = pNv->FbStart;
+       pNv->EXADriverPtr->memorySize = pNv->ScratchBufferStart;
+
+       pNv->EXADriverPtr->offScreenBase = 0;
+
+       pNv->EXADriverPtr->pixmapOffsetAlign = 256;
+       pNv->EXADriverPtr->pixmapPitchAlign = 64;
+
+       pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
+
+       pNv->EXADriverPtr->maxX = 32768;
+       pNv->EXADriverPtr->maxY = 32768;
+
+       pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
+
+       pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
+       pNv->EXADriverPtr->Copy = NVExaCopy;
+       pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
+
+       pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
+       pNv->EXADriverPtr->Solid = NVExaSolid;
+       pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
+
+       return exaDriverInit(pScreen, pNv->EXADriverPtr);
+}
Index: nv_video.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_video.c,v
retrieving revision 1.4
diff -u -p -r1.4 nv_video.c
--- nv_video.c  16 Aug 2012 16:35:27 -0000      1.4
+++ nv_video.c  10 Dec 2015 18:31:09 -0000
@@ -534,10 +534,44 @@ NVPutOverlayImage (
 }
 
 
+#ifndef ExaOffscreenMarkUsed
+extern void ExaOffscreenMarkUsed(PixmapPtr);
+#endif
+#ifndef exaGetDrawablePixmap
+extern PixmapPtr exaGetDrawablePixmap(DrawablePtr);
+#endif
+#ifndef exaPixmapIsOffscreen
+extern Bool exaPixmapIsOffscreen(PixmapPtr p);
+#endif
+/* To support EXA 2.0, 2.1 has this in the header */
+#ifndef exaMoveInPixmap
+extern void exaMoveInPixmap(PixmapPtr pPixmap);
+#endif
 
+/**
+ * NVPutBlitImage
+ * 
+ * @param pScrn screen
+ * @param src_offset
+ * @param id colorspace of image
+ * @param src_pitch
+ * @param dstBox
+ * @param x1
+ * @param y1
+ * @param x2
+ * @param y2
+ * @param width
+ * @param height
+ * @param src_w
+ * @param src_h
+ * @param drw_w
+ * @param drw_h
+ * @param clipBoxes
+ * @param pDraw
+ */
 static void
 NVPutBlitImage (
-    ScrnInfoPtr pScrnInfo,
+    ScrnInfoPtr pScrn,
     int         offset,
     int         id,
     int         dstPitch,
@@ -552,15 +586,59 @@ NVPutBlitImage (
     short       src_h,
     short       drw_w,
     short       drw_h,
-    RegionPtr   clipBoxes
+    RegionPtr   clipBoxes,
+    DrawablePtr pDraw
 )
 {
-    NVPtr          pNv     = NVPTR(pScrnInfo);
+    NVPtr          pNv     = NVPTR(pScrn);
     NVPortPrivPtr  pPriv   = GET_BLIT_PRIVATE(pNv);
-    BoxPtr         pbox    = REGION_RECTS(clipBoxes);
-    int            nbox    = REGION_NUM_RECTS(clipBoxes);
+    BoxPtr         pbox;
+    int            nbox;
     CARD32         dsdx, dtdy, size, point, srcpoint, format;
 
+    if (pNv->useEXA) {
+        ScreenPtr pScreen = pScrn->pScreen;
+        PixmapPtr pPix    = exaGetDrawablePixmap(pDraw);
+        int dst_format;
+
+        /* Try to get the dest drawable into vram */
+        if (!exaPixmapIsOffscreen(pPix)) {
+            exaMoveInPixmap(pPix);
+            ExaOffscreenMarkUsed(pPix);
+        }
+
+        /* If we failed, draw directly onto the screen pixmap.
+         * Not sure if this is the best approach, maybe failing
+         * with BadAlloc would be better?
+         */
+        if (!exaPixmapIsOffscreen(pPix)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                "XV: couldn't move dst surface into vram\n");
+            pPix = pScreen->GetScreenPixmap(pScreen);
+        }
+
+        NVAccelGetCtxSurf2DFormatFromPixmap(pPix, &dst_format);
+        NVAccelSetCtxSurf2D(pNv, pPix, pPix, dst_format);
+
+#ifdef COMPOSITE
+        /* Adjust coordinates if drawing to an offscreen pixmap */
+        if (pPix->screen_x || pPix->screen_y) {
+            REGION_TRANSLATE(pScrn->pScreen, clipBoxes,
+                                 -pPix->screen_x,
+                                 -pPix->screen_y);
+            dstBox->x1 -= pPix->screen_x;
+            dstBox->x2 -= pPix->screen_x;
+            dstBox->y1 -= pPix->screen_y;
+            dstBox->y2 -= pPix->screen_y;
+        }
+
+        DamageDamageRegion((DrawablePtr)pPix, clipBoxes);
+#endif
+    }
+
+    pbox = REGION_RECTS(clipBoxes);
+    nbox = REGION_NUM_RECTS(clipBoxes);
+
     dsdx = (src_w << 20) / drw_w;
     dtdy = (src_h << 20) / drw_h;
 
@@ -623,12 +701,17 @@ NVPutBlitImage (
        pbox++;
     }
 
-    if(pNv->CurrentLayout.depth == 15) {
-        NVDmaStart(pNv, SURFACE_FORMAT, 1);
-        NVDmaNext (pNv, SURFACE_FORMAT_DEPTH16);
+    if (!pNv->useEXA) {
+        if(pNv->CurrentLayout.depth == 15) {
+            NVDmaStart(pNv, SURFACE_FORMAT, 1);
+            NVDmaNext (pNv, SURFACE_FORMAT_DEPTH16);
+        }
     }
 
     NVDmaKickoff(pNv);
+    if (pNv->useEXA)
+        exaMarkSync(pScrn->pScreen);
+    else
 #ifdef HAVE_XAA_H
     SET_SYNC_FLAG(pNv->AccelInfoRec);
 #endif
@@ -1185,7 +1268,7 @@ static int NVPutImage
             NVPutBlitImage(pScrnInfo, offset, id, dstPitch, &dstBox,
                            xa, ya, xb, yb,
                            width, height, src_w, src_h, drw_w, drw_h,
-                           clipBoxes);
+                           clipBoxes, pDraw);
        } else {
             NVPutOverlayImage(pScrnInfo, offset, id, dstPitch, &dstBox, 
                              xa, ya, xb, yb,
Index: nv_xaa.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_xaa.c,v
retrieving revision 1.3
diff -u -p -r1.3 nv_xaa.c
--- nv_xaa.c    16 Aug 2012 16:35:27 -0000      1.3
+++ nv_xaa.c    10 Dec 2015 18:31:09 -0000
@@ -176,7 +176,7 @@ NVSetPattern(
     NVDmaNext (pNv, pat1);
 }
 
-static void 
+void
 NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask)
 {
     NVPtr pNv = NVPTR(pScrn);
@@ -270,13 +270,15 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
     NVDmaStart(pNv, RECT_FORMAT, 1);
     NVDmaNext (pNv, rectFormat);
 
-    NVDmaStart(pNv, LINE_FORMAT, 1);
-    NVDmaNext (pNv, lineFormat);
+    if (!pNv->useEXA) {
+        NVDmaStart(pNv, LINE_FORMAT, 1);
+        NVDmaNext (pNv, lineFormat);
+    }
 
     pNv->currentRop = ~0;  /* set to something invalid */
     NVSetRopSolid(pScrn, GXcopy, ~0);
 
-    NVDmaKickoff(pNv);
+    /*NVDmaKickoff(pNv);*/
 }
 
 void NVSync(ScrnInfoPtr pScrn)
@@ -291,7 +293,7 @@ void NVSync(ScrnInfoPtr pScrn)
     while(pNv->PGRAPH[0x0700/4]);
 }
 
-static void
+void
 NVDMAKickoffCallback (ScrnInfoPtr pScrn)
 {
    NVPtr pNv = NVPTR(pScrn);
Index: nv_dma.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_dma.h,v
retrieving revision 1.2
diff -u -p -r1.2 nv_dma.h
--- nv_dma.h    29 Jul 2008 20:04:57 -0000      1.2
+++ nv_dma.h    10 Dec 2015 18:31:09 -0000
@@ -21,17 +21,40 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#ifndef NV_DMA_H
+#define NV_DMA_H
+
+#define NVDmaNext(pNv, data) do {                                      \
+     (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data);                     \
+} while(0)
+
+#define NVDmaStart(pNv, tag, size) do {                                        
\
+        if((pNv)->dmaFree <= (size))                                    \
+            NVDmaWait(pNv, size);                                       \
+        NVDmaNext(pNv, ((size) << 18) | (tag));                                
\
+        (pNv)->dmaFree -= ((size) + 1);                                 \
+} while(0)
+
+
 #define SURFACE_FORMAT                                              0x00000300
-#define SURFACE_FORMAT_DEPTH8                                       0x00000001
-#define SURFACE_FORMAT_DEPTH15                                      0x00000002
-#define SURFACE_FORMAT_DEPTH16                                      0x00000004
-#define SURFACE_FORMAT_DEPTH24                                      0x00000006
+#define SURFACE_FORMAT_Y8                                           0x00000001
+#define SURFACE_FORMAT_X1R5G5B5                                     0x00000002
+#define SURFACE_FORMAT_R5G6B5                                       0x00000004
+#define SURFACE_FORMAT_X8R8G8B8                                     0x00000006
+#define SURFACE_FORMAT_A8R8G8B8                                     0x0000000a
 #define SURFACE_PITCH                                               0x00000304
 #define SURFACE_PITCH_SRC                                           15:0
 #define SURFACE_PITCH_DST                                           31:16
 #define SURFACE_OFFSET_SRC                                          0x00000308
 #define SURFACE_OFFSET_DST                                          0x0000030C
 
+/* compat */
+#define SURFACE_FORMAT_DEPTH8  SURFACE_FORMAT_Y8
+#define SURFACE_FORMAT_DEPTH15 SURFACE_FORMAT_X1R5G5B5
+#define SURFACE_FORMAT_DEPTH16 SURFACE_FORMAT_R5G6B5
+#define SURFACE_FORMAT_DEPTH24 SURFACE_FORMAT_X8R8G8B8
+#define SURFACE_FORMAT_DEPTH32 SURFACE_FORMAT_A8R8G8B8
+
 #define ROP_SET                                                     0x00002300
 
 #define PATTERN_FORMAT                                              0x00004300
@@ -165,3 +188,5 @@
 #define STRETCH_BLIT_SRC_POINT                                      0x0000E40C
 #define STRETCH_BLIT_SRC_POINT_U                                    15:0
 #define STRETCH_BLIT_SRC_POINT_V                                    31:16
+
+#endif /* NV_DMA_H */
Index: nv_include.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_include.h,v
retrieving revision 1.4
diff -u -p -r1.4 nv_include.h
--- nv_include.h        12 May 2013 13:06:25 -0000      1.4
+++ nv_include.h        10 Dec 2015 18:31:09 -0000
@@ -40,6 +40,8 @@
 #ifdef HAVE_XAA_H
 #include "xaa.h"
 #endif
+#include "exa.h"
+
 #include "xf86fbman.h"
 #include "xf86cmap.h"
 #include "shadowfb.h"
Index: nv_local.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_local.h,v
retrieving revision 1.3
diff -u -p -r1.3 nv_local.h
--- nv_local.h  18 Nov 2013 19:45:41 -0000      1.3
+++ nv_local.h  10 Dec 2015 18:31:09 -0000
@@ -54,16 +54,6 @@ typedef unsigned int   U032;
 #define VGA_WR08(p,i,d) NV_WR08(p,i,d)
 #define VGA_RD08(p,i)   NV_RD08(p,i)
 
-#define NVDmaNext(pNv, data) \
-     (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data)
-
-#define NVDmaStart(pNv, tag, size) {          \
-     if((pNv)->dmaFree <= (size))             \
-        NVDmaWait(pNv, size);                 \
-     NVDmaNext(pNv, ((size) << 18) | (tag));  \
-     (pNv)->dmaFree -= ((size) + 1);          \
-}
-
 #if defined(__i386__)
 #define _NV_FENCE() outb(0x3D0, 0);
 #else
Index: nv_proto.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_proto.h,v
retrieving revision 1.3
diff -u -p -r1.3 nv_proto.h
--- nv_proto.h  18 Nov 2013 19:45:41 -0000      1.3
+++ nv_proto.h  10 Dec 2015 18:31:09 -0000
@@ -34,8 +34,17 @@ Bool   NVAccelInit(ScreenPtr pScreen);
 void   NVSync(ScrnInfoPtr pScrn);
 void   NVResetGraphics(ScrnInfoPtr pScrn);
 void   NVDmaKickoff(NVPtr pNv);
+void   NVDMAKickoffCallback(ScrnInfoPtr pScrn);
 void   NVDmaWait(NVPtr pNv, int size);
 void   NVWaitVSync(NVPtr pNv);
+void   NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask);
+
+/* int nv_exa.c */
+uint32_t NVAccelGetPixmapOffset(NVPtr pNv, PixmapPtr pPix);
+Bool NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret);
+Bool NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPix, int *fmt_ret);
+Bool NVAccelSetCtxSurf2D(NVPtr pNv, PixmapPtr psPix, PixmapPtr pdPix, int fmt);
+Bool   NVExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 /* in nv_dga.c */
 Bool   NVDGAInit(ScreenPtr pScreen);
Index: nv_type.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/nv_type.h,v
retrieving revision 1.4
diff -u -p -r1.4 nv_type.h
--- nv_type.h   18 Nov 2013 19:45:41 -0000      1.4
+++ nv_type.h   10 Dec 2015 18:31:09 -0000
@@ -12,6 +12,39 @@
 #define NV_ARCH_30  0x30
 #define NV_ARCH_40  0x40
 
+#define CHIPSET_NV03     0x0010
+#define CHIPSET_NV04     0x0020
+#define CHIPSET_NV10     0x0100
+#define CHIPSET_NV11     0x0110
+#define CHIPSET_NV15     0x0150
+#define CHIPSET_NV17     0x0170
+#define CHIPSET_NV18     0x0180
+#define CHIPSET_NFORCE   0x01A0
+#define CHIPSET_NFORCE2  0x01F0
+#define CHIPSET_NV20     0x0200
+#define CHIPSET_NV25     0x0250
+#define CHIPSET_NV28     0x0280
+#define CHIPSET_NV30     0x0300
+#define CHIPSET_NV31     0x0310
+#define CHIPSET_NV34     0x0320
+#define CHIPSET_NV35     0x0330
+#define CHIPSET_NV36     0x0340
+#define CHIPSET_NV40     0x0040
+#define CHIPSET_NV41     0x00C0
+#define CHIPSET_NV43     0x0140
+#define CHIPSET_NV44     0x0160
+#define CHIPSET_NV44A    0x0220
+#define CHIPSET_NV45     0x0210
+#define CHIPSET_MISC_BRIDGED  0x00F0
+#define CHIPSET_G70      0x0090
+#define CHIPSET_G71      0x0290
+#define CHIPSET_G72      0x01D0
+#define CHIPSET_G73      0x0390
+// integrated GeForces (6100, 6150)
+#define CHIPSET_C51      0x0240
+// variant of C51, seems based on a G70 design
+#define CHIPSET_C512     0x03D0
+#define CHIPSET_G73_BRIDGED 0x02E0
 
 #define NV_BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1)  << (b))
 #define NV_MASKEXPAND(mask) NV_BITMASK(1?mask,0?mask)
@@ -77,6 +110,7 @@ typedef struct {
     RIVA_HW_STATE       *CurrentState;
     CARD32              Architecture;
     CARD32              CursorStart;
+    int                 offscreenHeight;
     EntityInfoPtr       pEnt;
 #if XSERVER_LIBPCIACCESS
     struct pci_device  *PciInfo;
@@ -125,9 +159,16 @@ typedef struct {
     volatile U008 *PDIO0;
     volatile U008 *PDIO;
     volatile U032 *PRAMDAC;
+
+    /* XAA */
 #ifdef HAVE_XAA_H
     XAAInfoRecPtr       AccelInfoRec;
 #endif
+
+    /* EXA */
+    ExaDriverPtr       EXADriverPtr;
+    Bool                useEXA;
+
     xf86CursorInfoPtr   CursorInfoRec;
     DGAModePtr          DGAModes;
     int                 numDGAModes;
Index: Makefile.am
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-nv/src/Makefile.am,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile.am
--- Makefile.am 16 Aug 2012 16:35:27 -0000      1.4
+++ Makefile.am 10 Dec 2015 18:31:09 -0000
@@ -46,6 +46,7 @@ nv_sources = \
          nv_shadow.c \
          nv_type.h \
          nv_video.c \
+         nv_exa.c \
          nv_xaa.c
 
 riva_sources = \

Reply via email to