freedreno/a6xx: Do tex-state invalidates in same ctx
authorRob Clark <robdclark@chromium.org>
Sat, 11 Feb 2023 15:49:07 +0000 (07:49 -0800)
committerMarge Bot <emma+marge@anholt.net>
Thu, 16 Feb 2023 19:57:13 +0000 (19:57 +0000)
If a resource invalidate is triggered by a different ctx (potentially on
a different thread) simply flag that the tex state needs invalidation,
but defer handling it to the ctx that owns the tex state.

This will let us remove atomic refcnt'ing on the tex state, and more
importantly atomic refcnt'ing on the fd_ringbuffer (as this was the one
special case where rb's could be accessed from multiple threads).

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21274>

src/gallium/drivers/freedreno/a6xx/fd6_context.h
src/gallium/drivers/freedreno/a6xx/fd6_texture.c
src/gallium/drivers/freedreno/a6xx/fd6_texture.h

index 3bfccc8..cb264ca 100644 (file)
@@ -121,6 +121,7 @@ struct fd6_context {
 
    uint16_t tex_seqno;
    struct hash_table *tex_cache;
+   bool tex_cache_needs_invalidate;
 
    /**
     * Descriptor sets for 3d shader stages
index dd5cbf5..8c132bd 100644 (file)
@@ -661,6 +661,31 @@ build_texture_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
    OUT_RING(ring, num_textures);
 }
 
+/**
+ * Handle invalidates potentially coming from other contexts.  By
+ * flagging the invalidate rather than handling it immediately, we
+ * avoid needing to refcnt (with it's associated atomics) the tex
+ * state.  And furthermore, this avoids cross-ctx (thread) sharing
+ * of fd_ringbuffer's, avoiding their need for atomic refcnts.
+ */
+static void
+handle_invalidates(struct fd_context *ctx)
+   assert_dt
+{
+   struct fd6_context *fd6_ctx = fd6_context(ctx);
+
+   fd_screen_assert_locked(ctx->screen);
+
+   hash_table_foreach (fd6_ctx->tex_cache, entry) {
+      struct fd6_texture_state *state = entry->data;
+
+      if (state->invalidate)
+         remove_tex_entry(fd6_ctx, entry);
+   }
+
+   fd6_ctx->tex_cache_needs_invalidate = false;
+}
+
 struct fd6_texture_state *
 fd6_texture_state(struct fd_context *ctx, enum pipe_shader_type type,
                   struct fd_texture_stateobj *tex)
@@ -701,6 +726,10 @@ fd6_texture_state(struct fd_context *ctx, enum pipe_shader_type type,
 
    uint32_t hash = tex_key_hash(&key);
    fd_screen_lock(ctx->screen);
+
+   if (unlikely(fd6_ctx->tex_cache_needs_invalidate))
+      handle_invalidates(ctx);
+
    struct hash_entry *entry =
       _mesa_hash_table_search_pre_hashed(fd6_ctx->tex_cache, hash, &key);
 
@@ -757,8 +786,9 @@ fd6_rebind_resource(struct fd_context *ctx, struct fd_resource *rsc) assert_dt
 
       for (unsigned i = 0; i < ARRAY_SIZE(state->key.view); i++) {
          if (rsc->seqno == state->key.view[i].rsc_seqno) {
-            remove_tex_entry(fd6_ctx, entry);
-            break;
+            struct fd6_texture_state *tex = entry->data;
+            tex->invalidate = true;
+            fd6_ctx->tex_cache_needs_invalidate = true;
          }
       }
    }
index 095fe9b..17d81da 100644 (file)
@@ -131,6 +131,7 @@ struct fd6_texture_state {
    struct pipe_reference reference;
    struct fd6_texture_key key;
    struct fd_ringbuffer *stateobj;
+   bool invalidate;
 };
 
 struct fd6_texture_state *