Module: Mesa
Branch: master
Commit: 2e1266d1fe9ef7ba152a86ef1dfa2bb3a8b61b94
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=2e1266d1fe9ef7ba152a86ef1dfa2bb3a8b61b94

Author: Dave Airlie <[email protected]>
Date:   Fri Mar 19 12:01:41 2021 +1000

gallivm: add subgroup elect intrinsic support.

Reviewed-by: Roland Scheidegger <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9645>

---

 src/gallium/auxiliary/gallivm/lp_bld_nir.c     |  3 +++
 src/gallium/auxiliary/gallivm/lp_bld_nir.h     |  1 +
 src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c | 37 ++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c 
b/src/gallium/auxiliary/gallivm/lp_bld_nir.c
index c49a37cfadf..d41be6ba0fc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c
@@ -1786,6 +1786,9 @@ static void visit_intrinsic(struct lp_build_nir_context 
*bld_base,
    case nir_intrinsic_vote_feq:
       bld_base->vote(bld_base, cast_type(bld_base, get_src(bld_base, 
instr->src[0]), nir_type_int, nir_src_bit_size(instr->src[0])), instr, result);
       break;
+   case nir_intrinsic_elect:
+      bld_base->elect(bld_base, result);
+      break;
    case nir_intrinsic_interp_deref_at_offset:
    case nir_intrinsic_interp_deref_at_centroid:
    case nir_intrinsic_interp_deref_at_sample:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.h 
b/src/gallium/auxiliary/gallivm/lp_bld_nir.h
index 9de1ccbd16f..e396db71eb8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_nir.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.h
@@ -185,6 +185,7 @@ struct lp_build_nir_context
    void (*end_primitive)(struct lp_build_nir_context *bld_base, uint32_t 
stream_id);
 
    void (*vote)(struct lp_build_nir_context *bld_base, LLVMValueRef src, 
nir_intrinsic_instr *instr, LLVMValueRef dst[4]);
+   void (*elect)(struct lp_build_nir_context *bld_base, LLVMValueRef dst[4]);
    void (*helper_invocation)(struct lp_build_nir_context *bld_base, 
LLVMValueRef *dst);
 
    void (*interp_at)(struct lp_build_nir_context *bld_base,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c 
b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
index 4847f5c49b0..6c122fc18ba 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
@@ -1884,6 +1884,42 @@ static void emit_vote(struct lp_build_nir_context 
*bld_base, LLVMValueRef src,
    result[0] = lp_build_broadcast_scalar(&bld_base->uint_bld, 
LLVMBuildLoad(builder, res_store, ""));
 }
 
+static void emit_elect(struct lp_build_nir_context *bld_base, LLVMValueRef 
result[4])
+{
+   struct gallivm_state *gallivm = bld_base->base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef exec_mask = mask_vec(bld_base);
+   struct lp_build_loop_state loop_state;
+
+   LLVMValueRef idx_store = lp_build_alloca(gallivm, 
bld_base->int_bld.elem_type, "");
+   LLVMValueRef found_store = lp_build_alloca(gallivm, 
bld_base->int_bld.elem_type, "");
+   lp_build_loop_begin(&loop_state, gallivm, lp_build_const_int32(gallivm, 0));
+   LLVMValueRef value_ptr = LLVMBuildExtractElement(gallivm->builder, 
exec_mask,
+                                                    loop_state.counter, "");
+   LLVMValueRef cond = LLVMBuildICmp(gallivm->builder,
+                                     LLVMIntEQ,
+                                     value_ptr,
+                                     lp_build_const_int32(gallivm, -1), "");
+   LLVMValueRef cond2 = LLVMBuildICmp(gallivm->builder,
+                                      LLVMIntEQ,
+                                      LLVMBuildLoad(builder, found_store, ""),
+                                      lp_build_const_int32(gallivm, 0), "");
+
+   cond = LLVMBuildAnd(builder, cond, cond2, "");
+   struct lp_build_if_state ifthen;
+   lp_build_if(&ifthen, gallivm, cond);
+   LLVMBuildStore(builder, lp_build_const_int32(gallivm, 1), found_store);
+   LLVMBuildStore(builder, loop_state.counter, idx_store);
+   lp_build_endif(&ifthen);
+   lp_build_loop_end_cond(&loop_state, lp_build_const_int32(gallivm, 
bld_base->uint_bld.type.length),
+                          NULL, LLVMIntUGE);
+
+   result[0] = LLVMBuildInsertElement(builder, bld_base->uint_bld.zero,
+                                      lp_build_const_int32(gallivm, -1),
+                                      LLVMBuildLoad(builder, idx_store, ""),
+                                      "");
+}
+
 static void
 emit_interp_at(struct lp_build_nir_context *bld_base,
                unsigned num_components,
@@ -2129,6 +2165,7 @@ void lp_build_nir_soa(struct gallivm_state *gallivm,
    bld.bld_base.image_op = emit_image_op;
    bld.bld_base.image_size = emit_image_size;
    bld.bld_base.vote = emit_vote;
+   bld.bld_base.elect = emit_elect;
    bld.bld_base.helper_invocation = emit_helper_invocation;
    bld.bld_base.interp_at = emit_interp_at;
    bld.bld_base.load_scratch = emit_load_scratch;

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to