From 681de5a6411a120060ace56fb580460c91ab75b6 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Fri, 27 Feb 2026 17:43:35 +1100 Subject: [PATCH] st/glsl_to_nir: update state var locations earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: a6fcc2835ead (" 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 Reviewed-by: Mike Blumenkrantz (cherry picked from commit 6c60f423b38207b06259df0f850ac70e13198e36) Part-of: --- .pick_status.json | 2 +- src/mesa/state_tracker/st_glsl_to_nir.cpp | 33 ++++++++++++++--------- src/mesa/state_tracker/st_nir.h | 4 +++ src/mesa/state_tracker/st_program.c | 2 ++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 5ce31094d8f..cfffdc84512 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 9944cdb3289..4ee17306829 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -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); diff --git a/src/mesa/state_tracker/st_nir.h b/src/mesa/state_tracker/st_nir.h index 927605ae511..21150302e46 100644 --- a/src/mesa/state_tracker/st_nir.h +++ b/src/mesa/state_tracker/st_nir.h @@ -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); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 1ebdd595798..1405fa6206a 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -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);