radeonsi: change do_update_shaders boolean to a bitmask
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29326>
This commit is contained in:
Ganesh Belgur Ramachandra 2025-04-09 12:22:38 +00:00 committed by Marge Bot
parent aecc3fbe50
commit b1a34ac95d
7 changed files with 126 additions and 80 deletions

View file

@ -1211,7 +1211,7 @@ void si_invalidate_inlinable_uniforms(struct si_context *sctx, enum pipe_shader_
sctx->shaders[shader].key.ge.opt.inline_uniforms = false;
memset(inlined_values, 0, MAX_INLINABLE_UNIFORMS * 4);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(shader);
}
}
@ -1265,7 +1265,7 @@ static void si_set_inlinable_constants(struct pipe_context *ctx,
sctx->shaders[shader].key.ge.opt.inline_uniforms = true;
memcpy(inlined_values, values, num_values * 4);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(shader);
return;
}
@ -1274,7 +1274,7 @@ static void si_set_inlinable_constants(struct pipe_context *ctx,
*/
if (memcmp(inlined_values, values, num_values * 4)) {
memcpy(inlined_values, values, num_values * 4);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(shader);
}
}

View file

@ -106,6 +106,8 @@ struct ac_llvm_compiler;
#define SI_RESOURCE_FLAG_32BIT (PIPE_RESOURCE_FLAG_DRV_PRIV << 6)
#define SI_RESOURCE_FLAG_CLEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 7)
#define SI_SQTT_STATE_DIRTY_BIT BITFIELD_BIT(PIPE_SHADER_COMPUTE + 1)
enum si_has_gs {
GS_OFF,
GS_ON,
@ -1084,7 +1086,7 @@ struct si_context {
bool vertex_elements_but_no_buffers;
bool uses_nontrivial_vs_inputs;
bool force_trivial_vs_inputs;
bool do_update_shaders;
uint8_t dirty_shaders_mask; /* 0: vs, 1: tcs, 2: tes, 3: gs, 4: ps, 5: cs, 6: misc (e.g. sqtt) */
bool compute_shaderbuf_sgprs_dirty;
bool compute_image_sgprs_dirty;
bool vs_uses_base_instance;

View file

@ -464,7 +464,7 @@ void si_handle_sqtt(struct si_context *sctx, struct radeon_cmdbuf *rcs)
/* Force shader update to make sure si_sqtt_describe_pipeline_bind is
* called for the current "pipeline".
*/
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= SI_SQTT_STATE_DIRTY_BIT;
}
} else {
struct ac_sqtt_trace sqtt_trace = {0};

View file

@ -1387,8 +1387,12 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
si_vs_ps_key_update_rast_prim_smooth_stipple(sctx);
/* Used by si_get_vs_key_outputs in si_update_shaders: */
if (old_rs->clip_plane_enable != rs->clip_plane_enable)
sctx->do_update_shaders = true;
if (old_rs->clip_plane_enable != rs->clip_plane_enable) {
sctx->dirty_shaders_mask |=
BITFIELD_BIT(PIPE_SHADER_VERTEX) |
BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) |
BITFIELD_BIT(PIPE_SHADER_GEOMETRY);
}
if (old_rs->line_smooth != rs->line_smooth ||
old_rs->poly_smooth != rs->poly_smooth ||
@ -1730,13 +1734,17 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
if (old_dsa->alpha_func != dsa->alpha_func) {
si_ps_key_update_dsa(sctx);
si_update_ps_inputs_read_or_disabled(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |=
BITFIELD_BIT(PIPE_SHADER_VERTEX) |
BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) |
BITFIELD_BIT(PIPE_SHADER_GEOMETRY) |
BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
}
if (old_dsa->depth_enabled != dsa->depth_enabled ||
old_dsa->stencil_enabled != dsa->stencil_enabled) {
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
}
if (sctx->occlusion_query_mode == SI_OCCLUSION_QUERY_MODE_PRECISE_BOOLEAN &&
@ -2769,7 +2777,11 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
si_vs_ps_key_update_rast_prim_smooth_stipple(sctx);
si_update_ps_inputs_read_or_disabled(sctx);
si_update_vrs_flat_shading(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |=
BITFIELD_BIT(PIPE_SHADER_VERTEX) |
BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) |
BITFIELD_BIT(PIPE_SHADER_GEOMETRY) |
BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
if (sctx->gfx_level < GFX12 && !sctx->decompression_enabled) {
/* Prevent textures decompression when the framebuffer state
@ -3611,7 +3623,7 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
sctx->ps_iter_samples = min_samples;
si_ps_key_update_framebuffer_rasterizer_sample_shading(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
si_update_ps_iter_samples(sctx);
}
@ -4650,7 +4662,7 @@ static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
memcmp(old->fix_fetch, v->fix_fetch, sizeof(v->fix_fetch[0]) *
MAX2(old->count, v->count))) {
si_vs_key_update_inputs(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
}
if (v->instance_divisor_is_fetched) {
@ -4730,7 +4742,7 @@ static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
*/
if (sctx->vertex_elements->vb_alignment_check_mask & unaligned) {
si_vs_key_update_inputs(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
}
}

View file

@ -42,6 +42,15 @@
template <amd_gfx_level GFX_VERSION, si_has_tess HAS_TESS, si_has_gs HAS_GS, si_has_ngg NGG>
static bool si_update_shaders(struct si_context *sctx)
{
bool is_vs_state_changed =
(sctx->dirty_shaders_mask & BITFIELD_BIT(PIPE_SHADER_VERTEX)) != 0;
bool is_tess_state_changed =
((sctx->dirty_shaders_mask & (BITFIELD_BIT(PIPE_SHADER_TESS_CTRL) | BITFIELD_BIT(PIPE_SHADER_TESS_EVAL))) != 0);
bool is_gs_state_changed =
(sctx->dirty_shaders_mask & BITFIELD_BIT(PIPE_SHADER_GEOMETRY)) != 0;
bool is_ps_state_changed =
(sctx->dirty_shaders_mask & BITFIELD_BIT(PIPE_SHADER_FRAGMENT)) != 0;
struct pipe_context *ctx = (struct pipe_context *)sctx;
struct si_shader *old_vs = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current;
unsigned old_pa_cl_vs_out_cntl = old_vs ? old_vs->pa_cl_vs_out_cntl : 0;
@ -53,7 +62,7 @@ static bool si_update_shaders(struct si_context *sctx)
int r;
/* Update TCS and TES. */
if (HAS_TESS) {
if (HAS_TESS && is_tess_state_changed) {
if (!sctx->has_tessellation) {
si_init_tess_factor_ring(sctx);
if (!sctx->has_tessellation)
@ -85,7 +94,7 @@ static bool si_update_shaders(struct si_context *sctx)
si_pm4_bind_state(sctx, vs, sctx->shader.tes.current);
}
}
} else {
} else if (!HAS_TESS) {
/* Reset TCS to clear fixed function shader. */
if (!sctx->is_user_tcs && sctx->shader.tcs.cso) {
sctx->shader.tcs.cso = NULL;
@ -101,7 +110,7 @@ static bool si_update_shaders(struct si_context *sctx)
}
/* Update GS. */
if (HAS_GS) {
if (HAS_GS && is_gs_state_changed) {
r = si_shader_select(ctx, &sctx->shader.gs);
if (r)
return false;
@ -115,7 +124,7 @@ static bool si_update_shaders(struct si_context *sctx)
si_pm4_bind_state(sctx, vs, NULL);
sctx->prefetch_L2_mask &= ~SI_PREFETCH_VS;
}
} else {
} else if (!HAS_GS) {
if (!NGG) {
si_pm4_bind_state(sctx, gs, NULL);
sctx->prefetch_L2_mask &= ~SI_PREFETCH_GS;
@ -127,7 +136,7 @@ static bool si_update_shaders(struct si_context *sctx)
}
/* Update VS. */
if ((!HAS_TESS && !HAS_GS) || GFX_VERSION <= GFX8) {
if (is_vs_state_changed && ((!HAS_TESS && !HAS_GS) || GFX_VERSION <= GFX8)) {
r = si_shader_select(ctx, &sctx->shader.vs);
if (r)
return false;
@ -214,8 +223,8 @@ static bool si_update_shaders(struct si_context *sctx)
ge_cntl = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current->ge_cntl;
}
} else {
unsigned primgroup_size;
unsigned vertgroup_size;
unsigned primgroup_size = 128; /* recommended without a GS and tess */
unsigned vertgroup_size = 0;
assert(GFX_VERSION < GFX11);
if (HAS_TESS) {
@ -225,9 +234,6 @@ static bool si_update_shaders(struct si_context *sctx)
unsigned vgt_gs_onchip_cntl = sctx->shader.gs.current->gs.vgt_gs_onchip_cntl;
primgroup_size = G_028A44_GS_PRIMS_PER_SUBGRP(vgt_gs_onchip_cntl);
vertgroup_size = G_028A44_ES_VERTS_PER_SUBGRP(vgt_gs_onchip_cntl);
} else {
primgroup_size = 128; /* recommended without a GS and tess */
vertgroup_size = 0;
}
ge_cntl = S_03096C_PRIM_GRP_SIZE_GFX10(primgroup_size) |
@ -270,6 +276,7 @@ static bool si_update_shaders(struct si_context *sctx)
si_update_ngg_sgpr_state_provoking_vtx(sctx, hw_vs, NGG);
}
if (is_ps_state_changed) {
r = si_shader_select(ctx, &sctx->shader.ps);
if (r)
return false;
@ -289,6 +296,7 @@ static bool si_update_shaders(struct si_context *sctx)
sctx->ps_pa_sc_hisz_control = pa_sc_hisz_control;
si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state);
}
}
if (si_pm4_state_changed(sctx, ps) ||
(!NGG && si_pm4_state_changed(sctx, vs)) ||
@ -297,6 +305,7 @@ static bool si_update_shaders(struct si_context *sctx)
si_mark_atom_dirty(sctx, &sctx->atoms.s.spi_map);
}
if (is_ps_state_changed) {
if ((GFX_VERSION >= GFX10_3 || (GFX_VERSION >= GFX9 && sctx->screen->info.rbplus_allowed)) &&
si_pm4_state_changed(sctx, ps) &&
(!old_ps || old_spi_shader_col_format !=
@ -318,8 +327,9 @@ static bool si_update_shaders(struct si_context *sctx)
if (sctx->framebuffer.nr_samples <= 1)
si_mark_atom_dirty(sctx, &sctx->atoms.s.sample_locations);
}
}
if (HAS_TESS)
if (HAS_TESS && (is_vs_state_changed || is_tess_state_changed))
si_update_tess_io_layout_state(sctx);
if (GFX_VERSION >= GFX9 && unlikely(sctx->sqtt)) {
@ -488,7 +498,7 @@ static bool si_update_shaders(struct si_context *sctx)
if (GFX_VERSION >= GFX10 && NGG)
sctx->ngg_culling = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current->key.ge.opt.ngg_culling;
sctx->do_update_shaders = false;
sctx->dirty_shaders_mask = 0u;
return true;
}
@ -2151,7 +2161,7 @@ static void si_draw(struct pipe_context *ctx,
if (gs_tri_strip_adj_fix != sctx->shader.gs.key.ge.mono.u.gs_tri_strip_adj_fix) {
sctx->shader.gs.key.ge.mono.u.gs_tri_strip_adj_fix = gs_tri_strip_adj_fix;
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_GEOMETRY);
}
}
@ -2281,7 +2291,7 @@ static void si_draw(struct pipe_context *ctx,
/* Update shaders to disable VS input lowering. */
if (sctx->uses_nontrivial_vs_inputs) {
si_vs_key_update_inputs(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
}
}
} else {
@ -2291,7 +2301,7 @@ static void si_draw(struct pipe_context *ctx,
/* Update shaders to possibly enable VS input lowering. */
if (sctx->uses_nontrivial_vs_inputs) {
si_vs_key_update_inputs(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
}
}
}
@ -2300,6 +2310,7 @@ static void si_draw(struct pipe_context *ctx,
uint16_t old_ngg_culling = sctx->ngg_culling;
if (GFX_VERSION >= GFX10) {
struct si_shader_selector *hw_vs = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->cso;
bool needs_shader_update = false;
if (NGG &&
/* Tessellation and GS set ngg_cull_vert_threshold to UINT_MAX if the prim type
@ -2332,15 +2343,21 @@ static void si_draw(struct pipe_context *ctx,
if (ngg_culling != old_ngg_culling) {
/* If shader compilation is not ready, this setting will be rejected. */
sctx->ngg_culling = ngg_culling;
sctx->do_update_shaders = true;
needs_shader_update = true;
}
} else if (old_ngg_culling) {
sctx->ngg_culling = 0;
sctx->do_update_shaders = true;
needs_shader_update = true;
}
if (needs_shader_update) {
sctx->dirty_shaders_mask |=
(HAS_GS ? BITFIELD_BIT(PIPE_SHADER_GEOMETRY) :
(HAS_TESS ? BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) : BITFIELD_BIT(PIPE_SHADER_VERTEX)));
}
}
if (unlikely(sctx->do_update_shaders)) {
if (unlikely(sctx->dirty_shaders_mask)) {
if (unlikely(!(si_update_shaders<GFX_VERSION, HAS_TESS, HAS_GS, NGG>(sctx)))) {
DRAW_CLEANUP;
return;

View file

@ -2467,7 +2467,9 @@ void si_update_ps_inputs_read_or_disabled(struct si_context *sctx)
if (sctx->ps_inputs_read_or_disabled != ps_inputs_read_or_disabled) {
sctx->ps_inputs_read_or_disabled = ps_inputs_read_or_disabled;
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |=
(sctx->shader.gs.cso ? BITFIELD_BIT(PIPE_SHADER_GEOMETRY) :
(sctx->shader.tes.cso ? BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) : BITFIELD_BIT(PIPE_SHADER_VERTEX)));
}
}
@ -2515,13 +2517,19 @@ void si_vs_ps_key_update_rast_prim_smooth_stipple(struct si_context *sctx)
ps_key->ps.opt.force_front_face_input = ps->info.uses_frontface ? rs->force_front_face_input : 0;
}
if (vs_key->ge.opt.kill_pointsize != old_kill_pointsize ||
ps_key->ps.part.prolog.color_two_side != old_color_two_side ||
if (vs_key->ge.opt.kill_pointsize != old_kill_pointsize) {
sctx->dirty_shaders_mask |=
BITFIELD_BIT(PIPE_SHADER_VERTEX) |
BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) |
BITFIELD_BIT(PIPE_SHADER_GEOMETRY);
}
if (ps_key->ps.part.prolog.color_two_side != old_color_two_side ||
ps_key->ps.part.prolog.poly_stipple != old_poly_stipple ||
ps_key->ps.mono.poly_line_smoothing != old_poly_line_smoothing ||
ps_key->ps.mono.point_smoothing != old_point_smoothing ||
ps_key->ps.opt.force_front_face_input != old_force_front_face_input)
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
}
static void si_get_vs_key_outputs(struct si_context *sctx, struct si_shader_selector *vs,
@ -2745,7 +2753,7 @@ void si_ps_key_update_framebuffer_blend_dsa_rasterizer(struct si_context *sctx)
/* Update shaders only if the key changed. */
if (memcmp(&key->ps.part.epilog, &old_epilog, sizeof(old_epilog)) ||
key->ps.opt.prefer_mono != old_prefer_mono) {
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
} else {
assert(memcmp(&key->ps, &old_key, sizeof(old_key)) == 0);
}
@ -2768,7 +2776,7 @@ void si_ps_key_update_rasterizer(struct si_context *sctx)
if (key->ps.part.prolog.flatshade_colors != old_flatshade_colors ||
key->ps.part.epilog.clamp_color != old_clamp_color)
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
}
void si_ps_key_update_dsa(struct si_context *sctx)
@ -2883,7 +2891,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
/* Update shaders only if the key changed. */
if (memcmp(&key->ps.part.prolog, &old_prolog, sizeof(old_prolog)) ||
key->ps.mono.interpolate_at_sample_force_center != old_interpolate_at_sample_force_center)
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
}
/* Compute the key for the hw shader variant */
@ -3792,7 +3800,7 @@ static void si_update_common_shader_state(struct si_context *sctx, struct si_sha
sctx->ngg_culling = 0; /* this will be enabled on the first draw if needed */
si_invalidate_inlinable_uniforms(sctx, type);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(type);
}
static void si_update_last_vgt_stage_state(struct si_context *sctx,
@ -4678,19 +4686,19 @@ static void si_update_tess_in_out_patch_vertices(struct si_context *sctx)
if (sctx->shader.tcs.key.ge.opt.same_patch_vertices != same_patch_vertices) {
sctx->shader.tcs.key.ge.opt.same_patch_vertices = same_patch_vertices;
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_TESS_CTRL);
}
} else {
/* These fields are static for fixed function TCS. So no need to set
* do_update_shaders between fixed-TCS draws. As fixed-TCS to user-TCS
* or opposite, do_update_shaders should already be set by bind state.
* dirty_shaders_mask between fixed-TCS draws. As fixed-TCS to user-TCS
* or opposite, dirty_shaders_mask should already be set by bind state.
*/
sctx->shader.tcs.key.ge.opt.same_patch_vertices = sctx->gfx_level >= GFX9;
/* User may only change patch vertices, needs to update fixed func TCS. */
if (sctx->shader.tcs.cso &&
sctx->shader.tcs.cso->info.base.tess.tcs_vertices_out != sctx->patch_vertices)
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_TESS_CTRL);
}
}
@ -4708,7 +4716,7 @@ static void si_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertic
if (sctx->has_tessellation)
si_update_tess_io_layout_state(sctx);
else
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_TESS_CTRL);
}
/* Gfx12 programs patch_vertices in VGT_PRIMITIVE_TYPE.NUM_INPUT_CP. Make sure
@ -4785,7 +4793,7 @@ void si_update_tess_io_layout_state(struct si_context *sctx)
ls_current = sctx->shader.vs.current;
if (!ls_current) {
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
return;
}
}

View file

@ -225,8 +225,13 @@ static void si_set_streamout_targets(struct pipe_context *ctx, unsigned num_targ
*/
assert(!append_bitmask || enabled_mask == append_bitmask);
if (!!sctx->streamout.enabled_mask != !!enabled_mask)
sctx->do_update_shaders = true; /* to keep/remove streamout shader code as an optimization */
if (!!sctx->streamout.enabled_mask != !!enabled_mask) {
/* to keep/remove streamout shader code as an optimization */
sctx->dirty_shaders_mask |=
BITFIELD_BIT(PIPE_SHADER_VERTEX) |
BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) |
BITFIELD_BIT(PIPE_SHADER_GEOMETRY);
}
sctx->streamout.output_prim = output_prim;
sctx->streamout.num_verts_per_prim = output_prim == MESA_PRIM_UNKNOWN ?
@ -489,7 +494,9 @@ void si_update_prims_generated_query_state(struct si_context *sctx, unsigned typ
if (si_update_ngg(sctx)) {
si_shader_change_notify(sctx);
sctx->do_update_shaders = true;
sctx->dirty_shaders_mask |=
(sctx->shader.gs.cso ? BITFIELD_BIT(PIPE_SHADER_GEOMETRY) :
(sctx->shader.tes.cso ? BITFIELD_BIT(PIPE_SHADER_TESS_EVAL) : BITFIELD_BIT(PIPE_SHADER_VERTEX)));
}
}
}