From fcccc5528b8696fb4f9b3f9f528673b95d98a907 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 May 2012 11:27:44 +0100 Subject: [PATCH] sna: Improve handling of inplace IO for large transfers If the transfer is large enough to obliterate the caches, then it is preferrable to do it inplace rather than upload a proxy texture and queue a blit. This helps prevent an inconsistency where one layer believes the operation should be done inplace only for the IO layer to perform an indirect upload. Testing show no significant impact upon the cairo-traces, but it does prevent x11perf -shmput from exploding. Signed-off-by: Chris Wilson --- src/sna/kgem.h | 2 +- src/sna/sna_io.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 51025eaa..9eac68e9 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -462,7 +462,7 @@ static inline bool kgem_bo_map_will_stall(struct kgem *kgem, struct kgem_bo *bo) __FUNCTION__, bo->handle, bo->domain, bo->presumed_offset, bo->size)); - if (!kgem_bo_is_mappable(kgem, bo)) + if (!kgem_bo_is_mappable(kgem, bo) && kgem_bo_is_busy(bo)) return true; if (kgem->wedged) diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 2539518b..7cec3ff2 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -516,17 +516,16 @@ static bool upload_inplace(struct kgem *kgem, * able to almagamate a series of small writes into a single * operation. */ - if (!bo->map) { + if (!bo->map || kgem_bo_map_will_stall(kgem, bo)) { unsigned int bytes = 0; while (n--) { bytes += (box->x2 - box->x1) * (box->y2 - box->y1); box++; } - if (bytes * bpp >> 12 < kgem->half_cpu_cache_pages) - return false; + return bytes * bpp >> 12 >= kgem->half_cpu_cache_pages; } - return !kgem_bo_map_will_stall(kgem, bo); + return true; } bool sna_write_boxes(struct sna *sna, PixmapPtr dst, @@ -570,7 +569,9 @@ fallback: } /* Try to avoid switching rings... */ - if (!can_blt || kgem->ring == KGEM_RENDER || + if (!can_blt || + kgem->ring == KGEM_RENDER || + (kgem->has_semaphores && kgem->mode == KGEM_NONE) || upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { PixmapRec tmp;