<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Mar 10, 2018 at 10:18 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is based heavily on 97f10934edf8ac, "ac/nir: Add vote_ieq/vote_feq<br>
lowering pass." from Bas Nieuwenhuizen. This version is a bit more<br>
general since it's in common code. It also properly handles NaN due to<br>
not flipping the comparison for floats.<br>
---<br>
src/compiler/nir/nir.h | 1 +<br>
src/compiler/nir/nir_lower_<wbr>subgroups.c | 48 ++++++++++++++++++++++++++++++<wbr>++++<br>
2 files changed, 49 insertions(+)<br>
<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index 5b28c72..40b1028 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -2557,6 +2557,7 @@ typedef struct nir_lower_subgroups_options {<br>
uint8_t ballot_bit_size;<br>
bool lower_to_scalar:1;<br>
bool lower_vote_trivial:1;<br>
+ bool lower_vote_eq_to_ballot:1;<br>
bool lower_subgroup_masks:1;<br>
bool lower_shuffle:1;<br>
bool lower_quad:1;<br>
diff --git a/src/compiler/nir/nir_lower_<wbr>subgroups.c b/src/compiler/nir/nir_lower_<wbr>subgroups.c<br>
index f18ad00..e633ffe 100644<br>
--- a/src/compiler/nir/nir_lower_<wbr>subgroups.c<br>
+++ b/src/compiler/nir/nir_lower_<wbr>subgroups.c<br>
@@ -142,6 +142,51 @@ lower_vote_eq_to_scalar(nir_<wbr>builder *b, nir_intrinsic_instr *intrin)<br>
}<br>
<br>
static nir_ssa_def *<br>
+lower_vote_eq_to_ballot(nir_<wbr>builder *b, nir_intrinsic_instr *intrin,<br>
+ const nir_lower_subgroups_options *options)<br>
+{<br>
+ assert(intrin->src[0].is_ssa);<br>
+ nir_ssa_def *value = intrin->src[0].ssa;<br>
+<br>
+ /* We have to implicitly lower to scalar */<br>
+ nir_ssa_def *all_eq = NULL;<br>
+ for (unsigned i = 0; i < intrin->num_components; i++) {<br>
+ nir_intrinsic_instr *rfi =<br>
+ nir_intrinsic_instr_create(b-><wbr>shader,<br>
+ nir_intrinsic_read_first_<wbr>invocation);<br>
+ nir_ssa_dest_init(&rfi->instr, &rfi->dest,<br>
+ 1, intrin->dest.ssa.bit_size, NULL);<br>
+ rfi->num_components = intrin->dest.ssa.num_<wbr>components;<br></blockquote><div><br></div><div>This should be 1 component. copy+paste and/or rebase fail. Fixed locally.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ rfi->src[0] = nir_src_for_ssa(nir_channel(b, value, i));<br>
+ nir_builder_instr_insert(b, &rfi->instr);<br>
+<br>
+ nir_ssa_def *is_eq;<br>
+ if (intrin->intrinsic == nir_intrinsic_vote_feq) {<br>
+ is_eq = nir_feq(b, &rfi->dest.ssa, intrin->src[0].ssa);<br>
+ } else {<br>
+ is_eq = nir_ieq(b, &rfi->dest.ssa, intrin->src[0].ssa);<br>
+ }<br>
+<br>
+ if (all_eq == NULL) {<br>
+ all_eq = is_eq;<br>
+ } else {<br>
+ all_eq = nir_iand(b, all_eq, is_eq);<br>
+ }<br>
+ }<br>
+<br>
+ nir_intrinsic_instr *ballot =<br>
+ nir_intrinsic_instr_create(b-><wbr>shader, nir_intrinsic_ballot);<br>
+ nir_ssa_dest_init(&ballot-><wbr>instr, &ballot->dest,<br>
+ 1, options->ballot_bit_size, NULL);<br>
+ ballot->num_components = 1;<br>
+ ballot->src[0] = nir_src_for_ssa(nir_inot(b, all_eq));<br>
+ nir_builder_instr_insert(b, &ballot->instr);<br>
+<br>
+ return nir_ieq(b, &ballot->dest.ssa,<br>
+ nir_imm_intN_t(b, 0, options->ballot_bit_size));<br>
+}<br>
+<br>
+static nir_ssa_def *<br>
lower_shuffle(nir_builder *b, nir_intrinsic_instr *intrin,<br>
bool lower_to_scalar)<br>
{<br>
@@ -219,6 +264,9 @@ lower_subgroups_intrin(nir_<wbr>builder *b, nir_intrinsic_instr *intrin,<br>
if (options->lower_vote_trivial)<br>
return nir_imm_int(b, NIR_TRUE);<br>
<br>
+ if (options->lower_vote_eq_to_<wbr>ballot)<br>
+ return lower_vote_eq_to_ballot(b, intrin, options);<br>
+<br>
if (options->lower_to_scalar && intrin->num_components > 1)<br>
return lower_vote_eq_to_scalar(b, intrin);<br>
break;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div></div>