summaryrefslogtreecommitdiffstats
path: root/src/amd/common
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2018-01-21 15:06:10 +0100
committerBas Nieuwenhuizen <[email protected]>2018-03-07 21:18:35 +0100
commit8f9af587a2dd33580145779275203334d3acdc21 (patch)
tree44beb7d17db154c1f4a6c778effadad8f4b2bfa7 /src/amd/common
parent89651fba9bf95c4b1397aaf6cc24c062f44a83f2 (diff)
radv: Add minimal subgroup support.
Deliberately not implementing workgroup scopes as that is not needed for core vulkan. Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/common')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c49
-rw-r--r--src/amd/common/ac_shader_info.c2
2 files changed, 51 insertions, 0 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index f6ad51a412a..d02238dba7d 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -3884,6 +3884,46 @@ visit_load_local_invocation_index(struct ac_nir_context *ctx)
}
static LLVMValueRef
+visit_load_subgroup_id(struct ac_nir_context *ctx)
+{
+ if (ctx->stage == MESA_SHADER_COMPUTE) {
+ LLVMValueRef result;
+ result = LLVMBuildAnd(ctx->ac.builder, ctx->abi->tg_size,
+ LLVMConstInt(ctx->ac.i32, 0xfc0, false), "");
+ return LLVMBuildLShr(ctx->ac.builder, result, LLVMConstInt(ctx->ac.i32, 6, false), "");
+ } else {
+ return LLVMConstInt(ctx->ac.i32, 0, false);
+ }
+}
+
+static LLVMValueRef
+visit_load_num_subgroups(struct ac_nir_context *ctx)
+{
+ if (ctx->stage == MESA_SHADER_COMPUTE) {
+ return LLVMBuildAnd(ctx->ac.builder, ctx->abi->tg_size,
+ LLVMConstInt(ctx->ac.i32, 0x3f, false), "");
+ } else {
+ return LLVMConstInt(ctx->ac.i32, 1, false);
+ }
+}
+
+static LLVMValueRef
+visit_first_invocation(struct ac_nir_context *ctx)
+{
+ LLVMValueRef active_set = ac_build_ballot(&ctx->ac, ctx->ac.i32_1);
+
+ /* The second argument is whether cttz(0) should be defined, but we do not care. */
+ LLVMValueRef args[] = {active_set, LLVMConstInt(ctx->ac.i1, 0, false)};
+ LLVMValueRef result = ac_build_intrinsic(&ctx->ac,
+ "llvm.cttz.i64",
+ ctx->ac.i64, args, 2,
+ AC_FUNC_ATTR_NOUNWIND |
+ AC_FUNC_ATTR_READNONE);
+
+ return LLVMBuildTrunc(ctx->ac.builder, result, ctx->ac.i32, "");
+}
+
+static LLVMValueRef
visit_load_shared(struct ac_nir_context *ctx,
const nir_intrinsic_instr *instr)
{
@@ -4411,6 +4451,15 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
case nir_intrinsic_load_local_invocation_index:
result = visit_load_local_invocation_index(ctx);
break;
+ case nir_intrinsic_load_subgroup_id:
+ result = visit_load_subgroup_id(ctx);
+ break;
+ case nir_intrinsic_load_num_subgroups:
+ result = visit_load_num_subgroups(ctx);
+ break;
+ case nir_intrinsic_first_invocation:
+ result = visit_first_invocation(ctx);
+ break;
case nir_intrinsic_load_push_constant:
result = visit_load_push_constant(ctx, instr);
break;
diff --git a/src/amd/common/ac_shader_info.c b/src/amd/common/ac_shader_info.c
index 98de963147b..883358faaae 100644
--- a/src/amd/common/ac_shader_info.c
+++ b/src/amd/common/ac_shader_info.c
@@ -61,6 +61,8 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
break;
}
case nir_intrinsic_load_local_invocation_index:
+ case nir_intrinsic_load_subgroup_id:
+ case nir_intrinsic_load_num_subgroups:
info->cs.uses_local_invocation_idx = true;
break;
case nir_intrinsic_load_sample_id: