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:
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user