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.
v2: ASYNC cpu mmapings (on !llc) are not permitted 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 | 19 +++++++++++++++++-- src/mesa/drivers/dri/i965/brw_bufmgr.h | 10 ++++++++++ src/mesa/drivers/dri/i965/intel_batchbuffer.c | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c index 819408c180..265c9ea3fa 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; @@ -678,9 +679,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; } return bo->map_cpu; @@ -724,10 +726,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; return bo->map_gtt; } @@ -751,6 +754,18 @@ can_map_cpu(struct brw_bo *bo, unsigned flags) if (flags & (MAP_PERSISTENT | MAP_COHERENT | MAP_ASYNC)) return false; + /* As we are sharing this buffer with another process, we cannot rely on our + * own state tracking and so must force coherent mmap access. + */ + if (bo->external) + return false; + + /* We last wrote to the buffer via the CPU mmap, so it should be safe to + * continue accessing it via the same CPU mmap. + */ + if (bo->cpu) + return true; + return !(flags & MAP_WRITE); } diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h index 487f37935a..6eba1584c3 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