[Mesa-dev] [PATCH 08/17] nir/spirv: add plumbing for KHR_shader_ballot and KHR_subgroup_vote
Connor Abbott
connora at valvesoftware.com
Fri Jun 9 23:47:29 UTC 2017
From: Connor Abbott <cwabbott0 at gmail.com>
Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
---
src/compiler/spirv/nir_spirv.h | 2 +
src/compiler/spirv/spirv_to_nir.c | 80 ++++++++++++++++++++++++++++++++++++++
src/compiler/spirv/vtn_variables.c | 28 +++++++++++++
3 files changed, 110 insertions(+)
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 7f16866..75fe3a8 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -51,6 +51,8 @@ struct nir_spirv_supported_extensions {
bool image_write_without_format;
bool int64;
bool multiview;
+ bool shader_ballot;
+ bool shader_group_vote;
};
nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 0a5eb0e..a45ddbc 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -2552,6 +2552,69 @@ vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
nir_builder_instr_insert(&b->nb, &intrin->instr);
}
+static void
+vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode,
+ const uint32_t *w, unsigned count)
+{
+ nir_intrinsic_op intrinsic_op;
+ switch (opcode) {
+ case SpvOpSubgroupBallotKHR:
+ intrinsic_op = nir_intrinsic_ballot;
+ break;
+ case SpvOpSubgroupFirstInvocationKHR:
+ intrinsic_op = nir_intrinsic_read_first_invocation;
+ break;
+ case SpvOpSubgroupReadInvocationKHR:
+ intrinsic_op = nir_intrinsic_read_invocation;
+ break;
+ case SpvOpSubgroupAllKHR:
+ intrinsic_op = nir_intrinsic_all_invocations;
+ break;
+ case SpvOpSubgroupAnyKHR:
+ intrinsic_op = nir_intrinsic_any_invocations;
+ break;
+ case SpvOpSubgroupAllEqualKHR:
+ intrinsic_op = nir_intrinsic_all_invocations_equal;
+ break;
+ default:
+ unreachable("unknown subgroup instruction");
+ break;
+ }
+
+ nir_intrinsic_instr *intrin =
+ nir_intrinsic_instr_create(b->shader, intrinsic_op);
+
+ intrin->src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
+
+ if (opcode == SpvOpSubgroupReadInvocationKHR) {
+ intrin->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
+ }
+
+ intrin->num_components = intrin->src[0].ssa->num_components;
+ nir_ssa_dest_init(&intrin->instr, &intrin->dest,
+ intrin->num_components,
+ (opcode == SpvOpSubgroupBallotKHR) ? 64 : 32,
+ NULL);
+ nir_builder_instr_insert(&b->nb, &intrin->instr);
+
+ nir_ssa_def *result = &intrin->dest.ssa;
+
+ if (opcode == SpvOpSubgroupBallotKHR) {
+ /* convert from 64-bit to 4 32-bit components */
+ nir_ssa_def *tmp = nir_unpack_64_2x32(&b->nb, result);
+ nir_ssa_def *zero = nir_imm_int(&b->nb, 0);
+ result = nir_vec4(&b->nb, nir_channel(&b->nb, tmp, 0),
+ nir_channel(&b->nb, tmp, 1),
+ zero, zero);
+ }
+
+ struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+ const struct glsl_type *result_type =
+ vtn_value(b, w[1], vtn_value_type_type)->type->type;
+ val->ssa = vtn_create_ssa_value(b, result_type);
+ val->ssa->def = result;
+}
+
static unsigned
gl_primitive_from_spv_execution_mode(SpvExecutionMode mode)
{
@@ -2734,6 +2797,14 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
spv_check_supported(multiview, cap);
break;
+ case SpvCapabilitySubgroupBallotKHR:
+ spv_check_supported(shader_ballot, cap);
+ break;
+
+ case SpvCapabilitySubgroupVoteKHR:
+ spv_check_supported(shader_ballot, cap);
+ break;
+
default:
unreachable("Unhandled capability");
}
@@ -3238,6 +3309,15 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
vtn_handle_barrier(b, opcode, w, count);
break;
+ case SpvOpSubgroupBallotKHR:
+ case SpvOpSubgroupFirstInvocationKHR:
+ case SpvOpSubgroupReadInvocationKHR:
+ case SpvOpSubgroupAllKHR:
+ case SpvOpSubgroupAnyKHR:
+ case SpvOpSubgroupAllEqualKHR:
+ vtn_handle_subgroup(b, opcode, w, count);
+ break;
+
default:
unreachable("Unhandled opcode");
}
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 0f0cc1c..b62bf70 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -1040,6 +1040,34 @@ vtn_get_builtin_location(struct vtn_builder *b,
*location = SYSTEM_VALUE_VIEW_INDEX;
set_mode_system_value(mode);
break;
+ case SpvBuiltInSubgroupSize:
+ *location = SYSTEM_VALUE_SUBGROUP_SIZE;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupLocalInvocationId:
+ *location = SYSTEM_VALUE_SUBGROUP_INVOCATION;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupEqMaskKHR:
+ *location = SYSTEM_VALUE_SUBGROUP_EQ_MASK_32BIT;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupGeMaskKHR:
+ *location = SYSTEM_VALUE_SUBGROUP_GE_MASK_32BIT;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupGtMaskKHR:
+ *location = SYSTEM_VALUE_SUBGROUP_GT_MASK_32BIT;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupLeMaskKHR:
+ *location = SYSTEM_VALUE_SUBGROUP_LE_MASK_32BIT;
+ set_mode_system_value(mode);
+ break;
+ case SpvBuiltInSubgroupLtMaskKHR:
+ *location = SYSTEM_VALUE_SUBGROUP_LT_MASK_32BIT;
+ set_mode_system_value(mode);
+ break;
case SpvBuiltInHelperInvocation:
default:
unreachable("unsupported builtin");
--
2.9.4
More information about the mesa-dev
mailing list