[Mesa-dev] [PATCH 2/2] i965: Track initial CPU domain for mappings

Chris Wilson chris at chris-wilson.co.uk
Tue Jun 20 10:39:23 UTC 2017


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 <chris at chris-wilson.co.uk>
Cc: Kenneth Graunke <kenneth at whitecape.org>
Cc: Matt Turner <mattst88 at 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



More information about the mesa-dev mailing list