freedreno/a6xx: Avoid touching long lived stateobj refcnt
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

In particular, sharable shaders can be used from multiple threads/ctxs,
making the non-atomic refcnting unsound.

But we can avoid making the refcnting atomic just for this one specific
case by passing a flag to indicate whether the stateobj should be un-
reffed.

Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40177>
This commit is contained in:
Rob Clark 2026-03-02 09:17:07 -08:00 committed by Marge Bot
parent a95dee6dce
commit b74a07a422

View file

@ -91,7 +91,8 @@ enum fd6_pipeline_type {
struct fd6_state_group {
struct fd_ringbuffer *stateobj;
enum fd6_state_id group_id;
enum fd6_state_id group_id : 7;
bool unref : 1;
/* enable_mask controls which states the stateobj is evaluated in,
* b0 is binning pass b1 and/or b2 is draw pass
*/
@ -125,6 +126,9 @@ fd6_state_emit(struct fd6_state *state, fd_cs &cs)
.dword = g->enable_mask,
));
pkt.add(g->stateobj, 0, NULL);
if (g->unref)
fd_ringbuffer_del(g->stateobj);
} else {
pkt.add(CP_SET_DRAW_STATE__0(i,
.disable = true,
@ -133,9 +137,6 @@ fd6_state_emit(struct fd6_state *state, fd_cs &cs)
));
pkt.add(CP_SET_DRAW_STATE__ADDR(i));
}
if (g->stateobj)
fd_ringbuffer_del(g->stateobj);
}
}
@ -155,21 +156,29 @@ enable_mask(enum fd6_state_id group_id)
}
static inline void
fd6_state_take_group(struct fd6_state *state, struct fd_ringbuffer *stateobj,
enum fd6_state_id group_id)
__append_state_group(struct fd6_state *state, struct fd_ringbuffer *stateobj,
enum fd6_state_id group_id, bool unref)
{
assert(state->num_groups < ARRAY_SIZE(state->groups));
struct fd6_state_group *g = &state->groups[state->num_groups++];
g->stateobj = stateobj;
g->group_id = group_id;
g->unref = unref;
g->enable_mask = enable_mask(group_id);
}
static inline void
fd6_state_take_group(struct fd6_state *state, struct fd_ringbuffer *stateobj,
enum fd6_state_id group_id)
{
__append_state_group(state, stateobj, group_id, true);
}
static inline void
fd6_state_add_group(struct fd6_state *state, struct fd_ringbuffer *stateobj,
enum fd6_state_id group_id)
{
fd6_state_take_group(state, fd_ringbuffer_ref(stateobj), group_id);
__append_state_group(state, stateobj, group_id, false);
}
/* grouped together emit-state for prog/vertex/state emit: */