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 <jason@jlekstrand.net> Acked-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5613>
This commit is contained in:

committed by
Marge Bot

parent
8278a46b26
commit
6a5fb31fef
@@ -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:
|
||||
|
Reference in New Issue
Block a user