xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Thu Sep 10 10:43:05 PDT 2009


 src/r600_exa.c |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 161 insertions(+), 2 deletions(-)

New commits:
commit a88f60e7b789cd23a79e6e18a7e3fa008d15aa77
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Thu Sep 10 13:42:31 2009 -0400

    r600: add CS UTS and DFS hooks

diff --git a/src/r600_exa.c b/src/r600_exa.c
index 86da68c..40c7c04 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -2112,6 +2112,165 @@ R600DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
 
 }
 
+#if defined(XF86DRM_MODE)
+static inline void radeon_add_pixmap(struct radeon_cs *cs, PixmapPtr pPix, int read_domains, int write_domain)
+{
+    struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    radeon_cs_space_add_persistent_bo(cs, driver_priv->bo, read_domains, write_domain);
+}
+
+static Bool
+R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
+		     char *src, int src_pitch)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_bo *scratch;
+    unsigned size;
+    uint32_t dst_domain;
+    int bpp = pDst->drawable.bitsPerPixel;
+    uint32_t scratch_pitch = (w * bpp / 8 + 255) & ~255;
+    uint32_t src_pitch_hw = scratch_pitch / (bpp / 8);
+    uint32_t dst_pitch_hw = exaGetPixmapPitch(pDst) / (bpp / 8);
+    Bool r;
+    int i;
+
+    if (bpp < 8)
+	return FALSE;
+
+    driver_priv = exaGetPixmapDriverPrivate(pDst);
+
+    /* If we know the BO won't be busy, don't bother */
+    if (driver_priv->bo->cref == 1 &&
+	!radeon_bo_is_busy(driver_priv->bo, &dst_domain))
+	return FALSE;
+
+    size = scratch_pitch * h;
+    scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
+    if (scratch == NULL) {
+	return FALSE;
+    }
+    radeon_cs_space_reset_bos(info->cs);
+    radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+    radeon_cs_space_add_persistent_bo(info->cs, scratch, RADEON_GEM_DOMAIN_GTT, 0);
+    r = radeon_cs_space_check(info->cs);
+    if (r) {
+        r = FALSE;
+        goto out;
+    }
+
+    r = radeon_bo_map(scratch, 0);
+    if (r) {
+        r = FALSE;
+        goto out;
+    }
+    r = TRUE;
+    size = w * bpp / 8;
+    for (i = 0; i < h; i++) {
+        memcpy(scratch->ptr + i * scratch_pitch, src, size);
+        src += src_pitch;
+    }
+    radeon_bo_unmap(scratch);
+
+    /* blit from gart to vram */
+    R600DoPrepareCopy(pScrn,
+		      src_pitch_hw, w, h,
+		      0, scratch, bpp,
+		      dst_pitch_hw, pDst->drawable.width, pDst->drawable.height,
+		      0, radeon_get_pixmap_bo(pDst), bpp,
+		      3, 0xffffffff);
+    R600AppendCopyVertex(pScrn, 0, 0, x, y, w, h);
+    R600DoCopy(pScrn);
+
+out:
+    radeon_bo_unref(scratch);
+    return r;
+}
+
+static Bool
+R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
+			 int h, char *dst, int dst_pitch)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_bo *scratch;
+    unsigned size;
+    uint32_t src_domain = 0;
+    int bpp = pSrc->drawable.bitsPerPixel;
+    uint32_t scratch_pitch = (w * bpp / 8 + 255) & ~255;
+    uint32_t dst_pitch_hw = scratch_pitch / (bpp / 8);
+    uint32_t src_pitch_hw = exaGetPixmapPitch(pSrc) / (bpp / 8);
+    Bool r;
+
+    if (bpp < 8)
+	return FALSE;
+
+    driver_priv = exaGetPixmapDriverPrivate(pSrc);
+
+    /* If we know the BO won't end up in VRAM anyway, don't bother */
+    if (driver_priv->bo->cref > 1) {
+	src_domain = driver_priv->bo->space_accounted & 0xffff;
+	if (!src_domain)
+	    src_domain = driver_priv->bo->space_accounted >> 16;
+
+	if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
+	    (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
+	    src_domain = 0;
+    }
+
+    if (!src_domain)
+	radeon_bo_is_busy(driver_priv->bo, &src_domain);
+
+    if (src_domain != RADEON_GEM_DOMAIN_VRAM)
+	return FALSE;
+
+    size = scratch_pitch * h;
+    scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
+    if (scratch == NULL) {
+	return FALSE;
+    }
+    radeon_cs_space_reset_bos(info->cs);
+    radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+    radeon_cs_space_add_persistent_bo(info->cs, scratch, 0, RADEON_GEM_DOMAIN_GTT);
+    r = radeon_cs_space_check(info->cs);
+    if (r) {
+        r = FALSE;
+        goto out;
+    }
+
+    /* blit from vram to gart */
+    R600DoPrepareCopy(pScrn,
+		      src_pitch_hw, pSrc->drawable.width, pSrc->drawable.height,
+		      0, radeon_get_pixmap_bo(pSrc), bpp,
+		      dst_pitch_hw, w, h,
+		      0, scratch, bpp,
+		      3, 0xffffffff);
+    R600AppendCopyVertex(pScrn, x, y, 0, 0, w, h);
+    R600DoCopy(pScrn);
+
+    r = radeon_bo_map(scratch, 0);
+    if (r) {
+        r = FALSE;
+        goto out;
+    }
+    r = TRUE;
+    w *= bpp / 8;
+    size = 0;
+    while (h--) {
+        memcpy(dst, scratch->ptr + size, w);
+        size += scratch_pitch;
+        dst += dst_pitch;
+    }
+    radeon_bo_unmap(scratch);
+out:
+    radeon_bo_unref(scratch);
+    return r;
+}
+#endif
+
 static int
 R600MarkSync(ScreenPtr pScreen)
 {
@@ -2305,8 +2464,8 @@ R600DrawInit(ScreenPtr pScreen)
 	info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
 	info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
 	info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
-	info->accel_state->exa->UploadToScreen = NULL;
-	info->accel_state->exa->DownloadFromScreen = NULL;
+	info->accel_state->exa->UploadToScreen = R600UploadToScreenCS;
+	info->accel_state->exa->DownloadFromScreen = R600DownloadFromScreenCS;
     } else
 #endif
 #endif


More information about the xorg-commit mailing list