st/glsl_to_nir: update state var locations earlier

We need to update the state var locations before the
st_serialize_base_nir() calls otherwise
_mesa_optimize_state_parameters() can alter params such that
variants wont be able to find the correct match when calling
_mesa_lookup_state_param_idx().

Prior to 891d46f5 this worked because after failing to match
we would end up adding additional params back in that we had
just attempted to optimise.

Fixes: a6fcc2835e ("
st/glsl_to_nir: make sure the variant has the correct locations set")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14837

Acked-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
(cherry picked from commit 6c60f423b3)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40359>
This commit is contained in:
Timothy Arceri 2026-02-27 17:43:35 +11:00 committed by Eric Engestrom
parent 0edb7039cb
commit 681de5a641
4 changed files with 28 additions and 13 deletions

View file

@ -4804,7 +4804,7 @@
"description": "st/glsl_to_nir: update state var locations earlier",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "a6fcc2835ead0282c2bb6c29e0eed3711b2ec6d1",
"notes": null

View file

@ -112,6 +112,25 @@ st_nir_lookup_parameter_index(struct gl_program *prog, nir_variable *var)
return -1;
}
void
st_update_state_param_locations(struct gl_context *ctx,
struct gl_program *prog, nir_shader *nir)
{
nir_foreach_variable_with_modes(uniform, nir, nir_var_uniform) {
if (uniform->state_slots) {
const gl_state_index16 *const stateTokens = uniform->state_slots[0].tokens;
int loc = _mesa_lookup_state_param_idx(prog->Parameters, stateTokens);
assert(loc >= 0);
if (ctx->Const.PackedDriverUniformStorage) {
uniform->data.driver_location =
prog->Parameters->Parameters[loc].ValueOffset;
} else
uniform->data.driver_location = loc;
}
}
}
static void
st_nir_assign_uniform_locations(struct st_context *st,
struct gl_program *prog,
@ -135,18 +154,7 @@ st_nir_assign_uniform_locations(struct st_context *st,
imageidx += type_size(uniform->type);
}
} else if (uniform->state_slots) {
const gl_state_index16 *const stateTokens = uniform->state_slots[0].tokens;
/* Make sure the variant has the correct locations set */
loc = _mesa_lookup_state_param_idx(prog->Parameters, stateTokens);
if (loc >= 0) {
if (ctx->Const.PackedDriverUniformStorage) {
uniform->data.driver_location =
prog->Parameters->Parameters[loc].ValueOffset;
} else
uniform->data.driver_location = loc;
}
/* State vars should have been handled already */
continue;
} else {
loc = st_nir_lookup_parameter_index(prog, uniform);
@ -358,6 +366,7 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog,
st_set_prog_affected_state_flags(prog);
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
st_update_state_param_locations(st->ctx, prog, nir);
if (st->allow_st_finalize_nir_twice) {
st_serialize_base_nir(prog, nir);

View file

@ -74,6 +74,10 @@ void st_finalize_nir(struct st_context *st, struct gl_program *prog,
struct nir_shader *nir, bool is_before_variants,
bool is_draw_shader);
void st_update_state_param_locations(struct gl_context *ctx,
struct gl_program *prog,
struct nir_shader *nir);
void st_nir_lower_samplers(struct pipe_screen *screen, struct nir_shader *nir,
struct gl_shader_program *shader_program,
struct gl_program *prog);

View file

@ -395,6 +395,8 @@ st_prog_to_nir_postprocess(struct st_context *st, nir_shader *nir,
/* This must be done after optimizations to assign IO bases. */
nir_recompute_io_bases(nir, nir_var_shader_in | nir_var_shader_out);
st_update_state_param_locations(st->ctx, prog, nir);
if (st->allow_st_finalize_nir_twice) {
st_serialize_base_nir(prog, nir);
st_finalize_nir(st, prog, NULL, nir, true, false);