summaryrefslogtreecommitdiff
path: root/src/radeon_exa_funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_exa_funcs.c')
-rw-r--r--src/radeon_exa_funcs.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index e48317f5..f937c4e3 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -507,6 +507,33 @@ out:
}
static Bool
+RADEONDownloadFromScreenGTT(PixmapPtr pSrc, int x, int y, int w,
+ int h, char *dst, int dst_pitch)
+{
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int src_pitch = exaGetPixmapPitch(pSrc);
+ int bpp = pSrc->drawable.bitsPerPixel;
+ int src_offset;
+ int r;
+
+ driver_priv = exaGetPixmapDriverPrivate(pSrc);
+ r = radeon_bo_map(driver_priv->bo, 0);
+ if (r)
+ return FALSE;
+
+ src_offset = (x * bpp / 8) + (y * src_pitch);
+ w *= bpp / 8;
+
+ while (h--) {
+ memcpy(dst, driver_priv->bo->ptr + src_offset, w);
+ src_offset += src_pitch;
+ dst += dst_pitch;
+ }
+ radeon_bo_unmap(driver_priv->bo);
+ return TRUE;
+}
+
+static Bool
RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
int h, char *dst, int dst_pitch)
{
@@ -519,11 +546,19 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
unsigned bpp = pSrc->drawable.bitsPerPixel;
uint32_t scratch_pitch = (w * bpp / 8 + 63) & ~63;
Bool r;
+ uint32_t src_domain;
+ int busy;
if (bpp < 8)
return FALSE;
driver_priv = exaGetPixmapDriverPrivate(pSrc);
+
+ busy = radeon_bo_is_busy(driver_priv->bo, &src_domain);
+
+ if (src_domain == RADEON_GEM_DOMAIN_GTT)
+ return RADEONDownloadFromScreenGTT(pSrc, x, y, w, h,
+ dst, dst_pitch);
size = scratch_pitch * h;
scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);