xf86-video-nv: 4 commits - man/nv.man README.G80 src/g80_driver.c src/g80_exa.c src/g80_exa.h src/g80_type.h src/g80_xaa.c src/g80_xaa.h src/Makefile.am

Aaron Plattner aplattner at kemper.freedesktop.org
Wed Apr 25 06:58:11 EEST 2007


 README.G80       |    5 
 man/nv.man       |    9 +
 src/Makefile.am  |    2 
 src/g80_driver.c |   83 ++++++++++++-
 src/g80_exa.c    |  329 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/g80_exa.h    |    1 
 src/g80_type.h   |   11 +
 src/g80_xaa.c    |   10 -
 src/g80_xaa.h    |    5 
 9 files changed, 436 insertions(+), 19 deletions(-)

New commits:
diff-tree ed9f98853a781344c10cb801214917e13bddf27c (from 88d44d5e4fd0025c30e9d67b55c603c59bd1c0c1)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Apr 24 20:57:43 2007 -0700

    Remove some old stuff from README.G80.

diff --git a/README.G80 b/README.G80
index f168957..a49c3c8 100644
--- a/README.G80
+++ b/README.G80
@@ -3,12 +3,7 @@ series of graphics processors.
 
 There are a few caveats of which to be aware:
  - The XVideo extension is not supported.
- - With X servers prior to version 1.2.0 (X.org 7.2.0) on 64-bit Linux or most
-   non-Linux platforms, the driver may fail to restore the console due to bugs
-   in the server's x86 emulator.
  - The RENDER extension is not accelerated by this driver.
- - Only one output can be used at a time.  Work is in progress in the randr-1.2
-   branch to support dual-head output.
 
 Bugs should be reported at http://bugs.freedesktop.org/ under the "xorg"
 product, "Driver/nVidia (open)" component.  Please be sure to fill out the
diff-tree 88d44d5e4fd0025c30e9d67b55c603c59bd1c0c1 (from 29433b76969b73a2a22081bf965bb0cdbaad75af)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Apr 24 20:45:52 2007 -0700

    Get EXA resizing working and document it.

diff --git a/man/nv.man b/man/nv.man
index 6ef62c5..9f5917f 100644
--- a/man/nv.man
+++ b/man/nv.man
@@ -143,6 +143,15 @@ Enable or disable the hardware cursor.  
 .TP
 .BI "Option \*qNoAccel\*q \*q" boolean \*q
 Disable or enable acceleration.  Default: acceleration is enabled.
+.TP
+.BI "Option \*qAccelMethod\*q \*q" string \*q
+Choose acceleration architecture, either \*qXAA\*q or \*qEXA\*q.
+XAA is the old but stable architecture.
+EXA is newer and supports resizing the desktop larger than it started out with RandR 1.2.
+If you choose to use EXA, you might also consider setting
+.B Option \*qMigrationHeuristic\*q \*qgreedy\*q
+to improve performance.
+Default: XAA.
 .\" ******************** end G80 section ********************
 .
 .SH "SEE ALSO"
diff --git a/src/g80_driver.c b/src/g80_driver.c
index 3e93237..c81388c 100644
--- a/src/g80_driver.c
+++ b/src/g80_driver.c
@@ -133,6 +133,7 @@ G80FreeRec(ScrnInfoPtr pScrn)
 static Bool
 G80ResizeScreen(ScrnInfoPtr pScrn, int width, int height)
 {
+    ScreenPtr pScreen = pScrn->pScreen;
     G80Ptr pNv = G80PTR(pScrn);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int pitch = width * (pScrn->bitsPerPixel / 8);
@@ -143,8 +144,8 @@ G80ResizeScreen(ScrnInfoPtr pScrn, int w
     pScrn->virtualX = width;
     pScrn->virtualY = height;
 
-    /* Can resize if XAA is disabled */
-    if(!pNv->xaa) {
+    /* Can resize if XAA is disabled or EXA is enabled */
+    if(!pNv->xaa || pNv->exa) {
         (*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen)->devKind = pitch;
         pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8);
 
@@ -156,6 +157,23 @@ G80ResizeScreen(ScrnInfoPtr pScrn, int w
         }
     }
 
+    /*
+     * If EXA is enabled, use exaOffscreenAlloc to carve out a chunk of memory
+     * for the screen.
+     */
+    if(pNv->exa) {
+        if(pNv->exaScreenArea)
+            exaOffscreenFree(pScreen, pNv->exaScreenArea);
+        pNv->exaScreenArea = exaOffscreenAlloc(pScreen, pitch * pScrn->virtualY,
+                                               256, TRUE, NULL, NULL);
+        if(!pNv->exaScreenArea || pNv->exaScreenArea->offset != 0) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                       "Failed to reserve EXA memory for the screen or EXA "
+                       "returned an area with a nonzero offset.  Don't be "
+                       "surprised if your screen is corrupt.\n");
+        }
+    }
+
     return TRUE;
 }
 
@@ -362,7 +380,7 @@ G80PreInit(ScrnInfoPtr pScrn, int flags)
     G80DispCreateCrtcs(pScrn);
 
     /* We can grow the desktop if XAA is disabled */
-    if(!xf86InitialConfiguration(pScrn, pNv->NoAccel)) {
+    if(!xf86InitialConfiguration(pScrn, pNv->NoAccel || pNv->AccelMethod == EXA)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
             "No valid initial configuration found\n");
         goto fail;
@@ -469,8 +487,13 @@ G80CloseScreen(int scrnIndex, ScreenPtr 
 
     if(pNv->xaa)
         XAADestroyInfoRec(pNv->xaa);
-    if(pNv->exa)
+    if(pNv->exa) {
+        if(pNv->exaScreenArea) {
+            exaOffscreenFree(pScreen, pNv->exaScreenArea);
+            pNv->exaScreenArea = NULL;
+        }
         exaDriverFini(pScrn->pScreen);
+    }
     xf86_cursors_fini(pScreen);
 
     if(xf86ServerIsExiting()) {
diff --git a/src/g80_exa.c b/src/g80_exa.c
index 8113c1a..96dbc21 100644
--- a/src/g80_exa.c
+++ b/src/g80_exa.c
@@ -302,7 +302,7 @@ Bool G80ExaInit(ScreenPtr pScreen, ScrnI
     exa->exa_major         = EXA_VERSION_MAJOR;
     exa->exa_minor         = EXA_VERSION_MINOR;
     exa->memoryBase        = pNv->mem;
-    exa->offScreenBase     = pitch * pScrn->virtualY;
+    exa->offScreenBase     = 0;
     exa->memorySize        = pitch * pNv->offscreenHeight;
     exa->pixmapOffsetAlign = 256;
     exa->pixmapPitchAlign  = 256;
diff --git a/src/g80_type.h b/src/g80_type.h
index 17acf93..15b8792 100644
--- a/src/g80_type.h
+++ b/src/g80_type.h
@@ -60,6 +60,7 @@ typedef struct G80Rec {
 
     /* EXA */
     ExaDriverPtr        exa;
+    ExaOffscreenArea   *exaScreenArea;
 
     /* DMA command buffer */
     CARD32              dmaPut;
diff-tree 29433b76969b73a2a22081bf965bb0cdbaad75af (from 339e30cb49a48344ec7b0dfd701b958b07ed32e5)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Sat Apr 21 21:43:06 2007 -0700

    EXA: Add solid, copy, and UTS hooks.

diff --git a/src/g80_exa.c b/src/g80_exa.c
index 7f487ff..8113c1a 100644
--- a/src/g80_exa.c
+++ b/src/g80_exa.c
@@ -28,6 +28,7 @@
 
 #include "g80_type.h"
 #include "g80_dma.h"
+#include "g80_xaa.h"
 
 static void
 waitMarker(ScreenPtr pScreen, int marker)
@@ -36,23 +37,112 @@ waitMarker(ScreenPtr pScreen, int marker
 }
 
 static Bool
+setSrc(G80Ptr pNv, PixmapPtr pSrc)
+{
+    CARD32 depth;
+
+    switch(pSrc->drawable.depth) {
+        case  8: depth = 0x000000f3; break;
+        case 15: depth = 0x000000f8; break;
+        case 16: depth = 0x000000e8; break;
+        case 24: depth = 0x000000e6; break;
+        case 32: depth = 0x000000cf; break;
+        default: return FALSE;
+    }
+
+    G80DmaStart(pNv, 0x230, 2);
+    G80DmaNext (pNv, depth);
+    G80DmaNext (pNv, 0x00000001);
+    G80DmaStart(pNv, 0x244, 5);
+    G80DmaNext (pNv, exaGetPixmapPitch(pSrc));
+    G80DmaNext (pNv, pSrc->drawable.width);
+    G80DmaNext (pNv, pSrc->drawable.height);
+    G80DmaNext (pNv, 0x00000000);
+    G80DmaNext (pNv, exaGetPixmapOffset(pSrc));
+
+    return TRUE;
+}
+
+static Bool
+setDst(G80Ptr pNv, PixmapPtr pDst)
+{
+    CARD32 depth, depth2;
+
+    switch(pDst->drawable.depth) {
+        case  8: depth = 0x000000f3; depth2 = 3; break;
+        case 15: depth = 0x000000f8; depth2 = 1; break;
+        case 16: depth = 0x000000e8; depth2 = 0; break;
+        case 24: depth = 0x000000e6; depth2 = 2; break;
+        case 32: depth = 0x000000cf; depth2 = 2; break;
+        default: return FALSE;
+    }
+
+    G80DmaStart(pNv, 0x200, 2);
+    G80DmaNext (pNv, depth);
+    G80DmaNext (pNv, 0x00000001);
+    G80DmaStart(pNv, 0x214, 5);
+    G80DmaNext (pNv, exaGetPixmapPitch(pDst));
+    G80DmaNext (pNv, pDst->drawable.width);
+    G80DmaNext (pNv, pDst->drawable.height);
+    G80DmaNext (pNv, 0x00000000);
+    G80DmaNext (pNv, exaGetPixmapOffset(pDst));
+    G80DmaStart(pNv, 0x2e8, 1);
+    G80DmaNext (pNv, depth2);
+    G80DmaStart(pNv, 0x584, 1);
+    G80DmaNext (pNv, depth);
+    G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height);
+
+    return TRUE;
+}
+
+/* solid fills */
+
+static Bool
 prepareSolid(PixmapPtr      pPixmap,
              int            alu,
              Pixel          planemask,
              Pixel          fg)
 {
-    return FALSE;
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    G80Ptr pNv = G80PTR(pScrn);
+
+    if(pPixmap->drawable.depth > 24) return FALSE;
+    if(!setDst(pNv, pPixmap)) return FALSE;
+    G80DmaStart(pNv, 0x2ac, 1);
+    G80DmaNext (pNv, 1);
+    G80SetRopSolid(pNv, alu, planemask);
+    G80DmaStart(pNv, 0x580, 1);
+    G80DmaNext (pNv, 4);
+    G80DmaStart(pNv, 0x588, 1);
+    G80DmaNext (pNv, fg);
+
+    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
+    return TRUE;
 }
 
-static Bool
-checkComposite(int          op,
-               PicturePtr   pSrcPicture,
-               PicturePtr   pMaskPicture,
-               PicturePtr   pDstPicture)
+static void
+solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    G80Ptr pNv = G80PTR(pScrn);
+
+    G80DmaStart(pNv, 0x600, 4);
+    G80DmaNext (pNv, x1);
+    G80DmaNext (pNv, y1);
+    G80DmaNext (pNv, x2);
+    G80DmaNext (pNv, y2);
+
+    if((x2 - x1) * (y2 - y1) >= 512)
+        G80DmaKickoff(pNv);
+}
+
+static void
+doneSolid(PixmapPtr pPixmap)
 {
-    return FALSE;
 }
 
+/* screen to screen copies */
+
 static Bool
 prepareCopy(PixmapPtr       pSrcPixmap,
             PixmapPtr       pDstPixmap,
@@ -61,9 +151,145 @@ prepareCopy(PixmapPtr       pSrcPixmap,
             int             alu,
             Pixel           planemask)
 {
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    G80Ptr pNv = G80PTR(pScrn);
+
+    if(!setSrc(pNv, pSrcPixmap)) return FALSE;
+    if(!setDst(pNv, pDstPixmap)) return FALSE;
+    G80DmaStart(pNv, 0x2ac, 1);
+    if(alu == GXcopy && planemask == ~0) {
+        G80DmaNext (pNv, 3);
+    } else {
+        G80DmaNext (pNv, 1);
+        G80SetRopSolid(pNv, alu, planemask);
+    }
+    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
+    return TRUE;
+}
+
+static void
+copy(PixmapPtr pDstPixmap,
+     int       srcX,
+     int       srcY,
+     int       dstX,
+     int       dstY,
+     int       width,
+     int       height)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    G80Ptr pNv = G80PTR(pScrn);
+
+    G80DmaStart(pNv, 0x110, 1);
+    G80DmaNext (pNv, 0);
+    G80DmaStart(pNv, 0x8b0, 12);
+    G80DmaNext (pNv, dstX);
+    G80DmaNext (pNv, dstY);
+    G80DmaNext (pNv, width);
+    G80DmaNext (pNv, height);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, 1);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, 1);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, srcX);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, srcY);
+
+    if(width * height >= 512)
+        G80DmaKickoff(pNv);
+}
+
+static void
+doneCopy(PixmapPtr pDstPixmap)
+{
+}
+
+/* composite */
+
+static Bool
+checkComposite(int          op,
+               PicturePtr   pSrc,
+               PicturePtr   pMask,
+               PicturePtr   pDst)
+{
     return FALSE;
 }
 
+/* upload to screen */
+
+static Bool
+upload(PixmapPtr pDst,
+       int       x,
+       int       y,
+       int       w,
+       int       h,
+       char      *src,
+       int       src_pitch)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    G80Ptr pNv = G80PTR(pScrn);
+    const int Bpp = pDst->drawable.bitsPerPixel >> 3;
+    int line_dwords = (w * Bpp + 3) / 4;
+    const Bool kickoff = w * h >= 512;
+    CARD32 depth;
+
+    if(!setDst(pNv, pDst)) return FALSE;
+    switch(pDst->drawable.depth) {
+        case  8: depth = 0x000000f3; break;
+        case 15: depth = 0x000000f8; break;
+        case 16: depth = 0x000000e8; break;
+        case 24: depth = 0x000000e6; break;
+        case 32: depth = 0x000000cf; break;
+        default: return FALSE;
+    }
+
+    G80SetClip(pNv, x, y, w, h);
+    G80DmaStart(pNv, 0x2ac, 1);
+    G80DmaNext (pNv, 3);
+    G80DmaStart(pNv, 0x800, 2);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, depth);
+    G80DmaStart(pNv, 0x838, 10);
+    G80DmaNext (pNv, (line_dwords * 4) / Bpp);
+    G80DmaNext (pNv, h);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, 1);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, 1);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, x);
+    G80DmaNext (pNv, 0);
+    G80DmaNext (pNv, y);
+
+    while(h-- > 0) {
+        int count = line_dwords;
+        char *p = src;
+
+        while(count) {
+            int size = count > 1792 ? 1792 : count;
+
+            G80DmaStart(pNv, 0x40000860, size);
+            memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4);
+
+            p += size * Bpp;
+            pNv->dmaCurrent += size;
+
+            count -= size;
+        }
+
+        src += src_pitch;
+    }
+
+    if(kickoff)
+        G80DmaKickoff(pNv);
+    else
+        pNv->DMAKickoffCallback = G80DMAKickoffCallback;
+
+    return TRUE;
+}
+
+/******************************************************************************/
+
 Bool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
 {
     G80Ptr pNv = G80PTR(pScrn);
@@ -86,15 +312,16 @@ Bool G80ExaInit(ScreenPtr pScreen, ScrnI
 
     /**** Rendering ops ****/
     exa->PrepareSolid     = prepareSolid;
-    //exa->Solid            = solid;
-    //exa->DoneSolid        = doneSolid;
+    exa->Solid            = solid;
+    exa->DoneSolid        = doneSolid;
     exa->PrepareCopy      = prepareCopy;
-    //exa->Copy             = copy;
-    //exa->DoneCopy         = doneCopy;
+    exa->Copy             = copy;
+    exa->DoneCopy         = doneCopy;
     exa->CheckComposite   = checkComposite;
     //exa->PrepareComposite = prepareComposite;
     //exa->Composite        = composite;
     //exa->DoneComposite    = doneComposite;
+    exa->UploadToScreen   = upload;
 
     exa->WaitMarker       = waitMarker;
 
diff --git a/src/g80_xaa.c b/src/g80_xaa.c
index d256d64..0859623 100644
--- a/src/g80_xaa.c
+++ b/src/g80_xaa.c
@@ -56,7 +56,7 @@ G80DMAKickoffCallback(ScrnInfoPtr pScrn)
     pNv->DMAKickoffCallback = NULL;
 }
 
-static void
+void
 G80SetPattern(G80Ptr pNv, int bg, int fg, int pat0, int pat1)
 {
     G80DmaStart(pNv, 0x2f0, 4);
@@ -66,7 +66,7 @@ G80SetPattern(G80Ptr pNv, int bg, int fg
     G80DmaNext (pNv, pat1);
 }
 
-static void
+void
 G80SetRopSolid(G80Ptr pNv, CARD32 rop, CARD32 planemask)
 {
     static const int rops[] = {
@@ -95,7 +95,7 @@ G80SetRopSolid(G80Ptr pNv, CARD32 rop, C
     }
 }
 
-static void inline
+void inline
 G80SetClip(G80Ptr pNv, int x, int y, int w, int h)
 {
     G80DmaStart(pNv, 0x280, 4);
diff --git a/src/g80_xaa.h b/src/g80_xaa.h
index 7d2fee5..6c1d765 100644
--- a/src/g80_xaa.h
+++ b/src/g80_xaa.h
@@ -1,3 +1,6 @@
 void G80Sync(ScrnInfoPtr pScrn);
 void G80DMAKickoffCallback(ScrnInfoPtr pScrn);
+void G80SetPattern(G80Ptr pNv, int bg, int fg, int pat0, int pat1);
+void G80SetRopSolid(G80Ptr pNv, CARD32 rop, CARD32 planemask);
+void G80SetClip(G80Ptr pNv, int x, int y, int w, int h);
 Bool G80XAAInit(ScreenPtr);
diff-tree 339e30cb49a48344ec7b0dfd701b958b07ed32e5 (from c6e4105ce40ef053e026cc0ffe4925ab568ea700)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Mon Apr 16 02:23:26 2007 -0700

    G80: EXA infrastructure.
    
    No acceleration yet.

diff --git a/src/Makefile.am b/src/Makefile.am
index 52b6b47..e2166fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -75,6 +75,8 @@ g80_sources = \
          g80_dma.c \
          g80_dma.h \
          g80_driver.c \
+         g80_exa.c \
+         g80_exa.h \
          g80_output.c \
          g80_output.h \
          g80_sor.c \
diff --git a/src/g80_driver.c b/src/g80_driver.c
index a4e7bad..3e93237 100644
--- a/src/g80_driver.c
+++ b/src/g80_driver.c
@@ -45,6 +45,7 @@
 #include "g80_display.h"
 #include "g80_dma.h"
 #include "g80_output.h"
+#include "g80_exa.h"
 #include "g80_xaa.h"
 
 #define G80_REG_SIZE (1024 * 1024 * 16)
@@ -66,6 +67,13 @@ static const char *xaaSymbols[] = {
     NULL
 };
 
+static const char *exaSymbols[] = {
+    "exaDriverAlloc",
+    "exaDriverInit",
+    "exaDriverFini",
+    NULL
+};
+
 static const char *i2cSymbols[] = {
     "xf86CreateI2CBusRec",
     "xf86I2CBusInit",
@@ -96,11 +104,13 @@ static const char *int10Symbols[] = {
 typedef enum {
     OPTION_HW_CURSOR,
     OPTION_NOACCEL,
+    OPTION_ACCEL_METHOD,
 } G80Opts;
 
 static const OptionInfoRec G80Options[] = {
     { OPTION_HW_CURSOR,         "HWCursor",     OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_NOACCEL,           "NoAccel",      OPTV_BOOLEAN,   {0}, FALSE },
+    { OPTION_ACCEL_METHOD,      "AccelMethod",  OPTV_STRING,    {0}, FALSE },
     { -1,                       NULL,           OPTV_NONE,      {0}, FALSE }
 };
 
@@ -164,6 +174,7 @@ G80PreInit(ScrnInfoPtr pScrn, int flags)
     Bool primary;
     const rgb zeros = {0, 0, 0};
     const Gamma gzeros = {0.0, 0.0, 0.0};
+    char *s;
     CARD32 tmp;
 
     if(flags & PROBE_DETECT) {
@@ -272,6 +283,16 @@ G80PreInit(ScrnInfoPtr pScrn, int flags)
         pNv->NoAccel = TRUE;
         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
     }
+    s = xf86GetOptValString(pNv->Options, OPTION_ACCEL_METHOD);
+    if(!s || !strcasecmp(s, "xaa"))
+        pNv->AccelMethod = XAA;
+    else if(!strcasecmp(s, "exa"))
+        pNv->AccelMethod = EXA;
+    else {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unrecognized AccelMethod "
+        "\"%s\".\n", s);
+        goto fail;
+    }
 
     /* Set the bits per RGB for 8bpp mode */
     if(pScrn->depth == 8)
@@ -366,8 +387,16 @@ G80PreInit(ScrnInfoPtr pScrn, int flags)
     xf86LoaderReqSymLists(fbSymbols, NULL);
 
     if(!pNv->NoAccel) {
-        if(!xf86LoadSubModule(pScrn, "xaa")) goto fail;
-        xf86LoaderReqSymLists(xaaSymbols, NULL);
+        switch(pNv->AccelMethod) {
+        case XAA:
+            if(!xf86LoadSubModule(pScrn, "xaa")) goto fail;
+            xf86LoaderReqSymLists(xaaSymbols, NULL);
+            break;
+        case EXA:
+            if(!xf86LoadSubModule(pScrn, "exa")) goto fail;
+            xf86LoaderReqSymLists(exaSymbols, NULL);
+            break;
+        }
     }
 
     /* Load ramdac if needed */
@@ -440,6 +469,8 @@ G80CloseScreen(int scrnIndex, ScreenPtr 
 
     if(pNv->xaa)
         XAADestroyInfoRec(pNv->xaa);
+    if(pNv->exa)
+        exaDriverFini(pScrn->pScreen);
     xf86_cursors_fini(pScreen);
 
     if(xf86ServerIsExiting()) {
@@ -759,10 +790,21 @@ G80ScreenInit(int scrnIndex, ScreenPtr p
 
     if(!pNv->NoAccel) {
         G80InitHW(pScrn);
-        if(!G80XAAInit(pScreen)) {
-            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                       "Hardware acceleration initialization failed\n");
-            return FALSE;
+        switch(pNv->AccelMethod) {
+        case XAA:
+            if(!G80XAAInit(pScreen)) {
+                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                           "XAA hardware acceleration initialization failed\n");
+                return FALSE;
+            }
+            break;
+        case EXA:
+            if(!G80ExaInit(pScreen, pScrn)) {
+                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                           "EXA hardware acceleration initialization failed\n");
+                return FALSE;
+            }
+            break;
         }
     }
 
diff --git a/src/g80_exa.c b/src/g80_exa.c
new file mode 100644
index 0000000..7f487ff
--- /dev/null
+++ b/src/g80_exa.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2007 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 "g80_type.h"
+#include "g80_dma.h"
+
+static void
+waitMarker(ScreenPtr pScreen, int marker)
+{
+    G80Sync(xf86Screens[pScreen->myNum]);
+}
+
+static Bool
+prepareSolid(PixmapPtr      pPixmap,
+             int            alu,
+             Pixel          planemask,
+             Pixel          fg)
+{
+    return FALSE;
+}
+
+static Bool
+checkComposite(int          op,
+               PicturePtr   pSrcPicture,
+               PicturePtr   pMaskPicture,
+               PicturePtr   pDstPicture)
+{
+    return FALSE;
+}
+
+static Bool
+prepareCopy(PixmapPtr       pSrcPixmap,
+            PixmapPtr       pDstPixmap,
+            int             dx,
+            int             dy,
+            int             alu,
+            Pixel           planemask)
+{
+    return FALSE;
+}
+
+Bool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
+{
+    G80Ptr pNv = G80PTR(pScrn);
+    ExaDriverPtr exa;
+    const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
+
+    exa = pNv->exa = exaDriverAlloc();
+    if(!exa) return FALSE;
+
+    exa->exa_major         = EXA_VERSION_MAJOR;
+    exa->exa_minor         = EXA_VERSION_MINOR;
+    exa->memoryBase        = pNv->mem;
+    exa->offScreenBase     = pitch * pScrn->virtualY;
+    exa->memorySize        = pitch * pNv->offscreenHeight;
+    exa->pixmapOffsetAlign = 256;
+    exa->pixmapPitchAlign  = 256;
+    exa->flags             = EXA_OFFSCREEN_PIXMAPS;
+    exa->maxX              = 8192;
+    exa->maxY              = 8192;
+
+    /**** Rendering ops ****/
+    exa->PrepareSolid     = prepareSolid;
+    //exa->Solid            = solid;
+    //exa->DoneSolid        = doneSolid;
+    exa->PrepareCopy      = prepareCopy;
+    //exa->Copy             = copy;
+    //exa->DoneCopy         = doneCopy;
+    exa->CheckComposite   = checkComposite;
+    //exa->PrepareComposite = prepareComposite;
+    //exa->Composite        = composite;
+    //exa->DoneComposite    = doneComposite;
+
+    exa->WaitMarker       = waitMarker;
+
+    return exaDriverInit(pScreen, exa);
+}
diff --git a/src/g80_exa.h b/src/g80_exa.h
new file mode 100644
index 0000000..2f01af6
--- /dev/null
+++ b/src/g80_exa.h
@@ -0,0 +1 @@
+Bool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn);
diff --git a/src/g80_type.h b/src/g80_type.h
index 95517e3..17acf93 100644
--- a/src/g80_type.h
+++ b/src/g80_type.h
@@ -1,4 +1,5 @@
 #include <xaa.h>
+#include <exa.h>
 #include <xf86.h>
 #include <xf86int10.h>
 #include <xf86Cursor.h>
@@ -24,6 +25,11 @@ typedef enum ORNum {
    SOR1 = 1
 } ORNum;
 
+typedef enum AccelMethod {
+    XAA,
+    EXA,
+} AccelMethod;
+
 typedef struct G80Rec {
     volatile CARD32 *   reg;
     unsigned char *     mem;
@@ -46,11 +52,15 @@ typedef struct G80Rec {
     OptionInfoPtr       Options;
     Bool                HWCursor;
     Bool                NoAccel;
+    AccelMethod         AccelMethod;
 
     /* XAA */
     XAAInfoRecPtr       xaa;
     CARD32              currentRop;
 
+    /* EXA */
+    ExaDriverPtr        exa;
+
     /* DMA command buffer */
     CARD32              dmaPut;
     CARD32              dmaCurrent;
diff --git a/src/g80_xaa.c b/src/g80_xaa.c
index 1f07444..d256d64 100644
--- a/src/g80_xaa.c
+++ b/src/g80_xaa.c
@@ -31,7 +31,7 @@
 #include "g80_dma.h"
 #include "g80_xaa.h"
 
-static void
+void
 G80Sync(ScrnInfoPtr pScrn)
 {
     G80Ptr pNv = G80PTR(pScrn);
@@ -47,7 +47,7 @@ G80Sync(ScrnInfoPtr pScrn)
     while(*pSync);
 }
 
-static void
+void
 G80DMAKickoffCallback(ScrnInfoPtr pScrn)
 {
     G80Ptr pNv = G80PTR(pScrn);
diff --git a/src/g80_xaa.h b/src/g80_xaa.h
index e2f1f63..7d2fee5 100644
--- a/src/g80_xaa.h
+++ b/src/g80_xaa.h
@@ -1 +1,3 @@
+void G80Sync(ScrnInfoPtr pScrn);
+void G80DMAKickoffCallback(ScrnInfoPtr pScrn);
 Bool G80XAAInit(ScreenPtr);



More information about the xorg-commit mailing list