summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/nir/nir_lower_subgroups.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_lower_subgroups.c b/src/compiler/nir/nir_lower_subgroups.c
index 3753b5e6427..c97849bf8ba 100644
--- a/src/compiler/nir/nir_lower_subgroups.c
+++ b/src/compiler/nir/nir_lower_subgroups.c
@@ -111,6 +111,32 @@ lower_read_invocation_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
}
static nir_ssa_def *
+lower_vote_eq_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
+{
+ assert(intrin->src[0].is_ssa);
+ nir_ssa_def *value = intrin->src[0].ssa;
+
+ nir_ssa_def *result = NULL;
+ for (unsigned i = 0; i < intrin->num_components; i++) {
+ nir_intrinsic_instr *chan_intrin =
+ nir_intrinsic_instr_create(b->shader, intrin->intrinsic);
+ nir_ssa_dest_init(&chan_intrin->instr, &chan_intrin->dest,
+ 1, intrin->dest.ssa.bit_size, NULL);
+ chan_intrin->num_components = 1;
+ chan_intrin->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
+ nir_builder_instr_insert(b, &chan_intrin->instr);
+
+ if (result) {
+ result = nir_iand(b, result, &chan_intrin->dest.ssa);
+ } else {
+ result = &chan_intrin->dest.ssa;
+ }
+ }
+
+ return result;
+}
+
+static nir_ssa_def *
lower_subgroups_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const nir_lower_subgroups_options *options)
{
@@ -125,6 +151,9 @@ lower_subgroups_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
case nir_intrinsic_vote_ieq:
if (options->lower_vote_trivial)
return nir_imm_int(b, NIR_TRUE);
+
+ if (options->lower_to_scalar && intrin->num_components > 1)
+ return lower_vote_eq_to_scalar(b, intrin);
break;
case nir_intrinsic_load_subgroup_size: