From 70542f5e1e2b255c06e3b92a70cbedecfa711132 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Sun, 22 Aug 2010 22:46:33 +1200 Subject: [PATCH 6/6] 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 --- 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 bf7cb88..c0f9dc9 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 */ -- 1.7.1