drm_api: Operate on textures instead of buffers
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa.c
index f2dac73e908c75ad544c0e6e8204e3884a33f389..acc49f4c2b1d221172e818ba20fae42c5f094123 100644 (file)
@@ -31,6 +31,7 @@
 #include "xorg_exa.h"
 #include "xorg_tracker.h"
 #include "xorg_composite.h"
+#include "xorg_exa_tgsi.h"
 
 #include <xorg-server.h>
 #include <xf86.h>
@@ -42,6 +43,8 @@
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
+#include "cso_cache/cso_context.h"
+
 #include "util/u_rect.h"
 
 /*
@@ -113,6 +116,10 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
 
     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,
@@ -210,10 +217,7 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_context *exa = ms->exa;
     struct exa_pixmap_priv *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 pipe_surface *surf = exa_gpu_surface(exa, priv);
 
     exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
                           priv->color);
@@ -231,9 +235,6 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
     struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
     struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
 
-    if (1)
-        return FALSE;
-
     if (alu != GXcopy)
        return FALSE;
 
@@ -252,10 +253,7 @@ 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 TRUE;
 }
@@ -268,10 +266,7 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_context *exa = ms->exa;
     struct exa_pixmap_priv *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);
+    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);
@@ -288,7 +283,10 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
    struct exa_context *exa = ms->exa;
 
    return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
-                                    pDstPicture);
+                                    pDstPicture,
+                                    exaGetPixmapDriverPrivate(pSrc),
+                                    exaGetPixmapDriverPrivate(pMask),
+                                    exaGetPixmapDriverPrivate(pDst));
 }
 
 static void
@@ -370,11 +368,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
        return 0;
     }
 
-    if (priv->flags & ~PIPE_TEXTURE_USAGE_PRIMARY) {
-       FatalError("BAD FLAGS\n");
-       return 0;
-    }
-    priv->flags = PIPE_TEXTURE_USAGE_PRIMARY;
+    priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
 
     return 0;
 }
@@ -390,11 +384,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
        return 0;
     }
 
-    if (priv->flags & ~PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
-       FatalError("BAD FLAGS\n");
-       return 0;
-    }
-    priv->flags = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+    priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
 
     return 0;
 }
@@ -406,7 +396,6 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_pixmap_priv *priv;
-    struct pipe_buffer *buffer = NULL;
     unsigned handle;
     unsigned stride;
 
@@ -422,9 +411,7 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
        return 0;
     }
 
-    ms->api->buffer_from_texture(ms->api, priv->tex, &buffer, &stride);
-    ms->api->handle_from_buffer(ms->api, ms->screen, buffer, &handle);
-    pipe_buffer_reference(&buffer, NULL);
+    ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
     if (stride_out)
        *stride_out = stride;
 
@@ -470,7 +457,11 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
        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));
@@ -486,12 +477,20 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
        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);
-        pipe_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+        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);
@@ -504,87 +503,117 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 struct pipe_texture *
 xorg_exa_get_texture(PixmapPtr pPixmap)
 {
-    struct exa_pixmap_priv *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_context *exa = ms->exa;
-
-    if (exa->ctx)
-       exa->ctx->destroy(exa->ctx);
+   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;
 
-    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_context *exa;
-    ExaDriverPtr pExa;
+   if (vsbuf && vsbuf->buffer)
+      pipe_buffer_reference(&vsbuf->buffer, NULL);
 
-    exa = xcalloc(1, sizeof(struct exa_context));
-    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->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 = ms->api->create_context(ms->api, 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: */