drm_api: Operate on textures instead of buffers
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa.c
index ac0bfc88a4dbade2ee27ea19f662069567526dba..acc49f4c2b1d221172e818ba20fae42c5f094123 100644 (file)
  *
  */
 
-/* FIXME ! */
-#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri"
-
-#include "xf86.h"
-//#include "xf86_OSproc.h"
+#include "xorg_exa.h"
 #include "xorg_tracker.h"
+#include "xorg_composite.h"
+#include "xorg_exa_tgsi.h"
+
+#include <xorg-server.h>
+#include <xf86.h>
+#include <picturestr.h>
+#include <picture.h>
 
-//#include "pipe/p_winsys.h"
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
-struct exa_entity
-{
-    ExaDriverPtr pExa;
-    struct pipe_context *ctx;
-    struct pipe_screen *scrn;
-};
+#include "cso_cache/cso_context.h"
 
-struct PixmapPriv
-{
-    int flags;
-    struct pipe_texture *tex;
-    unsigned int color;
-    struct pipe_surface *src_surf; /* for copies */
-    struct pipe_transfer *map_transfer;
-};
+#include "util/u_rect.h"
 
 /*
  * Helper functions
  */
 
-static enum pipe_format
-exa_get_pipe_format(int depth)
+static void
+exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
 {
     switch (depth) {
     case 32:
-       return PIPE_FORMAT_A8R8G8B8_UNORM;
+       *format = PIPE_FORMAT_A8R8G8B8_UNORM;
+       assert(*bbp == 32);
+       break;
     case 24:
-       return PIPE_FORMAT_X8R8G8B8_UNORM;
+       *format = PIPE_FORMAT_X8R8G8B8_UNORM;
+       assert(*bbp == 32);
+       break;
     case 16:
-       return PIPE_FORMAT_R5G6B5_UNORM;
+       *format = PIPE_FORMAT_R5G6B5_UNORM;
+       assert(*bbp == 16);
+       break;
     case 15:
-       return PIPE_FORMAT_A1R5G5B5_UNORM;
+       *format = PIPE_FORMAT_A1R5G5B5_UNORM;
+       assert(*bbp == 16);
+       break;
     case 8:
     case 4:
     case 1:
-       return PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
+       *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
+       break;
     default:
        assert(0);
-       return 0;
+       break;
     }
 }
 
@@ -104,10 +103,8 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv;
-    //int ret;
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv;
 
     priv = exaGetPixmapDriverPrivate(pPix);
 
@@ -116,7 +113,13 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
 
     if (!priv->tex)
        return FALSE;
+
+    if (priv->map_count++ == 0)
     {
+       if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
+           PIPE_REFERENCED_FOR_WRITE)
+           exa->ctx->flush(exa->ctx, 0, NULL);
+
        priv->map_transfer =
            exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
                                        PIPE_TRANSFER_READ_WRITE,
@@ -136,8 +139,8 @@ ExaFinishAccess(PixmapPtr pPix, int index)
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv;
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv;
     priv = exaGetPixmapDriverPrivate(pPix);
 
     if (!priv)
@@ -146,9 +149,12 @@ ExaFinishAccess(PixmapPtr pPix, int index)
     if (!priv->map_transfer)
        return;
 
-    exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
-    pipe_transfer_reference(&priv->map_transfer, NULL);
-
+    if (--priv->map_count == 0) {
+       assert(priv->map_transfer);
+       exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
+       exa->scrn->tex_transfer_destroy(priv->map_transfer);
+       priv->map_transfer = NULL;
+    }
 }
 
 static void
@@ -156,14 +162,14 @@ ExaDone(PixmapPtr pPixmap)
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct exa_entity *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct exa_context *exa = ms->exa;
 
     if (!priv)
        return;
 
     if (priv->src_surf)
-       exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf);
+       exa->scrn->tex_surface_destroy(priv->src_surf);
     priv->src_surf = NULL;
 }
 
@@ -178,8 +184,8 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct exa_entity *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct exa_context *exa = ms->exa;
 
     if (1)
         return FALSE;
@@ -209,17 +215,14 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct pipe_surface *surf =
-       exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-                                  PIPE_BUFFER_USAGE_GPU_READ |
-                                  PIPE_BUFFER_USAGE_GPU_WRITE);
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct pipe_surface *surf = exa_gpu_surface(exa, priv);
 
     exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
                           priv->color);
 
-    exa->scrn->tex_surface_release(exa->scrn, &surf);
+    exa->scrn->tex_surface_destroy(surf);
 }
 
 static Bool
@@ -228,12 +231,9 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
 {
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
-    struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
-
-    if (1)
-        return FALSE;
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
+    struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
 
     if (alu != GXcopy)
        return FALSE;
@@ -253,12 +253,9 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
     if (!exa->ctx || !exa->ctx->surface_copy)
        return FALSE;
 
-    priv->src_surf =
-       exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0,
-                                  PIPE_BUFFER_USAGE_GPU_READ |
-                                  PIPE_BUFFER_USAGE_GPU_WRITE);
+    priv->src_surf = exa_gpu_surface(exa, src_priv);
 
-    return FALSE;
+    return TRUE;
 }
 
 static void
@@ -267,16 +264,13 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
 {
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
-    struct pipe_surface *surf =
-       exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-                                  PIPE_BUFFER_USAGE_GPU_READ |
-                                  PIPE_BUFFER_USAGE_GPU_WRITE);
-
-    exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf,
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
+    struct pipe_surface *surf = exa_gpu_surface(exa, priv);
+
+    exa->ctx->surface_copy(exa->ctx, surf, dstX, dstY, priv->src_surf,
                           srcX, srcY, width, height);
-    exa->scrn->tex_surface_release(exa->scrn, &surf);
+    exa->scrn->tex_surface_destroy(surf);
 }
 
 static Bool
@@ -284,24 +278,28 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
                    PicturePtr pMaskPicture, PicturePtr pDstPicture,
                    PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
 {
-    return FALSE;
-}
-
-#if 0
-static Bool
-ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
-                 int src_pitch)
-{
-    ErrorF("UPLOAD\n");
-
-    return FALSE;
+   ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
+
+   return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
+                                    pDstPicture,
+                                    exaGetPixmapDriverPrivate(pSrc),
+                                    exaGetPixmapDriverPrivate(pMask),
+                                    exaGetPixmapDriverPrivate(pDst));
 }
-#endif
 
 static void
 ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
             int dstX, int dstY, int width, int height)
 {
+   ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
+   struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
+
+   xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
+                  dstX, dstY, width, height);
 }
 
 static Bool
@@ -309,15 +307,18 @@ ExaCheckComposite(int op,
                  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
                  PicturePtr pDstPicture)
 {
-    return FALSE;
+   return xorg_composite_accelerated(op,
+                                     pSrcPicture,
+                                     pMaskPicture,
+                                     pDstPicture);
 }
 
 static void *
 ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
 {
-    struct PixmapPriv *priv;
+    struct exa_pixmap_priv *priv;
 
-    priv = xcalloc(1, sizeof(struct PixmapPriv));
+    priv = xcalloc(1, sizeof(struct exa_pixmap_priv));
     if (!priv)
        return NULL;
 
@@ -327,16 +328,15 @@ ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
 static void
 ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
 {
-    struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
+    struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
 
     if (!priv)
        return;
 
     if (priv->tex)
-       ms->screen->texture_release(exa->scrn, &priv->tex);
+       ms->screen->texture_destroy(priv->tex);
 
     xfree(priv);
 }
@@ -344,7 +344,7 @@ ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
 static Bool
 ExaPixmapIsOffscreen(PixmapPtr pPixmap)
 {
-    struct PixmapPriv *priv;
+    struct exa_pixmap_priv *priv;
 
     priv = exaGetPixmapDriverPrivate(pPixmap);
 
@@ -357,14 +357,45 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap)
     return FALSE;
 }
 
+int
+xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
+{
+    struct exa_pixmap_priv *priv;
+    priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    if (!priv) {
+       FatalError("NO PIXMAP PRIVATE\n");
+       return 0;
+    }
+
+    priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+
+    return 0;
+}
+
+int
+xorg_exa_set_shared_usage(PixmapPtr pPixmap)
+{
+    struct exa_pixmap_priv *priv;
+    priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    if (!priv) {
+       FatalError("NO PIXMAP PRIVATE\n");
+       return 0;
+    }
+
+    priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+    return 0;
+}
+
 unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
+xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv;
-    struct pipe_buffer *buffer = NULL;
+    struct exa_pixmap_priv *priv;
     unsigned handle;
     unsigned stride;
 
@@ -380,9 +411,10 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
        return 0;
     }
 
-    drm_api_hocks.buffer_from_texture(priv->tex, &buffer, &stride);
-    drm_api_hocks.handle_from_buffer(ms->screen, buffer, &handle);
-    pipe_buffer_reference(ms->screen, &buffer, NULL);
+    ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
+    if (stride_out)
+       *stride_out = stride;
+
     return handle;
 }
 
@@ -393,10 +425,9 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
     modesettingPtr ms = modesettingPTR(pScrn);
-    //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    struct exa_entity *exa = ms->exa;
+    struct exa_context *exa = ms->exa;
 
     if (!priv)
        return FALSE;
@@ -420,115 +451,169 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
                             bitsPerPixel, devKind, NULL);
 
     /* Deal with screen resize */
-    if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) {
+    if (priv->tex && (priv->tex->width[0] != width ||
+                     priv->tex->height[0] != height ||
+                     priv->tex_flags != priv->flags)) {
        pipe_texture_reference(&priv->tex, NULL);
     }
 
-    if (!priv->tex) {
+    if (!priv->tex
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+       && priv->flags
+#endif
+       ) {
        struct pipe_texture template;
 
        memset(&template, 0, sizeof(template));
        template.target = PIPE_TEXTURE_2D;
-       template.compressed = 0;
-       template.format = exa_get_pipe_format(depth);
+       exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
        pf_get_block(template.format, &template.block);
        template.width[0] = width;
        template.height[0] = height;
        template.depth[0] = 1;
        template.last_level = 0;
-       template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+       template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
+       priv->tex_flags = priv->flags;
        priv->tex = exa->scrn->texture_create(exa->scrn, &template);
     }
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    if (!priv->tex) {
+       if (pPixData)
+           pPixmap->devPrivate.ptr = pPixData;
+       else
+           pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * pPixmap->devKind);
+    } else
+#endif
+    if (pPixData) {
+       struct pipe_transfer *transfer =
+           exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+                                       PIPE_TRANSFER_WRITE,
+                                       0, 0, width, height);
+        util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+                       &priv->tex->block, transfer->stride, 0, 0,
+                       width, height, pPixData, pPixmap->devKind, 0, 0);
+        exa->scrn->transfer_unmap(exa->scrn, transfer);
+        exa->scrn->tex_transfer_destroy(transfer);
+    }
+
     return TRUE;
 }
 
 struct pipe_texture *
 xorg_exa_get_texture(PixmapPtr pPixmap)
 {
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct pipe_texture *tex = NULL;
-    pipe_texture_reference(&tex, priv->tex);
-    return tex;
+   struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+   struct pipe_texture *tex = NULL;
+   pipe_texture_reference(&tex, priv->tex);
+   return tex;
 }
 
 void
 xorg_exa_close(ScrnInfoPtr pScrn)
 {
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
+   struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer;
+   struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer;
 
-    if (exa->ctx)
-       exa->ctx->destroy(exa->ctx);
-
-    exaDriverFini(pScrn->pScreen);
-    xfree(exa);
-    ms->exa = NULL;
-}
+   if (exa->shaders) {
+      xorg_shaders_destroy(exa->shaders);
+   }
 
-void *
-xorg_exa_init(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa;
-    ExaDriverPtr pExa;
+   if (vsbuf && vsbuf->buffer)
+      pipe_buffer_reference(&vsbuf->buffer, NULL);
 
-    exa = xcalloc(1, sizeof(struct exa_entity));
-    if (!exa)
-       return NULL;
+   if (fsbuf && fsbuf->buffer)
+      pipe_buffer_reference(&fsbuf->buffer, NULL);
 
-    pExa = exaDriverAlloc();
-    if (!pExa) {
-       goto out_err;
-    }
+   if (exa->cso) {
+      cso_release_all(exa->cso);
+      cso_destroy_context(exa->cso);
+   }
 
-    memset(pExa, 0, sizeof(*pExa));
-    pExa->exa_major = 2;
-    pExa->exa_minor = 2;
-    pExa->memoryBase = 0;
-    pExa->memorySize = 0;
-    pExa->offScreenBase = 0;
-    pExa->pixmapOffsetAlign = 0;
-    pExa->pixmapPitchAlign = 1;
-    pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
-    pExa->maxX = 8191;                /* FIXME */
-    pExa->maxY = 8191;                /* FIXME */
-    pExa->WaitMarker = ExaWaitMarker;
-    pExa->MarkSync = ExaMarkSync;
-    pExa->PrepareSolid = ExaPrepareSolid;
-    pExa->Solid = ExaSolid;
-    pExa->DoneSolid = ExaDone;
-    pExa->PrepareCopy = ExaPrepareCopy;
-    pExa->Copy = ExaCopy;
-    pExa->DoneCopy = ExaDone;
-    pExa->CheckComposite = ExaCheckComposite;
-    pExa->PrepareComposite = ExaPrepareComposite;
-    pExa->Composite = ExaComposite;
-    pExa->DoneComposite = ExaDoneComposite;
-    pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
-    pExa->PrepareAccess = ExaPrepareAccess;
-    pExa->FinishAccess = ExaFinishAccess;
-    //pExa->UploadToScreen = ExaUploadToScreen;
-    pExa->UploadToScreen = NULL;
-    pExa->CreatePixmap = ExaCreatePixmap;
-    pExa->DestroyPixmap = ExaDestroyPixmap;
-    pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
-
-    if (!exaDriverInit(pScrn->pScreen, pExa)) {
-       goto out_err;
-    }
+   if (exa->ctx)
+      exa->ctx->destroy(exa->ctx);
 
-    exa->scrn = ms->screen;
-    exa->ctx = drm_api_hocks.create_context(exa->scrn);
-    /* Share context with DRI */
-    ms->ctx = exa->ctx;
+   exaDriverFini(pScrn->pScreen);
+   xfree(exa);
+   ms->exa = NULL;
+}
 
-    return (void *)exa;
+void *
+xorg_exa_init(ScrnInfoPtr pScrn)
+{
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa;
+   ExaDriverPtr pExa;
+
+   exa = xcalloc(1, sizeof(struct exa_context));
+   if (!exa)
+      return NULL;
+
+   pExa = exaDriverAlloc();
+   if (!pExa) {
+      goto out_err;
+   }
+
+   memset(pExa, 0, sizeof(*pExa));
+
+   pExa->exa_major         = 2;
+   pExa->exa_minor         = 2;
+   pExa->memoryBase        = 0;
+   pExa->memorySize        = 0;
+   pExa->offScreenBase     = 0;
+   pExa->pixmapOffsetAlign = 0;
+   pExa->pixmapPitchAlign  = 1;
+   pExa->flags             = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
+   pExa->maxX              = 8191; /* FIXME */
+   pExa->maxY              = 8191; /* FIXME */
+
+   pExa->WaitMarker         = ExaWaitMarker;
+   pExa->MarkSync           = ExaMarkSync;
+   pExa->PrepareSolid       = ExaPrepareSolid;
+   pExa->Solid              = ExaSolid;
+   pExa->DoneSolid          = ExaDone;
+   pExa->PrepareCopy        = ExaPrepareCopy;
+   pExa->Copy               = ExaCopy;
+   pExa->DoneCopy           = ExaDone;
+   pExa->CheckComposite     = ExaCheckComposite;
+   pExa->PrepareComposite   = ExaPrepareComposite;
+   pExa->Composite          = ExaComposite;
+   pExa->DoneComposite      = ExaDoneComposite;
+   pExa->PixmapIsOffscreen  = ExaPixmapIsOffscreen;
+   pExa->PrepareAccess      = ExaPrepareAccess;
+   pExa->FinishAccess       = ExaFinishAccess;
+   pExa->CreatePixmap       = ExaCreatePixmap;
+   pExa->DestroyPixmap      = ExaDestroyPixmap;
+   pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
+
+   if (!exaDriverInit(pScrn->pScreen, pExa)) {
+      goto out_err;
+   }
+
+   exa->scrn = ms->screen;
+   exa->ctx = ms->api->create_context(ms->api, exa->scrn);
+   /* Share context with DRI */
+   ms->ctx = exa->ctx;
+
+   exa->cso = cso_create_context(exa->ctx);
+   exa->shaders = xorg_shaders_create(exa);
+
+   return (void *)exa;
+
+out_err:
+   xorg_exa_close(pScrn);
+
+   return NULL;
+}
 
-  out_err:
-    xorg_exa_close(pScrn);
+struct pipe_surface *
+exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
+{
+   return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
+                                     PIPE_BUFFER_USAGE_GPU_READ |
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
 
-    return NULL;
 }
 
-/* vim: set sw=4 ts=8 sts=4: */