iris: Make sure a bound resource is flushed after iris_dirty_for_history.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 29 May 2020 23:19:06 +0000 (16:19 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 2 Sep 2021 03:14:37 +0000 (03:14 +0000)
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 <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12691>

src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_resource.c

index 4418ad0..d45c49c 100644 (file)
@@ -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)
index 56c5f4c..12140ac 100644 (file)
@@ -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;
 }