diff options
Diffstat (limited to 'src/compiler/spirv')
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 31 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_amd.c | 61 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_private.h | 3 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_subgroup.c | 45 |
4 files changed, 133 insertions, 7 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 326f4b0d411..ccd11fa6329 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -394,10 +394,13 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode, if (strcmp(ext, "GLSL.std.450") == 0) { val->ext_handler = vtn_handle_glsl450_instruction; } else if ((strcmp(ext, "SPV_AMD_gcn_shader") == 0) - && (b->options && b->options->caps.gcn_shader)) { + && (b->options && b->options->caps.amd_gcn_shader)) { val->ext_handler = vtn_handle_amd_gcn_shader_instruction; + } else if ((strcmp(ext, "SPV_AMD_shader_ballot") == 0) + && (b->options && b->options->caps.amd_shader_ballot)) { + val->ext_handler = vtn_handle_amd_shader_ballot_instruction; } else if ((strcmp(ext, "SPV_AMD_shader_trinary_minmax") == 0) - && (b->options && b->options->caps.trinary_minmax)) { + && (b->options && b->options->caps.amd_trinary_minmax)) { val->ext_handler = vtn_handle_amd_shader_trinary_minmax_instruction; } else if (strcmp(ext, "OpenCL.std") == 0) { val->ext_handler = vtn_handle_opencl_instruction; @@ -3612,7 +3615,6 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, case SpvCapabilityImageReadWrite: case SpvCapabilityImageMipmap: case SpvCapabilityPipes: - case SpvCapabilityGroups: case SpvCapabilityDeviceEnqueue: case SpvCapabilityLiteralSampler: case SpvCapabilityGenericPointer: @@ -3677,6 +3679,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, spv_check_supported(subgroup_arithmetic, cap); break; + case SpvCapabilityGroups: + spv_check_supported(amd_shader_ballot, cap); + break; + case SpvCapabilityVariablePointersStorageBuffer: case SpvCapabilityVariablePointers: spv_check_supported(variable_pointers, cap); @@ -4525,12 +4531,31 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode, case SpvOpGroupNonUniformLogicalXor: case SpvOpGroupNonUniformQuadBroadcast: case SpvOpGroupNonUniformQuadSwap: + case SpvOpGroupAll: + case SpvOpGroupAny: + case SpvOpGroupBroadcast: + case SpvOpGroupIAdd: + case SpvOpGroupFAdd: + case SpvOpGroupFMin: + case SpvOpGroupUMin: + case SpvOpGroupSMin: + case SpvOpGroupFMax: + case SpvOpGroupUMax: + case SpvOpGroupSMax: case SpvOpSubgroupBallotKHR: case SpvOpSubgroupFirstInvocationKHR: case SpvOpSubgroupReadInvocationKHR: case SpvOpSubgroupAllKHR: case SpvOpSubgroupAnyKHR: case SpvOpSubgroupAllEqualKHR: + case SpvOpGroupIAddNonUniformAMD: + case SpvOpGroupFAddNonUniformAMD: + case SpvOpGroupFMinNonUniformAMD: + case SpvOpGroupUMinNonUniformAMD: + case SpvOpGroupSMinNonUniformAMD: + case SpvOpGroupFMaxNonUniformAMD: + case SpvOpGroupUMaxNonUniformAMD: + case SpvOpGroupSMaxNonUniformAMD: vtn_handle_subgroup(b, opcode, w, count); break; diff --git a/src/compiler/spirv/vtn_amd.c b/src/compiler/spirv/vtn_amd.c index 0d5b429783b..23f8930faa2 100644 --- a/src/compiler/spirv/vtn_amd.c +++ b/src/compiler/spirv/vtn_amd.c @@ -57,6 +57,67 @@ vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode, } bool +vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_opcode, + const uint32_t *w, unsigned count) +{ + const struct glsl_type *dest_type = + vtn_value(b, w[1], vtn_value_type_type)->type->type; + struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); + val->ssa = vtn_create_ssa_value(b, dest_type); + + unsigned num_args; + nir_intrinsic_op op; + switch ((enum ShaderBallotAMD)ext_opcode) { + case SwizzleInvocationsAMD: + num_args = 1; + op = nir_intrinsic_quad_swizzle_amd; + break; + case SwizzleInvocationsMaskedAMD: + num_args = 1; + op = nir_intrinsic_masked_swizzle_amd; + break; + case WriteInvocationAMD: + num_args = 3; + op = nir_intrinsic_write_invocation_amd; + break; + case MbcntAMD: + num_args = 1; + op = nir_intrinsic_mbcnt_amd; + break; + default: + unreachable("Invalid opcode"); + } + + nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->nb.shader, op); + nir_ssa_dest_init_for_type(&intrin->instr, &intrin->dest, dest_type, NULL); + intrin->num_components = intrin->dest.ssa.num_components; + + for (unsigned i = 0; i < num_args; i++) + intrin->src[i] = nir_src_for_ssa(vtn_ssa_value(b, w[i + 5])->def); + + if (intrin->intrinsic == nir_intrinsic_quad_swizzle_amd) { + struct vtn_value *val = vtn_value(b, w[6], vtn_value_type_constant); + unsigned mask = val->constant->values[0][0].u32 | + val->constant->values[0][1].u32 << 2 | + val->constant->values[0][2].u32 << 4 | + val->constant->values[0][3].u32 << 6; + nir_intrinsic_set_swizzle_mask(intrin, mask); + + } else if (intrin->intrinsic == nir_intrinsic_masked_swizzle_amd) { + struct vtn_value *val = vtn_value(b, w[6], vtn_value_type_constant); + unsigned mask = val->constant->values[0][0].u32 | + val->constant->values[0][1].u32 << 5 | + val->constant->values[0][2].u32 << 10; + nir_intrinsic_set_swizzle_mask(intrin, mask); + } + + nir_builder_instr_insert(&b->nb, &intrin->instr); + val->ssa->def = &intrin->dest.ssa; + + return true; +} + +bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode, const uint32_t *w, unsigned count) { diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index c0595709852..1b2be93621f 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -833,6 +833,9 @@ vtn_u64_literal(const uint32_t *w) bool vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode, const uint32_t *words, unsigned count); +bool vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_opcode, + const uint32_t *w, unsigned count); + bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode, const uint32_t *words, unsigned count); #endif /* _VTN_PRIVATE_H_ */ diff --git a/src/compiler/spirv/vtn_subgroup.c b/src/compiler/spirv/vtn_subgroup.c index ce795ec2cb5..8339b1a4862 100644 --- a/src/compiler/spirv/vtn_subgroup.c +++ b/src/compiler/spirv/vtn_subgroup.c @@ -183,7 +183,8 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, val->ssa, vtn_ssa_value(b, w[3]), NULL, 0, 0); break; - case SpvOpGroupNonUniformBroadcast: ++w; + case SpvOpGroupNonUniformBroadcast: + case SpvOpGroupBroadcast: ++w; case SpvOpSubgroupReadInvocationKHR: vtn_build_subgroup_instr(b, nir_intrinsic_read_invocation, val->ssa, vtn_ssa_value(b, w[3]), @@ -193,6 +194,8 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, case SpvOpGroupNonUniformAll: case SpvOpGroupNonUniformAny: case SpvOpGroupNonUniformAllEqual: + case SpvOpGroupAll: + case SpvOpGroupAny: case SpvOpSubgroupAllKHR: case SpvOpSubgroupAnyKHR: case SpvOpSubgroupAllEqualKHR: { @@ -201,10 +204,12 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, nir_intrinsic_op op; switch (opcode) { case SpvOpGroupNonUniformAll: + case SpvOpGroupAll: case SpvOpSubgroupAllKHR: op = nir_intrinsic_vote_all; break; case SpvOpGroupNonUniformAny: + case SpvOpGroupAny: case SpvOpSubgroupAnyKHR: op = nir_intrinsic_vote_any; break; @@ -232,8 +237,8 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, } nir_ssa_def *src0; - if (opcode == SpvOpGroupNonUniformAll || - opcode == SpvOpGroupNonUniformAny || + if (opcode == SpvOpGroupNonUniformAll || opcode == SpvOpGroupAll || + opcode == SpvOpGroupNonUniformAny || opcode == SpvOpGroupAny || opcode == SpvOpGroupNonUniformAllEqual) { src0 = vtn_ssa_value(b, w[4])->def; } else { @@ -319,13 +324,33 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, case SpvOpGroupNonUniformBitwiseXor: case SpvOpGroupNonUniformLogicalAnd: case SpvOpGroupNonUniformLogicalOr: - case SpvOpGroupNonUniformLogicalXor: { + case SpvOpGroupNonUniformLogicalXor: + case SpvOpGroupIAdd: + case SpvOpGroupFAdd: + case SpvOpGroupFMin: + case SpvOpGroupUMin: + case SpvOpGroupSMin: + case SpvOpGroupFMax: + case SpvOpGroupUMax: + case SpvOpGroupSMax: + case SpvOpGroupIAddNonUniformAMD: + case SpvOpGroupFAddNonUniformAMD: + case SpvOpGroupFMinNonUniformAMD: + case SpvOpGroupUMinNonUniformAMD: + case SpvOpGroupSMinNonUniformAMD: + case SpvOpGroupFMaxNonUniformAMD: + case SpvOpGroupUMaxNonUniformAMD: + case SpvOpGroupSMaxNonUniformAMD: { nir_op reduction_op; switch (opcode) { case SpvOpGroupNonUniformIAdd: + case SpvOpGroupIAdd: + case SpvOpGroupIAddNonUniformAMD: reduction_op = nir_op_iadd; break; case SpvOpGroupNonUniformFAdd: + case SpvOpGroupFAdd: + case SpvOpGroupFAddNonUniformAMD: reduction_op = nir_op_fadd; break; case SpvOpGroupNonUniformIMul: @@ -335,21 +360,33 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode, reduction_op = nir_op_fmul; break; case SpvOpGroupNonUniformSMin: + case SpvOpGroupSMin: + case SpvOpGroupSMinNonUniformAMD: reduction_op = nir_op_imin; break; case SpvOpGroupNonUniformUMin: + case SpvOpGroupUMin: + case SpvOpGroupUMinNonUniformAMD: reduction_op = nir_op_umin; break; case SpvOpGroupNonUniformFMin: + case SpvOpGroupFMin: + case SpvOpGroupFMinNonUniformAMD: reduction_op = nir_op_fmin; break; case SpvOpGroupNonUniformSMax: + case SpvOpGroupSMax: + case SpvOpGroupSMaxNonUniformAMD: reduction_op = nir_op_imax; break; case SpvOpGroupNonUniformUMax: + case SpvOpGroupUMax: + case SpvOpGroupUMaxNonUniformAMD: reduction_op = nir_op_umax; break; case SpvOpGroupNonUniformFMax: + case SpvOpGroupFMax: + case SpvOpGroupFMaxNonUniformAMD: reduction_op = nir_op_fmax; break; case SpvOpGroupNonUniformBitwiseAnd: |