st/xorg: Add EXA UploadToScreen and DownloadFromScreen hooks.
authorMichel Dänzer <daenzer@vmware.com>
Wed, 2 Sep 2009 13:41:40 +0000 (15:41 +0200)
committerMichel Dänzer <daenzer@vmware.com>
Wed, 2 Sep 2009 13:41:40 +0000 (15:41 +0200)
src/gallium/state_trackers/xorg/xorg_exa.c

index 1ed807de93d1251b3b8f2f9f783b19febf4d7b64..a17a71f23a8a50439f416ba7b04d9fdc85f469a1 100644 (file)
@@ -97,6 +97,68 @@ ExaMarkSync(ScreenPtr pScreen)
     return 1;
 }
 
+static Bool
+ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
+                     int dst_pitch)
+{
+    ScreenPtr pScreen = pPix->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
+    struct pipe_transfer *transfer;
+
+    if (!priv || !priv->tex)
+       return FALSE;
+
+    if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
+       PIPE_REFERENCED_FOR_WRITE)
+       exa->ctx->flush(exa->ctx, 0, NULL);
+
+    transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+                                          PIPE_TRANSFER_READ, x, y, w, h);
+    if (!transfer)
+       return FALSE;
+
+    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);
+
+    exa->scrn->transfer_unmap(exa->scrn, transfer);
+    exa->scrn->tex_transfer_destroy(transfer);
+
+    return TRUE;
+}
+
+static Bool
+ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
+                 int src_pitch)
+{
+    ScreenPtr pScreen = pPix->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_context *exa = ms->exa;
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
+    struct pipe_transfer *transfer;
+
+    if (!priv || !priv->tex)
+       return FALSE;
+
+    transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+                                          PIPE_TRANSFER_WRITE, x, y, w, h);
+    if (!transfer)
+       return FALSE;
+
+    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);
+
+    exa->scrn->transfer_unmap(exa->scrn, transfer);
+    exa->scrn->tex_transfer_destroy(transfer);
+
+    return TRUE;
+}
+
 static Bool
 ExaPrepareAccess(PixmapPtr pPix, int index)
 {
@@ -599,6 +661,8 @@ xorg_exa_init(ScrnInfoPtr pScrn)
    pExa->Composite          = ExaComposite;
    pExa->DoneComposite      = ExaDoneComposite;
    pExa->PixmapIsOffscreen  = ExaPixmapIsOffscreen;
+   pExa->DownloadFromScreen = ExaDownloadFromScreen;
+   pExa->UploadToScreen     = ExaUploadToScreen;
    pExa->PrepareAccess      = ExaPrepareAccess;
    pExa->FinishAccess       = ExaFinishAccess;
    pExa->CreatePixmap       = ExaCreatePixmap;