From f91bcd2455973af6c046b18ce32d3636b2482827 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 11 Feb 2023 07:49:07 -0800 Subject: [PATCH] freedreno/a6xx: Do tex-state invalidates in same ctx 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 Part-of: --- .../drivers/freedreno/a6xx/fd6_context.h | 1 + .../drivers/freedreno/a6xx/fd6_texture.c | 34 +++++++++++++++++-- .../drivers/freedreno/a6xx/fd6_texture.h | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.h b/src/gallium/drivers/freedreno/a6xx/fd6_context.h index 3bfccc800f8..cb264ca1c0c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_context.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.h @@ -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 diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index dd5cbf55a17..8c132bda095 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -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; } } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h index 095fe9b1721..17d81da67d9 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h @@ -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 *