summaryrefslogtreecommitdiff
path: root/src/radeon_exa.c
diff options
context:
space:
mode:
authorKarl Tomlinson <karlt+@karlt.net>2010-08-22 22:46:33 +1200
committerMichel Dänzer <michel@daenzer.net>2010-09-20 10:13:08 +0200
commitf8fb9312d791af1f77020e8c2d35bb30841ed9aa (patch)
treec9e8cc4e38ff230b2db3417886f694a4e9cc12a7 /src/radeon_exa.c
parent35c4ff936601ee083f51510a5192fb97d622a483 (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.c36
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, &current_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 */