summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2021-03-19 12:01:41 +1000
committerMarge Bot <eric+marge@anholt.net>2021-04-07 19:56:17 +0000
commit2e1266d1fe9ef7ba152a86ef1dfa2bb3a8b61b94 (patch)
tree8da5b28c517b7561102c4dd4abb74c8357f66739
parent52415cd39ee19a6db060cabe79f5adb759d3e070 (diff)
gallivm: add subgroup elect intrinsic support.
Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9645>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_nir.c3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_nir.h1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c37
3 files changed, 41 insertions, 0 deletions
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;