radeonsi: add a si_clear_and_set_barrier_flags helper

Same as si_set_barrier_flags except it can be used to clear
some barriers first.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39308>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2026-01-14 10:57:35 +01:00 committed by Marge Bot
parent db4b1cdb3b
commit 9175388740
4 changed files with 31 additions and 30 deletions

View file

@ -324,6 +324,7 @@ static void si_draw_vstate_tmz_preamble(struct pipe_context *ctx,
void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs)
{
unsigned new_barrier_flags;
bool is_secure = false;
if (!first_cs)
@ -372,16 +373,15 @@ void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs)
*
* TODO: Do we also need to invalidate CB & DB caches?
*/
ctx->barrier_flags |= SI_BARRIER_INV_L2;
new_barrier_flags = SI_BARRIER_INV_L2;
if (ctx->gfx_level < GFX10)
ctx->barrier_flags |= SI_BARRIER_INV_ICACHE | SI_BARRIER_INV_SMEM | SI_BARRIER_INV_VMEM;
new_barrier_flags |= SI_BARRIER_INV_ICACHE | SI_BARRIER_INV_SMEM | SI_BARRIER_INV_VMEM;
/* Disable pipeline stats if there are no active queries. */
ctx->barrier_flags &= ~SI_BARRIER_EVENT_PIPELINESTAT_START & ~SI_BARRIER_EVENT_PIPELINESTAT_STOP;
if (ctx->num_hw_pipestat_streamout_queries)
ctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_START;
new_barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_START;
else
ctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_STOP;
new_barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_STOP;
ctx->pipeline_stats_enabled = -1; /* indicate that the current hw state is unknown */
@ -389,9 +389,11 @@ void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs)
* When switching NGG->legacy, we need to flush VGT for certain hw generations.
*/
if (ctx->screen->info.has_vgt_flush_ngg_legacy_bug && !ctx->ngg)
ctx->barrier_flags |= SI_BARRIER_EVENT_VGT_FLUSH;
new_barrier_flags |= SI_BARRIER_EVENT_VGT_FLUSH;
si_mark_atom_dirty(ctx, &ctx->atoms.s.barrier);
si_clear_and_set_barrier_flags(ctx,
SI_BARRIER_EVENT_PIPELINESTAT_START | SI_BARRIER_EVENT_PIPELINESTAT_STOP,
new_barrier_flags);
si_mark_atom_dirty(ctx, &ctx->atoms.s.spi_ge_ring_state);
if (ctx->screen->attribute_pos_prim_ring && !is_secure) {

View file

@ -1378,6 +1378,12 @@ static inline void si_set_barrier_flags(struct si_context *sctx, unsigned flags)
sctx->barrier_flags |= flags;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
}
static inline void si_clear_and_set_barrier_flags(struct si_context *sctx, unsigned clear, unsigned set)
{
sctx->barrier_flags &= ~clear;
sctx->barrier_flags |= set;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
}
void si_barrier_before_internal_op(struct si_context *sctx, unsigned flags,
unsigned num_buffers,
@ -2263,17 +2269,19 @@ si_set_rasterized_prim(struct si_context *sctx, enum mesa_prim rast_prim,
}
}
/* There are 4 ways to flush caches and all of them are correct.
/* There are 5 ways to flush caches and all of them are correct.
*
* 1) si_set_barrier_flags(sctx, ...); // deferred
*
* 2) sctx->barrier_flags |= ...; // multiple times
* 2) si_clear_and_set_barrier_flags(sctx, ..., ...); // deferred
*
* 3) sctx->barrier_flags |= ...; // multiple times
* si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier); // deferred
*
* 3) sctx->barrier_flags |= ...;
* 4) sctx->barrier_flags |= ...;
* si_emit_barrier_direct(sctx); // immediate
*
* 4) sctx->barrier_flags |= ...;
* 5) sctx->barrier_flags |= ...;
* sctx->emit_barrier(sctx, cs); // immediate (2 is better though)
*/
static inline void si_emit_barrier_direct(struct si_context *sctx)

View file

@ -895,15 +895,12 @@ static void si_update_hw_pipeline_stats(struct si_context *sctx, unsigned type,
sctx->num_hw_pipestat_streamout_queries += diff;
/* Enable/disable pipeline stats if we have any queries. */
if (diff == 1 && sctx->num_hw_pipestat_streamout_queries == 1) {
sctx->barrier_flags &= ~SI_BARRIER_EVENT_PIPELINESTAT_STOP;
sctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_START;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
} else if (diff == -1 && sctx->num_hw_pipestat_streamout_queries == 0) {
sctx->barrier_flags &= ~SI_BARRIER_EVENT_PIPELINESTAT_START;
sctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_STOP;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
}
if (diff == 1 && sctx->num_hw_pipestat_streamout_queries == 1)
si_clear_and_set_barrier_flags(sctx, SI_BARRIER_EVENT_PIPELINESTAT_STOP,
SI_BARRIER_EVENT_PIPELINESTAT_START);
else if (diff == -1 && sctx->num_hw_pipestat_streamout_queries == 0)
si_clear_and_set_barrier_flags(sctx, SI_BARRIER_EVENT_PIPELINESTAT_START,
SI_BARRIER_EVENT_PIPELINESTAT_STOP);
}
}

View file

@ -1679,17 +1679,11 @@ static void si_set_active_query_state(struct pipe_context *ctx, bool enable)
/* Pipeline stat & streamout queries. */
if (enable) {
/* Disable pipeline stats if there are no active queries. */
if (sctx->num_hw_pipestat_streamout_queries) {
sctx->barrier_flags &= ~SI_BARRIER_EVENT_PIPELINESTAT_STOP;
sctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_START;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
}
if (sctx->num_hw_pipestat_streamout_queries)
si_clear_and_set_barrier_flags(sctx, SI_BARRIER_EVENT_PIPELINESTAT_STOP, SI_BARRIER_EVENT_PIPELINESTAT_START);
} else {
if (sctx->num_hw_pipestat_streamout_queries) {
sctx->barrier_flags &= ~SI_BARRIER_EVENT_PIPELINESTAT_START;
sctx->barrier_flags |= SI_BARRIER_EVENT_PIPELINESTAT_STOP;
si_mark_atom_dirty(sctx, &sctx->atoms.s.barrier);
}
if (sctx->num_hw_pipestat_streamout_queries)
si_clear_and_set_barrier_flags(sctx, SI_BARRIER_EVENT_PIPELINESTAT_START, SI_BARRIER_EVENT_PIPELINESTAT_STOP);
}
/* Occlusion queries. */