nir/opt_varyings: use workgroup divergence to identify convergent mesh outputs

It turns out we do have workgroup divergence, hidden behind
nir_divergence_across_subgroups, if I understand it correctly.

Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41225>
This commit is contained in:
Marek Olšák 2026-04-27 22:12:27 -04:00 committed by Marge Bot
parent edb60c76e2
commit e966c1bdec

View file

@ -1625,17 +1625,13 @@ gather_outputs(struct nir_builder *builder, nir_intrinsic_instr *intr, void *cb_
if (is_store) {
nir_scalar value = nir_scalar_resolved(intr->src[0].ssa, 0);
const bool constant = nir_scalar_is_const(value);
/* If the store instruction is executed in a divergent block, the value
* that's stored in the output becomes divergent.
*
* Mesh shaders get special treatment because we can't follow their topology,
* so we only propagate constants.
* TODO: revisit this when workgroup divergence analysis is merged.
* For all shaders except mesh shaders, "divergent" is vertex divergence.
* For mesh shaders, it's workgroup divergence.
*/
const bool divergent = (!constant && linkage->producer_stage == MESA_SHADER_MESH) ||
intr->instr.block->divergent ||
const bool divergent = intr->instr.block->divergent ||
nir_src_is_divergent(&intr->src[0]);
if (!out->producer.value.def) {
@ -5426,7 +5422,11 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
* divergence information.
*/
if (consumer->info.stage == MESA_SHADER_FRAGMENT) {
nir_custom_divergence_analysis(producer, nir_divergence_vertex);
nir_divergence_options divergence_options =
producer->info.stage == MESA_SHADER_MESH ?
nir_divergence_across_subgroups : nir_divergence_vertex;
nir_custom_divergence_analysis(producer, divergence_options);
}
/* This also removes dead varyings. */