diff options
author | Karl Tomlinson <karlt+@karlt.net> | 2010-08-22 22:46:33 +1200 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2010-09-20 10:13:08 +0200 |
commit | f8fb9312d791af1f77020e8c2d35bb30841ed9aa (patch) | |
tree | c9e8cc4e38ff230b2db3417886f694a4e9cc12a7 /src/radeon_exa.c | |
parent | 35c4ff936601ee083f51510a5192fb97d622a483 (diff) |
RADEONPrepareAccess_CS: fallback to DFS when pixmap is in VRAM
This avoids costly CPU VRAM reads and lets EXA manage a system memory cache
of the portions of pixmaps needed for unaccelerated operations.
https://bugs.freedesktop.org/show_bug.cgi?id=27139
Diffstat (limited to 'src/radeon_exa.c')
-rw-r--r-- | src/radeon_exa.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/src/radeon_exa.c b/src/radeon_exa.c index bf7cb885..c0f9dc9e 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -284,12 +284,21 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); struct radeon_exa_pixmap_priv *driver_priv; + uint32_t possible_domains = ~0U; + uint32_t current_domain = 0; +#ifdef EXA_MIXED_PIXMAPS + Bool can_fail = !(pPix->drawable.bitsPerPixel < 8) && + pPix != pScreen->GetScreenPixmap(pScreen) && + (info->accel_state->exa->flags & EXA_MIXED_PIXMAPS); +#else + Bool can_fail = FALSE; +#endif + Bool flush = FALSE; int ret; #if X_BYTE_ORDER == X_BIG_ENDIAN /* May need to handle byte swapping in DownloadFrom/UploadToScreen */ - if (pPix->drawable.bitsPerPixel > 8 && - pPix != pScreen->GetScreenPixmap(pScreen)) + if (can_fail && pPix->drawable.bitsPerPixel > 8) return FALSE; #endif @@ -298,7 +307,28 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) return FALSE; /* if we have more refs than just the BO then flush */ - if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) + if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { + flush = TRUE; + + if (can_fail) { + possible_domains = radeon_bo_get_src_domain(driver_priv->bo); + if (possible_domains == RADEON_GEM_DOMAIN_VRAM) + return FALSE; /* use DownloadFromScreen */ + } + } + + /* if the BO might end up in VRAM, prefer DownloadFromScreen */ + if (can_fail && (possible_domains & RADEON_GEM_DOMAIN_VRAM)) { + radeon_bo_is_busy(driver_priv->bo, ¤t_domain); + + if (current_domain & possible_domains) { + if (current_domain == RADEON_GEM_DOMAIN_VRAM) + return FALSE; + } else if (possible_domains & RADEON_GEM_DOMAIN_VRAM) + return FALSE; + } + + if (flush) radeon_cs_flush_indirect(pScrn); /* flush IB */ |