Skip to content

Commit 91e89a9

Browse files
authored
[val] Allow untyped access chains in OpSpecConstantOp (KhronosGroup#6768)
SPV_KHR_untyped_pointers allows the following opcodes to be used in `OpSpecConstantOp` with the `Kernel` capability: * `OpUntypedAccessChainKHR` * `OpUntypedInBoundsAccessChainKHR` * `OpUntypedPtrAccessChainKHR` * `OpUntypedInBoundsPtrAccessChainKHR` Contributes to KhronosGroup#6564
1 parent d5bbf95 commit 91e89a9

4 files changed

Lines changed: 63 additions & 5 deletions

File tree

source/assembly_grammar.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,16 @@ const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = {
153153
CASE(InBoundsAccessChain),
154154
CASE(PtrAccessChain),
155155
CASE(InBoundsPtrAccessChain),
156+
CASE(UntypedAccessChainKHR),
157+
CASE(UntypedInBoundsAccessChainKHR),
158+
CASE(UntypedPtrAccessChainKHR),
159+
CASE(UntypedInBoundsPtrAccessChainKHR),
156160
CASE(CooperativeMatrixLengthNV),
157161
CASE(CooperativeMatrixLengthKHR)
158162
};
159163

160-
// The 60 is determined by counting the opcodes listed in the spec.
161-
static_assert(61 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]),
164+
// The count is determined by counting the opcodes listed in the spec.
165+
static_assert(65 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]),
162166
"OpSpecConstantOp opcode table is incomplete");
163167
#undef CASE
164168
// clang-format on

source/val/validate_constants.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,10 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _,
633633
case spv::Op::OpInBoundsAccessChain:
634634
case spv::Op::OpPtrAccessChain:
635635
case spv::Op::OpInBoundsPtrAccessChain:
636+
case spv::Op::OpUntypedAccessChainKHR:
637+
case spv::Op::OpUntypedInBoundsAccessChainKHR:
638+
case spv::Op::OpUntypedPtrAccessChainKHR:
639+
case spv::Op::OpUntypedInBoundsPtrAccessChainKHR:
636640
if (!_.HasCapability(spv::Capability::Kernel)) {
637641
return _.diag(SPV_ERROR_INVALID_ID, inst)
638642
<< "Specialization constant operation " << spvOpcodeString(op)

source/val/validate_id.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,15 @@ bool InstructionCanHaveTypeOperand(const Instruction* inst) {
131131
const auto opcode = inst->opcode();
132132
bool type_instruction = spvOpcodeGeneratesType(opcode);
133133
bool debug_instruction = spvOpcodeIsDebug(opcode) || inst->IsDebugInfo();
134-
bool coop_matrix_spec_constant_op_length =
134+
bool spec_constant_op_with_type_operand =
135135
(opcode == spv::Op::OpSpecConstantOp) &&
136136
(spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthNV ||
137-
spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthKHR);
137+
spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthKHR ||
138+
spvOpcodeGeneratesUntypedPointer(spv::Op(inst->word(3))));
138139
return type_instruction || debug_instruction || inst->IsNonSemantic() ||
139140
spvOpcodeIsDecoration(opcode) || instruction_allow_set.count(opcode) ||
140141
spvOpcodeGeneratesUntypedPointer(opcode) ||
141-
coop_matrix_spec_constant_op_length;
142+
spec_constant_op_with_type_operand;
142143
}
143144

144145
bool InstructionRequiresTypeOperand(const Instruction* inst) {

test/val/val_constants_test.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,55 @@ OpMemoryModel Logical VulkanKHR
807807
HasSubstr("must be OpTypeCooperativeMatrixKHR"));
808808
}
809809

810+
TEST_F(ValidateConstant, UntypedAccessChainSpecConstantOpGood) {
811+
std::string spirv = R"(
812+
OpCapability Addresses
813+
OpCapability Kernel
814+
OpCapability Linkage
815+
OpCapability UntypedPointersKHR
816+
OpExtension "SPV_KHR_untyped_pointers"
817+
OpMemoryModel Physical32 OpenCL
818+
%uint = OpTypeInt 32 0
819+
%uint_0 = OpConstant %uint 0
820+
%uint_4 = OpConstant %uint 4
821+
%arr = OpTypeArray %uint %uint_4
822+
%ptr = OpTypeUntypedPointerKHR CrossWorkgroup
823+
%var = OpUntypedVariableKHR %ptr CrossWorkgroup %arr
824+
%ac = OpSpecConstantOp %ptr UntypedAccessChainKHR %arr %var %uint_0
825+
%iac = OpSpecConstantOp %ptr UntypedInBoundsAccessChainKHR %arr %var %uint_0
826+
%pac = OpSpecConstantOp %ptr UntypedPtrAccessChainKHR %arr %var %uint_0
827+
%ipac = OpSpecConstantOp %ptr UntypedInBoundsPtrAccessChainKHR %arr %var %uint_0
828+
)";
829+
830+
CompileSuccessfully(spirv);
831+
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
832+
EXPECT_THAT(getDiagnosticString(), Eq(""));
833+
}
834+
835+
TEST_F(ValidateConstant, UntypedAccessChainSpecConstantOpRequiresKernel) {
836+
std::string spirv = R"(
837+
OpCapability Shader
838+
OpCapability Linkage
839+
OpCapability UntypedPointersKHR
840+
OpExtension "SPV_KHR_untyped_pointers"
841+
OpMemoryModel Logical GLSL450
842+
%uint = OpTypeInt 32 0
843+
%uint_0 = OpConstant %uint 0
844+
%uint_4 = OpConstant %uint 4
845+
%arr = OpTypeArray %uint %uint_4
846+
%ptr = OpTypeUntypedPointerKHR Workgroup
847+
%var = OpUntypedVariableKHR %ptr Workgroup %arr
848+
%ac = OpSpecConstantOp %ptr UntypedInBoundsPtrAccessChainKHR %arr %var %uint_0
849+
)";
850+
851+
CompileSuccessfully(spirv);
852+
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
853+
EXPECT_THAT(getDiagnosticString(),
854+
HasSubstr("Specialization constant operation "
855+
"UntypedInBoundsPtrAccessChainKHR requires Kernel "
856+
"capability"));
857+
}
858+
810859
// Some check use SPV_ERROR_INVALID_DATA vs SPV_ERROR_INVALID_ID
811860
#define BAD_KERNEL_OPERANDS(STR, ERR) \
812861
{ \

0 commit comments

Comments
 (0)