From dfef775c8adba850f97cd24522cbdb5131a8c307 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 29 May 2020 16:19:06 -0700 Subject: [PATCH] iris: Make sure a bound resource is flushed after iris_dirty_for_history. This is the last step before we can start removing the history flush mechanism: In cases where a dirtied buffer has the potential to be concurrently bound to the pipeline (as indicated by the bind_history mask), flag the "flush" dirty bits corresponding to its binding point. This ensures that the buffer-local memory barriers introduced earlier in this series are executed before the next draw call, which in turn will emit any necessary PIPE_CONTROLs in cases where the buffer is bound through a cache incoherent with the cache that performed the write. Reviewed-by: Kenneth Graunke Part-of: --- src/gallium/drivers/iris/iris_context.h | 1 + src/gallium/drivers/iris/iris_resource.c | 30 ++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 4418ad02649..d45c49c5ae0 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -154,6 +154,7 @@ enum { #define IRIS_STAGE_DIRTY_CONSTANTS_GS (1ull << 21) #define IRIS_STAGE_DIRTY_CONSTANTS_FS (1ull << 22) #define IRIS_STAGE_DIRTY_CONSTANTS_CS (1ull << 23) +#define IRIS_SHIFT_FOR_STAGE_DIRTY_BINDINGS 24 #define IRIS_STAGE_DIRTY_BINDINGS_VS (1ull << 24) #define IRIS_STAGE_DIRTY_BINDINGS_TCS (1ull << 25) #define IRIS_STAGE_DIRTY_BINDINGS_TES (1ull << 26) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 56c5f4c19ea..12140ac06f4 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -2324,13 +2324,39 @@ void iris_dirty_for_history(struct iris_context *ice, struct iris_resource *res) { + const uint64_t stages = res->bind_stages; + uint64_t dirty = 0ull; uint64_t stage_dirty = 0ull; if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) { - stage_dirty |= ((uint64_t)res->bind_stages) - << IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS; + for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { + if (stages & (1u << stage)) { + struct iris_shader_state *shs = &ice->state.shaders[stage]; + shs->dirty_cbufs |= ~0u; + } + } + dirty |= IRIS_DIRTY_RENDER_MISC_BUFFER_FLUSHES | + IRIS_DIRTY_COMPUTE_MISC_BUFFER_FLUSHES; + stage_dirty |= (stages << IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS); } + if (res->bind_history & (PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_SHADER_IMAGE)) { + dirty |= IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES | + IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES; + stage_dirty |= (stages << IRIS_SHIFT_FOR_STAGE_DIRTY_BINDINGS); + } + + if (res->bind_history & PIPE_BIND_SHADER_BUFFER) { + dirty |= IRIS_DIRTY_RENDER_MISC_BUFFER_FLUSHES | + IRIS_DIRTY_COMPUTE_MISC_BUFFER_FLUSHES; + stage_dirty |= (stages << IRIS_SHIFT_FOR_STAGE_DIRTY_BINDINGS); + } + + if (res->bind_history & PIPE_BIND_VERTEX_BUFFER) + dirty |= IRIS_DIRTY_VERTEX_BUFFER_FLUSHES; + + ice->state.dirty |= dirty; ice->state.stage_dirty |= stage_dirty; }