From: Kenneth Graunke Date: Tue, 5 May 2020 18:03:12 +0000 (-0700) Subject: nir: Fix divergence analysis for tessellation input/outputs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a5fb31fefbc24a5ad375a26206328e416f4e846;p=mesa.git nir: Fix divergence analysis for tessellation input/outputs The load_per_vertex_{input,output} intrinsics simply mean that they're reading an arrayed input/output, which have one element per invocation. Most accesses to those use gl_InvocationID as the subscript. However, it's totally possible to read any element of the array. For example, an evaluation shader might read gl_in[2].gl_Position, or a control shader might read output[0]. For threads processing a single patch, an input/output load is convergent if and only if both sources (the per-vertex-array subscript and the offset) are convergent. For threads processing multiple patches, we continued to mark them divergent. Reviewed-by: Jason Ekstrand Acked-by: Daniel Schürmann Part-of: --- diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index 6589299cad4..3e2e4b86e20 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -145,6 +145,16 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) else is_divergent = true; break; + case nir_intrinsic_load_per_vertex_input: + is_divergent = instr->src[0].ssa->divergent || + instr->src[1].ssa->divergent; + if (stage == MESA_SHADER_TESS_CTRL) + is_divergent |= !(options & nir_divergence_single_patch_per_tcs_subgroup); + if (stage == MESA_SHADER_TESS_EVAL) + is_divergent |= !(options & nir_divergence_single_patch_per_tes_subgroup); + else + is_divergent = true; + break; case nir_intrinsic_load_input_vertex: is_divergent = instr->src[1].ssa->divergent; assert(stage == MESA_SHADER_FRAGMENT); @@ -158,6 +168,12 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) else is_divergent = true; break; + case nir_intrinsic_load_per_vertex_output: + assert(stage == MESA_SHADER_TESS_CTRL); + is_divergent = instr->src[0].ssa->divergent || + instr->src[1].ssa->divergent || + !(options & nir_divergence_single_patch_per_tcs_subgroup); + break; case nir_intrinsic_load_layer_id: case nir_intrinsic_load_front_face: assert(stage == MESA_SHADER_FRAGMENT); @@ -302,8 +318,6 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) case nir_intrinsic_load_sample_pos: case nir_intrinsic_load_vertex_id_zero_base: case nir_intrinsic_load_vertex_id: - case nir_intrinsic_load_per_vertex_input: - case nir_intrinsic_load_per_vertex_output: case nir_intrinsic_load_instance_id: case nir_intrinsic_load_invocation_id: case nir_intrinsic_load_local_invocation_id: