[PATCH 4/6] radeon: complete big endian UTS and DFS even when scratch allocation fails.

Karl Tomlinson karlt+ at karlt.net
Sun Aug 22 02:02:45 PDT 2010


On big endian systems, PrepareAccess will fail when byte-swapping is required
so UploadToScreen and DownloadFromScreen cannot rely on fallback to
PrepareAccess.

When scratch BO space allocation fails, this patch merely adds simple fallback
to direct CPU access without any GPU blit.  This sometimes requires a CS flush
even in UploadToScreen.  (No allocation retry after a flush is added here.)
---
 src/radeon_exa_funcs.c |  120 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index d02c787..8c9a874 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -459,7 +459,8 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
     ScreenPtr pScreen = pDst->drawable.pScreen;
     RINFO_FROM_SCREEN(pScreen);
     struct radeon_exa_pixmap_priv *driver_priv;
-    struct radeon_bo *scratch;
+    struct radeon_bo *scratch = NULL;
+    struct radeon_bo *copy_dst;
     unsigned char *dst;
     unsigned size;
     uint32_t datatype = 0;
@@ -467,7 +468,12 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
     uint32_t dst_pitch_offset;
     unsigned bpp = pDst->drawable.bitsPerPixel;
     uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64);
+    uint32_t copy_pitch;
     uint32_t swap = RADEON_HOST_DATA_SWAP_NONE;
+    int ret;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+    Bool flush = TRUE;
+#endif
     Bool r;
     int i;
 
@@ -490,54 +496,78 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
 #endif
 
     /* If we know the BO won't be busy, don't bother */
-    if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs) &&
-	!radeon_bo_is_busy(driver_priv->bo, &dst_domain)) {
 #if X_BYTE_ORDER == X_BIG_ENDIAN
-	/* Can't return FALSE here if we need to swap bytes */
-	if (swap != RADEON_HOST_DATA_SWAP_NONE &&
-	    driver_priv->bo != info->front_bo) {
-	    scratch = driver_priv->bo;
-	    scratch_pitch = pDst->devKind;
-	    goto copy;
-	}
+    copy_dst = driver_priv->bo;
+    copy_pitch = pSrc->devKind;
 #endif
-	return FALSE;
+    if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	flush = FALSE;
+#endif
+	if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain)) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	    /* Can't return FALSE here if we need to swap bytes */
+	    if (swap != RADEON_HOST_DATA_SWAP_NONE &&
+		driver_priv->bo != info->front_bo) {
+		goto copy;
+	    }
+#endif
+	    return FALSE;
+	}
     }
 
     size = scratch_pitch * h;
     scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
     if (scratch == NULL) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	if (swap != RADEON_HOST_DATA_SWAP_NONE &&
+	    driver_priv->bo != info->front_bo) {
+	    goto copy;
+	}
+#endif
 	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) {
+    ret = radeon_cs_space_check(info->cs);
+    if (ret) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	if (swap != RADEON_HOST_DATA_SWAP_NONE &&
+	    driver_priv->bo != info->front_bo) {
+	    goto copy;
+	}
+#endif
         r = FALSE;
         goto out;
     }
-
+    copy_dst = scratch;
+    copy_pitch = scratch_pitch;
 #if X_BYTE_ORDER == X_BIG_ENDIAN
+    flush = FALSE;
+
 copy:
+    if (flush)
+	radeon_cs_flush_indirect(pScrn);
 #endif
-    r = radeon_bo_map(scratch, 0);
-    if (r) {
+
+    ret = radeon_bo_map(copy_dst, 0);
+    if (ret) {
         r = FALSE;
         goto out;
     }
     r = TRUE;
     size = w * bpp / 8;
-    dst = scratch->ptr;
-    if (scratch == driver_priv->bo)
-	dst += y * scratch_pitch + x * bpp / 8;
+    dst = copy_dst->ptr;
+    if (copy_dst == driver_priv->bo)
+	dst += y * copy_pitch + x * bpp / 8;
     for (i = 0; i < h; i++) {
-        RADEONCopySwap(dst + i * scratch_pitch, (uint8_t*)src, size, swap);
+        RADEONCopySwap(dst + i * copy_pitch, (uint8_t*)src, size, swap);
         src += src_pitch;
     }
-    radeon_bo_unmap(scratch);
+    radeon_bo_unmap(copy_dst);
 
-    if (scratch != driver_priv->bo) {
+    if (copy_dst == scratch) {
 	RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype);
 	RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset);
 	ACCEL_PREAMBLE();
@@ -548,7 +578,7 @@ copy:
     }
 
 out:
-    if (scratch != driver_priv->bo)
+    if (scratch)
 	radeon_bo_unref(scratch);
     return r;
 }
@@ -559,14 +589,17 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
 {
     RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
     struct radeon_exa_pixmap_priv *driver_priv;
-    struct radeon_bo *scratch;
+    struct radeon_bo *scratch = NULL;
+    struct radeon_bo *copy_src;
     unsigned size;
     uint32_t datatype = 0;
     uint32_t src_domain = 0;
     uint32_t src_pitch_offset;
     unsigned bpp = pSrc->drawable.bitsPerPixel;
     uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64);
+    uint32_t copy_pitch;
     uint32_t swap = RADEON_HOST_DATA_SWAP_NONE;
+    int ret;
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     Bool flush = FALSE;
 #endif
@@ -591,6 +624,10 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
 #endif
 
     /* If we know the BO won't end up in VRAM anyway, don't bother */
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+    copy_src = driver_priv->bo;
+    copy_pitch = pSrc->devKind;
+#endif
     if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
 	src_domain = radeon_bo_get_src_domain(driver_priv->bo);
 	if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
@@ -609,8 +646,6 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	/* Can't return FALSE here if we need to swap bytes */
 	if (swap != RADEON_HOST_DATA_SWAP_NONE) {
-	    scratch = driver_priv->bo;
-	    scratch_pitch = pSrc->devKind;
 	    goto copy;
 	}
 #endif
@@ -620,13 +655,23 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
     size = scratch_pitch * h;
     scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
     if (scratch == NULL) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	if (swap != RADEON_HOST_DATA_SWAP_NONE) {
+	    goto copy;
+	}
+#endif
 	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) {
+    ret = radeon_cs_space_check(info->cs);
+    if (ret) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	if (swap != RADEON_HOST_DATA_SWAP_NONE) {
+	    goto copy;
+	}
+#endif
         r = FALSE;
         goto out;
     }
@@ -638,6 +683,8 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
                     scratch_pitch << 16, x, y, 0, 0, w, h,
                     RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT,
                     RADEON_GEM_DOMAIN_GTT);
+    copy_src = scratch;
+    copy_pitch = scratch_pitch;
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     flush = TRUE;
 
@@ -646,25 +693,26 @@ copy:
 #endif
 	FLUSH_RING();
 
-    r = radeon_bo_map(scratch, 0);
-    if (r) {
+    ret = radeon_bo_map(copy_src, 0);
+    if (ret) {
+	ErrorF("failed to map pixmap: %d\n", ret);
         r = FALSE;
         goto out;
     }
     r = TRUE;
     w *= bpp / 8;
-    if (scratch == driver_priv->bo)
-	size = y * scratch_pitch + x * bpp / 8;
+    if (copy_src == driver_priv->bo)
+	size = y * copy_pitch + x * bpp / 8;
     else
 	size = 0;
     while (h--) {
-        RADEONCopySwap((uint8_t*)dst, scratch->ptr + size, w, swap);
-        size += scratch_pitch;
+        RADEONCopySwap((uint8_t*)dst, copy_src->ptr + size, w, swap);
+        size += copy_pitch;
         dst += dst_pitch;
     }
-    radeon_bo_unmap(scratch);
+    radeon_bo_unmap(copy_src);
 out:
-    if (scratch != driver_priv->bo)
+    if (scratch)
 	radeon_bo_unref(scratch);
     return r;
 }
-- 
1.7.1



More information about the xorg-driver-ati mailing list