st/xorg: Flush any pending operations on upload
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa.c
index 94f4ea2c3868a5e90f9b30076c2d05dc9b02dcd9..3d83b5700d50d0aa95456c2ef026c0a95eac2f3b 100644 (file)
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
-#include "cso_cache/cso_context.h"
-
 #include "util/u_rect.h"
 
-#define DEBUG_SOLID 0
-#define DISABLE_ACCEL 1
+#define DEBUG_PRINT 0
 
 /*
  * Helper functions
  */
+struct render_format_str {
+   int format;
+   const char *name;
+};
+static const struct render_format_str formats_info[] =
+{
+   {PICT_a8r8g8b8, "PICT_a8r8g8b8"},
+   {PICT_x8r8g8b8, "PICT_x8r8g8b8"},
+   {PICT_a8b8g8r8, "PICT_a8b8g8r8"},
+   {PICT_x8b8g8r8, "PICT_x8b8g8r8"},
+#ifdef PICT_TYPE_BGRA
+   {PICT_b8g8r8a8, "PICT_b8g8r8a8"},
+   {PICT_b8g8r8x8, "PICT_b8g8r8x8"},
+   {PICT_a2r10g10b10, "PICT_a2r10g10b10"},
+   {PICT_x2r10g10b10, "PICT_x2r10g10b10"},
+   {PICT_a2b10g10r10, "PICT_a2b10g10r10"},
+   {PICT_x2b10g10r10, "PICT_x2b10g10r10"},
+#endif
+   {PICT_r8g8b8, "PICT_r8g8b8"},
+   {PICT_b8g8r8, "PICT_b8g8r8"},
+   {PICT_r5g6b5, "PICT_r5g6b5"},
+   {PICT_b5g6r5, "PICT_b5g6r5"},
+   {PICT_a1r5g5b5, "PICT_a1r5g5b5"},
+   {PICT_x1r5g5b5, "PICT_x1r5g5b5"},
+   {PICT_a1b5g5r5, "PICT_a1b5g5r5"},
+   {PICT_x1b5g5r5, "PICT_x1b5g5r5"},
+   {PICT_a4r4g4b4, "PICT_a4r4g4b4"},
+   {PICT_x4r4g4b4, "PICT_x4r4g4b4"},
+   {PICT_a4b4g4r4, "PICT_a4b4g4r4"},
+   {PICT_x4b4g4r4, "PICT_x4b4g4r4"},
+   {PICT_a8, "PICT_a8"},
+   {PICT_r3g3b2, "PICT_r3g3b2"},
+   {PICT_b2g3r3, "PICT_b2g3r3"},
+   {PICT_a2r2g2b2, "PICT_a2r2g2b2"},
+   {PICT_a2b2g2r2, "PICT_a2b2g2r2"},
+   {PICT_c8, "PICT_c8"},
+   {PICT_g8, "PICT_g8"},
+   {PICT_x4a4, "PICT_x4a4"},
+   {PICT_x4c4, "PICT_x4c4"},
+   {PICT_x4g4, "PICT_x4g4"},
+   {PICT_a4, "PICT_a4"},
+   {PICT_r1g2b1, "PICT_r1g2b1"},
+   {PICT_b1g2r1, "PICT_b1g2r1"},
+   {PICT_a1r1g1b1, "PICT_a1r1g1b1"},
+   {PICT_a1b1g1r1, "PICT_a1b1g1r1"},
+   {PICT_c4, "PICT_c4"},
+   {PICT_g4, "PICT_g4"},
+   {PICT_a1, "PICT_a1"},
+   {PICT_g1, "PICT_g1"}
+};
+static const char *render_format_name(int format)
+{
+   int i = 0;
+   for (i = 0; i < sizeof(formats_info)/sizeof(formats_info[0]); ++i) {
+      if (formats_info[i].format == format)
+         return formats_info[i].name;
+   }
+   return NULL;
+}
 
 static void
-exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
+exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
 {
     switch (depth) {
     case 32:
        *format = PIPE_FORMAT_A8R8G8B8_UNORM;
+       *picture_format = PICT_a8r8g8b8;
        assert(*bbp == 32);
        break;
     case 24:
        *format = PIPE_FORMAT_X8R8G8B8_UNORM;
+       *picture_format = PICT_x8r8g8b8;
        assert(*bbp == 32);
        break;
     case 16:
        *format = PIPE_FORMAT_R5G6B5_UNORM;
+       *picture_format = PICT_r5g6b5;
        assert(*bbp == 16);
        break;
     case 15:
        *format = PIPE_FORMAT_A1R5G5B5_UNORM;
+       *picture_format = PICT_x1r5g5b5;
        assert(*bbp == 16);
        break;
     case 8:
-       *format = PIPE_FORMAT_I8_UNORM;
+       *format = PIPE_FORMAT_L8_UNORM;
+       *picture_format = PICT_a8;
        assert(*bbp == 8);
        break;
     case 4:
@@ -88,21 +149,15 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
     }
 }
 
-static void
-xorg_exa_init_state(struct exa_context *exa)
-{
-   struct pipe_depth_stencil_alpha_state dsa;
-
-   /* set common initial clip state */
-   memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-   cso_set_depth_stencil_alpha(exa->cso, &dsa);
-}
-
 static void
 xorg_exa_common_done(struct exa_context *exa)
 {
+   renderer_draw_flush(exa->renderer);
+
    exa->copy.src = NULL;
    exa->copy.dst = NULL;
+   exa->transform.has_src = FALSE;
+   exa->transform.has_mask = FALSE;
    exa->has_solid_color = FALSE;
    exa->num_bound_samplers = 0;
 }
@@ -114,12 +169,13 @@ xorg_exa_common_done(struct exa_context *exa)
 static void
 ExaWaitMarker(ScreenPtr pScreen, int marker)
 {
+   /* Nothing to do, handled in the PrepareAccess hook */
 }
 
 static int
 ExaMarkSync(ScreenPtr pScreen)
 {
-    return 1;
+   return 1;
 }
 
 static Bool
@@ -145,6 +201,11 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
     if (!transfer)
        return FALSE;
 
+#if DEBUG_PRINT
+    debug_printf("------ ExaDownloadFromScreen(%d, %d, %d, %d, %d)\n",
+                 x, y, w, h, dst_pitch);
+#endif
+
     util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
                   w, h, exa->scrn->transfer_map(exa->scrn, transfer),
                   transfer->stride, 0, 0);
@@ -169,11 +230,21 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
     if (!priv || !priv->tex)
        return FALSE;
 
+    /* make sure that any pending operations are flushed to hardware */
+    if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+       (PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
+       xorg_exa_flush(exa, 0, NULL);
+
     transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
                                           PIPE_TRANSFER_WRITE, x, y, w, h);
     if (!transfer)
        return FALSE;
 
+#if DEBUG_PRINT
+    debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n",
+                 x, y, w, h, src_pitch);
+#endif
+
     util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
                   &priv->tex->block, transfer->stride, 0, 0, w, h,
                   (unsigned char*)src, src_pitch, 0, 0);
@@ -201,7 +272,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
     if (!priv->tex)
        return FALSE;
 
-    if (priv->map_count++ == 0)
+    if (priv->map_count == 0)
     {
        if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
            PIPE_REFERENCED_FOR_WRITE)
@@ -209,14 +280,25 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
 
        priv->map_transfer =
            exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+#ifdef EXA_MIXED_PIXMAPS
+                                       PIPE_TRANSFER_MAP_DIRECTLY |
+#endif
                                        PIPE_TRANSFER_READ_WRITE,
                                        0, 0, priv->tex->width[0], priv->tex->height[0]);
+       if (!priv->map_transfer)
+#ifdef EXA_MIXED_PIXMAPS
+           return FALSE;
+#else
+           FatalError("failed to create transfer\n");
+#endif
 
        pPix->devPrivate.ptr =
            exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
        pPix->devKind = priv->map_transfer->stride;
     }
 
+    priv->map_count++;
+
     return TRUE;
 }
 
@@ -256,11 +338,6 @@ ExaDone(PixmapPtr pPixmap)
     if (!priv)
        return;
 
-#if 1
-    xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#else
-    xorg_exa_finish(exa);
-#endif
     xorg_exa_common_done(exa);
 }
 
@@ -282,36 +359,28 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
     struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
     struct exa_context *exa = ms->exa;
 
-#if 1
+#if DEBUG_PRINT
     debug_printf("ExaPrepareSolid(0x%x)\n", fg);
 #endif
-    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
-       return FALSE;
+    if (!exa->pipe)
+       XORG_FALLBACK("accle not enabled");
 
     if (!priv || !priv->tex)
-       return FALSE;
+       XORG_FALLBACK("%s", !priv ? "!priv" : "!priv->tex");
 
-    if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
-                                        priv->tex->target,
-                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
-       return FALSE;
+    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
+       XORG_FALLBACK("planeMask is not solid");
 
     if (alu != GXcopy)
-       return FALSE;
+       XORG_FALLBACK("not GXcopy");
 
-    if (!exa->pipe)
-       return FALSE;
-
-
-#if DEBUG_SOLID
-    fg = 0xffff0000;
-#endif
+    if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+                                        priv->tex->target,
+                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
+       XORG_FALLBACK("format %s", pf_name(priv->tex->format));
+    }
 
-#if DISABLE_ACCEL
-    return FALSE;
-#else
-    return xorg_solid_bind_state(exa, priv, fg);
-#endif
+    return exa->accel && xorg_solid_bind_state(exa, priv, fg);
 }
 
 static void
@@ -322,48 +391,11 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
     struct exa_context *exa = ms->exa;
     struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
 
+#if DEBUG_PRINT
     debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
-
-#if 0
-    if (x0 == 0 && y0 == 0 &&
-        x1 == priv->tex->width[0] &&
-        y1 == priv->tex->height[0]) {
-       exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
-                       exa->solid_color, 1., 0);
-    } else
 #endif
 
-#if DEBUG_SOLID
-       exa->solid_color[0] = 0.f;
-       exa->solid_color[1] = 1.f;
-       exa->solid_color[2] = 0.f;
-       exa->solid_color[3] = 1.f;
-    xorg_solid(exa, priv, 0, 0, 1024, 768);
-       exa->solid_color[0] = 1.f;
-       exa->solid_color[1] = 0.f;
-       exa->solid_color[2] = 0.f;
-       exa->solid_color[3] = 1.f;
-       xorg_solid(exa, priv, 0, 0, 300, 300);
-       xorg_solid(exa, priv, 300, 300, 350, 350);
-       xorg_solid(exa, priv, 350, 350, 500, 500);
-
-       xorg_solid(exa, priv,
-               priv->tex->width[0] - 10,
-               priv->tex->height[0] - 10,
-               priv->tex->width[0],
-               priv->tex->height[0]);
-
-    exa->solid_color[0] = 0.f;
-    exa->solid_color[1] = 0.f;
-    exa->solid_color[2] = 1.f;
-    exa->solid_color[3] = 1.f;
-
-    exa->has_solid_color = FALSE;
-    ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
-    ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
-#else
     xorg_solid(exa, priv, x0, y0, x1, y1) ;
-#endif
 }
 
 static Bool
@@ -376,39 +408,38 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
     struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
     struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
 
+#if DEBUG_PRINT
     debug_printf("ExaPrepareCopy\n");
+#endif
+    if (!exa->pipe)
+       XORG_FALLBACK("accle not enabled");
 
-    if (alu != GXcopy)
-       return FALSE;
+    if (!priv || !priv->tex)
+       XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex");
+
+    if (!src_priv || !src_priv->tex)
+       XORG_FALLBACK("pSrc %s", !src_priv ? "!priv" : "!priv->tex");
 
     if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
-       return FALSE;
+       XORG_FALLBACK("planeMask is not solid");
 
-    if (!priv || !src_priv)
-       return FALSE;
+    if (alu != GXcopy)
+       XORG_FALLBACK("alu not GXcopy");
 
     if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                         priv->tex->target,
-                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0) ||
-        !exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format,
+                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+       XORG_FALLBACK("pDst format %s", pf_name(priv->tex->format));
+
+    if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format,
                                         src_priv->tex->target,
                                         PIPE_TEXTURE_USAGE_SAMPLER, 0))
-       return FALSE;
-
-    if (!priv->tex || !src_priv->tex)
-       return FALSE;
-
-    if (!exa->pipe)
-       return FALSE;
+       XORG_FALLBACK("pSrc format %s", pf_name(src_priv->tex->format));
 
     exa->copy.src = src_priv;
     exa->copy.dst = priv;
 
-#if DISABLE_ACCEL
-    return FALSE;
-#else
-    return TRUE;
-#endif
+    return exa->accel;
 }
 
 static void
@@ -420,14 +451,51 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
 
+#if DEBUG_PRINT
    debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n",
                 srcX, srcY, dstX, dstY, width, height);
+#endif
 
    debug_assert(priv == exa->copy.dst);
 
-   xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY,
-                    exa->copy.src, srcX, srcY,
-                    width, height);
+   renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY,
+                        exa->copy.src, srcX, srcY,
+                        width, height);
+}
+
+static Bool
+picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
+{
+   if (pSrc->picture_format == pSrcPicture->format)
+      return TRUE;
+
+   if (pSrc->picture_format != PICT_a8r8g8b8)
+      return FALSE;
+
+   /* pSrc->picture_format == PICT_a8r8g8b8 */
+   switch (pSrcPicture->format) {
+   case PICT_a8r8g8b8:
+   case PICT_x8r8g8b8:
+   case PICT_a8b8g8r8:
+   case PICT_x8b8g8r8:
+   /* just treat these two as x8... */
+   case PICT_r8g8b8:
+   case PICT_b8g8r8:
+      return TRUE;
+#ifdef PICT_TYPE_BGRA
+   case PICT_b8g8r8a8:
+   case PICT_b8g8r8x8:
+      return FALSE; /* does not support swizzleing the alpha channel yet */
+   case PICT_a2r10g10b10:
+   case PICT_x2r10g10b10:
+   case PICT_a2b10g10r10:
+   case PICT_x2b10g10r10:
+      return FALSE;
+#endif
+   default:
+      return FALSE;
+   }
+   return FALSE;
 }
 
 static Bool
@@ -438,19 +506,74 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa = ms->exa;
+   struct exa_pixmap_priv *priv;
+
+#if DEBUG_PRINT
+   debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n",
+                op, pSrcPicture, pMaskPicture, pDstPicture);
+   debug_printf("\tFormats: src(%s), mask(%s), dst(%s)\n",
+                pSrcPicture ? render_format_name(pSrcPicture->format) : "none",
+                pMaskPicture ? render_format_name(pMaskPicture->format) : "none",
+                pDstPicture ? render_format_name(pDstPicture->format) : "none");
+#endif
+   if (!exa->pipe)
+      XORG_FALLBACK("accle not enabled");
+
+   priv = exaGetPixmapDriverPrivate(pDst);
+   if (!priv || !priv->tex)
+      XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex");
+
+   if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+                                       priv->tex->target,
+                                       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+      XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format));
+
+   if (priv->picture_format != pDstPicture->format)
+      XORG_FALLBACK("pDst pic_format: %s != %s",
+                    render_format_name(priv->picture_format),
+                    render_format_name(pDstPicture->format));
+
+   if (pSrc) {
+      priv = exaGetPixmapDriverPrivate(pSrc);
+      if (!priv || !priv->tex)
+         XORG_FALLBACK("pSrc %s", !priv ? "!priv" : "!priv->tex");
+
+      if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+                                          priv->tex->target,
+                                          PIPE_TEXTURE_USAGE_SAMPLER, 0))
+         XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
+
+      if (!picture_check_formats(priv, pSrcPicture))
+         XORG_FALLBACK("pSrc pic_format: %s != %s",
+                       render_format_name(priv->picture_format),
+                       render_format_name(pSrcPicture->format));
+
+      if (priv->picture_format == PICT_a8)
+         XORG_FALLBACK("pSrc pic_format == PICT_a8");
+   }
 
-   debug_printf("ExaPrepareComposite\n");
+   if (pMask) {
+      priv = exaGetPixmapDriverPrivate(pMask);
+      if (!priv || !priv->tex)
+         XORG_FALLBACK("pMask %s", !priv ? "!priv" : "!priv->tex");
 
-#if DISABLE_ACCEL
-   (void) exa;
-   return FALSE;
-#else
-   return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
+      if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+                                          priv->tex->target,
+                                          PIPE_TEXTURE_USAGE_SAMPLER, 0))
+         XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
+
+      if (!picture_check_formats(priv, pMaskPicture))
+         XORG_FALLBACK("pMask pic_format: %s != %s",
+                       render_format_name(priv->picture_format),
+                       render_format_name(pMaskPicture->format));
+   }
+
+   return exa->accel &&
+          xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
                                     pDstPicture,
-                                    exaGetPixmapDriverPrivate(pSrc),
-                                    exaGetPixmapDriverPrivate(pMask),
+                                    pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
+                                    pMask ? exaGetPixmapDriverPrivate(pMask) : NULL,
                                     exaGetPixmapDriverPrivate(pDst));
-#endif
 }
 
 static void
@@ -462,7 +585,12 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
 
-   debug_printf("\tExaComposite\n");
+#if DEBUG_PRINT
+   debug_printf("\tExaComposite(src[%d,%d], mask=[%d, %d], dst=[%d, %d], dim=[%d, %d])\n",
+                srcX, srcY, maskX, maskY, dstX, dstY, width, height);
+   debug_printf("\t   Num bound samplers = %d\n",
+                exa->num_bound_samplers);
+#endif
 
    xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
                   dstX, dstY, width, height);
@@ -473,13 +601,18 @@ ExaCheckComposite(int op,
                  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
                  PicturePtr pDstPicture)
 {
+   ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
    boolean accelerated = xorg_composite_accelerated(op,
                                                     pSrcPicture,
                                                     pMaskPicture,
                                                     pDstPicture);
+#if DEBUG_PRINT
    debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
                 op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
-   return accelerated;
+#endif
+   return exa->accel && accelerated;
 }
 
 static void *
@@ -617,70 +750,45 @@ 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 ||
-         priv->tex_flags != priv->flags)) {
+    if ((exa->accel || priv->flags) &&
+        (!priv->tex ||
+         (priv->tex->width[0] != width ||
+          priv->tex->height[0] != height ||
+          priv->tex_flags != priv->flags))) {
        struct pipe_texture *texture = NULL;
-
-#ifdef DRM_MODE_FEATURE_DIRTYFB
-       if (priv->flags)
-#endif
-       {
-           struct pipe_texture template;
-
-           memset(&template, 0, sizeof(template));
-           template.target = PIPE_TEXTURE_2D;
-           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 | priv->flags;
-           priv->tex_flags = priv->flags;
-           texture = exa->scrn->texture_create(exa->scrn, &template);
-
-           if (priv->tex) {
-               struct pipe_surface *dst_surf;
-                struct pipe_surface *src_surf;
-
-               dst_surf = exa->scrn->get_tex_surface(
-                   exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
-               src_surf = exa_gpu_surface(exa, priv);
-               exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
-                                        0, 0, min(width, texture->width[0]),
-                                        min(height, texture->height[0]));
-               exa->scrn->tex_surface_destroy(dst_surf);
-               exa->scrn->tex_surface_destroy(src_surf);
-           } else if (pPixmap->devPrivate.ptr) {
-               struct pipe_transfer *transfer;
-
-               if (priv->map_count != 0)
-                    FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
-
-               transfer =
-                   exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
-                                               PIPE_TRANSFER_WRITE,
-                                               0, 0, width, height);
-               util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
-                              &texture->block, transfer->stride, 0, 0,
-                              width, height, pPixmap->devPrivate.ptr,
-                              pPixmap->devKind, 0, 0);
-               exa->scrn->transfer_unmap(exa->scrn, transfer);
-               exa->scrn->tex_transfer_destroy(transfer);
-
-               xfree(pPixmap->devPrivate.ptr);
-               pPixmap->devPrivate.ptr = NULL;
-           }
-       }
-#ifdef DRM_MODE_FEATURE_DIRTYFB
-       else {
-           xfree(pPixmap->devPrivate.ptr);
-           pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
-                                            pPixmap->devKind);
+       struct pipe_texture template;
+
+       memset(&template, 0, sizeof(template));
+       template.target = PIPE_TEXTURE_2D;
+       exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
+       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 | priv->flags;
+       priv->tex_flags = priv->flags;
+       texture = exa->scrn->texture_create(exa->scrn, &template);
+
+       if (priv->tex) {
+           struct pipe_surface *dst_surf;
+           struct pipe_surface *src_surf;
+
+           dst_surf = exa->scrn->get_tex_surface(
+               exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
+           src_surf = xorg_gpu_surface(exa->pipe->screen, priv);
+        if (exa->pipe->surface_copy) {
+            exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
+                        0, 0, min(width, texture->width[0]),
+                        min(height, texture->height[0]));
+        } else {
+            util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
+                        0, 0, min(width, texture->width[0]),
+                        min(height, texture->height[0]));
+        }
+           exa->scrn->tex_surface_destroy(dst_surf);
+           exa->scrn->tex_surface_destroy(src_surf);
        }
-#endif
 
        pipe_texture_reference(&priv->tex, texture);
        /* the texture we create has one reference */
@@ -699,28 +807,58 @@ xorg_exa_get_texture(PixmapPtr pPixmap)
    return tex;
 }
 
+Bool
+xorg_exa_set_texture(PixmapPtr pPixmap, struct  pipe_texture *tex)
+{
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+    if (!priv)
+       return FALSE;
+
+    if (pPixmap->drawable.width != tex->width[0] ||
+       pPixmap->drawable.height != tex->height[0])
+       return FALSE;
+
+    pipe_texture_reference(&priv->tex, tex);
+    priv->tex_flags = tex->tex_usage & mask;
+
+    return TRUE;
+}
+
+struct pipe_texture *
+xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
+                            int width, int height,
+                            int depth, int bitsPerPixel)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_context *exa = ms->exa;
+    struct pipe_texture template;
+    int dummy;
+
+    memset(&template, 0, sizeof(template));
+    template.target = PIPE_TEXTURE_2D;
+    exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy);
+    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_PRIMARY;
+    template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+    return exa->scrn->texture_create(exa->scrn, &template);
+}
+
 void
 xorg_exa_close(ScrnInfoPtr pScrn)
 {
    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->shaders) {
-      xorg_shaders_destroy(exa->shaders);
-   }
-
-   if (vsbuf && vsbuf->buffer)
-      pipe_buffer_reference(&vsbuf->buffer, NULL);
 
-   if (fsbuf && fsbuf->buffer)
-      pipe_buffer_reference(&fsbuf->buffer, NULL);
-
-   if (exa->cso) {
-      cso_release_all(exa->cso);
-      cso_destroy_context(exa->cso);
-   }
+   renderer_destroy(exa->renderer);
 
    if (exa->pipe)
       exa->pipe->destroy(exa->pipe);
@@ -731,7 +869,7 @@ xorg_exa_close(ScrnInfoPtr pScrn)
 }
 
 void *
-xorg_exa_init(ScrnInfoPtr pScrn)
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
 {
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa;
@@ -795,10 +933,8 @@ xorg_exa_init(ScrnInfoPtr pScrn)
    /* Share context with DRI */
    ms->ctx = exa->pipe;
 
-   exa->cso = cso_create_context(exa->pipe);
-   exa->shaders = xorg_shaders_create(exa);
-
-   xorg_exa_init_state(exa);
+   exa->renderer = renderer_create(exa->pipe);
+   exa->accel = accel;
 
    return (void *)exa;
 
@@ -809,11 +945,11 @@ out_err:
 }
 
 struct pipe_surface *
-exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
+xorg_gpu_surface(struct pipe_screen *scrn, 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 scrn->get_tex_surface(scrn, priv->tex, 0, 0, 0,
+                                PIPE_BUFFER_USAGE_GPU_READ |
+                                PIPE_BUFFER_USAGE_GPU_WRITE);
 
 }