diff --git a/src/compiler/nir/nir_opt_varyings.c b/src/compiler/nir/nir_opt_varyings.c index 18387eb3997..f52efccf87c 100644 --- a/src/compiler/nir/nir_opt_varyings.c +++ b/src/compiler/nir/nir_opt_varyings.c @@ -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. */