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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21274>
This commit is contained in:
Rob Clark
2023-02-11 07:49:07 -08:00
committed by Marge Bot
parent e7993d68e2
commit f91bcd2455
3 changed files with 34 additions and 2 deletions
@@ -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
@@ -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;
}
}
}
@@ -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 *