[Mesa-dev] [PATCH v2 02/10] i965: Track initial CPU domain for mappings

Chris Wilson chris at chris-wilson.co.uk
Mon Jun 19 10:55:01 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.

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        | 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



More information about the mesa-dev mailing list