[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