diff options
Diffstat (limited to 'src/radeon_exa_funcs.c')
-rw-r--r-- | src/radeon_exa_funcs.c | 35 |
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); |