st/xorg: Flush any pending operations on upload
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa.c
index c71779bc207cee96815ce23ad5304789b6483d90..3d83b5700d50d0aa95456c2ef026c0a95eac2f3b 100644 (file)
 #include "util/u_rect.h"
 
 #define DEBUG_PRINT 0
-#define ACCEL_ENABLED TRUE
 
 /*
  * Helper functions
  */
-#if DEBUG_PRINT
 struct render_format_str {
    int format;
    const char *name;
 };
 static const struct render_format_str formats_info[] =
 {
-   {PICT_a2r10g10b10, "PICT_a2r10g10b10"},
-   {PICT_x2r10g10b10, "PICT_x2r10g10b10"},
-   {PICT_a2b10g10r10, "PICT_a2b10g10r10"},
-   {PICT_x2b10g10r10, "PICT_x2b10g10r10"},
    {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"},
@@ -109,7 +109,6 @@ static const char *render_format_name(int format)
    }
    return NULL;
 }
-#endif
 
 static void
 exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
@@ -170,15 +169,7 @@ xorg_exa_common_done(struct exa_context *exa)
 static void
 ExaWaitMarker(ScreenPtr pScreen, int marker)
 {
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   modesettingPtr ms = modesettingPTR(pScrn);
-   struct exa_context *exa = ms->exa;
-
-#if 0
-   xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#else
-   xorg_exa_finish(exa);
-#endif
+   /* Nothing to do, handled in the PrepareAccess hook */
 }
 
 static int
@@ -239,6 +230,11 @@ 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)
@@ -384,7 +380,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
        XORG_FALLBACK("format %s", pf_name(priv->tex->format));
     }
 
-    return ACCEL_ENABLED && xorg_solid_bind_state(exa, priv, fg);
+    return exa->accel && xorg_solid_bind_state(exa, priv, fg);
 }
 
 static void
@@ -443,7 +439,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
     exa->copy.src = src_priv;
     exa->copy.dst = priv;
 
-    return ACCEL_ENABLED;
+    return exa->accel;
 }
 
 static void
@@ -467,6 +463,41 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
                         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
 ExaPrepareComposite(int op, PicturePtr pSrcPicture,
                    PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -512,10 +543,13 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
          XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
 
-      if (priv->picture_format != pSrcPicture->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");
    }
 
    if (pMask) {
@@ -528,13 +562,13 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
          XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
 
-      if (priv->picture_format != pMaskPicture->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 ACCEL_ENABLED &&
+   return exa->accel &&
           xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
                                     pDstPicture,
                                     pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
@@ -567,6 +601,9 @@ 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,
@@ -575,7 +612,7 @@ ExaCheckComposite(int op,
    debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
                 op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
 #endif
-   return ACCEL_ENABLED && accelerated;
+   return exa->accel && accelerated;
 }
 
 static void *
@@ -713,10 +750,11 @@ 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;
        struct pipe_texture template;
 
@@ -831,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;
@@ -896,6 +934,7 @@ xorg_exa_init(ScrnInfoPtr pScrn)
    ms->ctx = exa->pipe;
 
    exa->renderer = renderer_create(exa->pipe);
+   exa->accel = accel;
 
    return (void *)exa;