If we need to force a cache domain transition (e.g. a buffer was in the CPU domain and we want to access it via WC) then we need to trigger a clflush. This overrides the use of MAP_ASYNC as we call into the kernel to change domains on the whole object.
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Kenneth Graunke <kenn...@whitecape.org> Cc: Matt Turner <matts...@gmail.com> --- src/mesa/drivers/dri/i965/brw_bufmgr.c | 14 ++++++++++---- src/mesa/drivers/dri/i965/brw_bufmgr.h | 10 ++++++++++ src/mesa/drivers/dri/i965/intel_batchbuffer.c | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c index d8a8f92dd7..423f0127d8 100644 --- a/src/mesa/drivers/dri/i965/brw_bufmgr.c +++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c @@ -325,6 +325,7 @@ retry: bo->size = bo_size; bo->idle = true; + bo->cpu = true; memclear(create); create.size = bo_size; @@ -699,9 +700,10 @@ brw_bo_map_cpu(struct brw_context *brw, struct brw_bo *bo, unsigned flags) DBG("brw_bo_map_cpu: %d (%s) -> %p\n", bo->gem_handle, bo->name, bo->map_cpu); - if (!(flags & MAP_ASYNC) || !bufmgr->has_llc) { + if (!(flags & MAP_ASYNC)) { set_domain(brw, "CPU mapping", bo, I915_GEM_DOMAIN_CPU, flags & MAP_WRITE ? I915_GEM_DOMAIN_CPU : 0); + bo->cpu |= flags & MAP_WRITE; } bo_mark_mmaps_incoherent(bo); @@ -753,10 +755,11 @@ brw_bo_map_gtt(struct brw_context *brw, struct brw_bo *bo, unsigned flags) DBG("bo_map_gtt: %d (%s) -> %p\n", bo->gem_handle, bo->name, bo->map_gtt); - if (!(flags & MAP_ASYNC) || !bufmgr->has_llc) { + if (!(flags & MAP_ASYNC) || bo->cpu) { set_domain(brw, "GTT mapping", bo, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); } + bo->cpu = false; bo_mark_mmaps_incoherent(bo); VG(VALGRIND_MAKE_MEM_DEFINED(bo->map_gtt, bo->size)); @@ -774,10 +777,13 @@ can_map_cpu(struct brw_bo *bo, unsigned flags) if (flags & MAP_PERSISTENT) return false; - if (flags & MAP_COHERENT) + if (flags & MAP_COHERENT || bo->external) return false; - return !(flags & MAP_WRITE); + if (bo->cpu) + return true; + + return !(flags & (MAP_WRITE | MAP_ASYNC)); } void * diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h index fedfd999a2..36116af4dd 100644 --- a/src/mesa/drivers/dri/i965/brw_bufmgr.h +++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h @@ -89,6 +89,16 @@ struct brw_bo { */ bool idle; + /** + * Boolean of whether we last wrote to the buffer using the CPU. + * + * On non-llc architectures, moving in and out of the CPU cache requires + * cache-line flushes (clfllush). We need to track when we have to force + * such a transition, and so we track when we last write into the buffer + * using the CPU. + */ + bool cpu; + int refcount; const char *name; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 5fa849c5a5..6e9a42f3c9 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -633,6 +633,7 @@ execbuffer(int fd, struct brw_bo *bo = batch->exec_bos[i]; bo->idle = false; + bo->cpu = false; bo->index = -1; /* Update brw_bo::offset64 */ -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev