spirv-val: Multiple interface var with same SC (#4969)

* spirv-val: Multiple interface var with same SC

* spirv-val: Use C style headers
This commit is contained in:
Spencer Fricke 2022-11-11 02:32:58 +09:00 committed by GitHub
parent aae7d41325
commit 996d4c021f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 200 additions and 0 deletions

View File

@ -537,6 +537,64 @@ spv_result_t ValidateLocations(ValidationState_t& _,
return SPV_SUCCESS;
}
spv_result_t ValidateStorageClass(ValidationState_t& _,
const Instruction* entry_point) {
bool has_push_constant = false;
bool has_ray_payload = false;
bool has_hit_attribute = false;
bool has_callable_data = false;
for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
auto interface_var = _.FindDef(interface_id);
auto storage_class = interface_var->GetOperandAs<spv::StorageClass>(2);
switch (storage_class) {
case spv::StorageClass::PushConstant: {
if (has_push_constant) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
<< _.VkErrorID(6673)
<< "Entry-point has more than one variable with the "
"PushConstant storage class in the interface";
}
has_push_constant = true;
break;
}
case spv::StorageClass::IncomingRayPayloadKHR: {
if (has_ray_payload) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
<< _.VkErrorID(4700)
<< "Entry-point has more than one variable with the "
"IncomingRayPayloadKHR storage class in the interface";
}
has_ray_payload = true;
break;
}
case spv::StorageClass::HitAttributeKHR: {
if (has_hit_attribute) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
<< _.VkErrorID(4702)
<< "Entry-point has more than one variable with the "
"HitAttributeKHR storage class in the interface";
}
has_hit_attribute = true;
break;
}
case spv::StorageClass::IncomingCallableDataKHR: {
if (has_callable_data) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
<< _.VkErrorID(4706)
<< "Entry-point has more than one variable with the "
"IncomingCallableDataKHR storage class in the interface";
}
has_callable_data = true;
break;
}
default:
break;
}
}
return SPV_SUCCESS;
}
} // namespace
spv_result_t ValidateInterfaces(ValidationState_t& _) {
@ -555,6 +613,9 @@ spv_result_t ValidateInterfaces(ValidationState_t& _) {
if (auto error = ValidateLocations(_, &inst)) {
return error;
}
if (auto error = ValidateStorageClass(_, &inst)) {
return error;
}
}
if (inst.opcode() == spv::Op::OpTypeVoid) break;
}

View File

@ -2060,14 +2060,20 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
case 4699:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
case 4700:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700);
case 4701:
return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
case 4702:
return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04702);
case 4703:
return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
case 4704:
return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
case 4705:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
case 4706:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04706);
case 7119:
return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119);
case 4708:
@ -2126,6 +2132,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
case 6672:
return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
case 6673:
return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-06673);
case 6674:
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
case 6675:

View File

@ -3210,6 +3210,48 @@ TEST_F(ValidateDecorations,
"statically used per shader entry point."));
}
TEST_F(ValidateDecorations,
VulkanMultiplePushConstantsSingleEntryPointInterfaceBad) {
std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %func1 "func1" %pc1 %pc2
OpDecorate %struct Block
OpMemberDecorate %struct 0 Offset 0
%void = OpTypeVoid
%voidfn = OpTypeFunction %void
%float = OpTypeFloat 32
%int = OpTypeInt 32 0
%int_0 = OpConstant %int 0
%struct = OpTypeStruct %float
%ptr = OpTypePointer PushConstant %struct
%ptr_float = OpTypePointer PushConstant %float
%pc1 = OpVariable %ptr PushConstant
%pc2 = OpVariable %ptr PushConstant
%func1 = OpFunction %void None %voidfn
%label1 = OpLabel
%access1 = OpAccessChain %ptr_float %pc1 %int_0
%load1 = OpLoad %float %access1
OpReturn
OpFunctionEnd
%func2 = OpFunction %void None %voidfn
%label2 = OpLabel
%access2 = OpAccessChain %ptr_float %pc2 %int_0
%load2 = OpLoad %float %access2
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpVariable-06673"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has more than one variable with the "
"PushConstant storage class in the interface"));
}
TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
std::string spirv = R"(
OpCapability Shader

View File

@ -578,6 +578,95 @@ OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0
"IncomingRayPayloadKHR"));
}
TEST_F(ValidateRayTracing, InterfaceIncomingRayPayload) {
const std::string body = R"(
OpCapability RayTracingKHR
OpExtension "SPV_KHR_ray_tracing"
OpMemoryModel Logical GLSL450
OpEntryPoint CallableKHR %main "main" %inData1 %inData2
OpName %main "main"
%void = OpTypeVoid
%func = OpTypeFunction %void
%int = OpTypeInt 32 1
%inData_ptr = OpTypePointer IncomingRayPayloadKHR %int
%inData1 = OpVariable %inData_ptr IncomingRayPayloadKHR
%inData2 = OpVariable %inData_ptr IncomingRayPayloadKHR
%main = OpFunction %void None %func
%label = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Entry-point has more than one variable with the "
"IncomingRayPayloadKHR storage class in the interface"));
}
TEST_F(ValidateRayTracing, InterfaceHitAttribute) {
const std::string body = R"(
OpCapability RayTracingKHR
OpExtension "SPV_KHR_ray_tracing"
OpMemoryModel Logical GLSL450
OpEntryPoint CallableKHR %main "main" %inData1 %inData2
OpName %main "main"
%void = OpTypeVoid
%func = OpTypeFunction %void
%int = OpTypeInt 32 1
%inData_ptr = OpTypePointer HitAttributeKHR %int
%inData1 = OpVariable %inData_ptr HitAttributeKHR
%inData2 = OpVariable %inData_ptr HitAttributeKHR
%main = OpFunction %void None %func
%label = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04702"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has more than one variable with the "
"HitAttributeKHR storage class in the interface"));
}
TEST_F(ValidateRayTracing, InterfaceIncomingCallableData) {
const std::string body = R"(
OpCapability RayTracingKHR
OpExtension "SPV_KHR_ray_tracing"
OpMemoryModel Logical GLSL450
OpEntryPoint CallableKHR %main "main" %inData1 %inData2
OpName %main "main"
%void = OpTypeVoid
%func = OpTypeFunction %void
%int = OpTypeInt 32 1
%inData_ptr = OpTypePointer IncomingCallableDataKHR %int
%inData1 = OpVariable %inData_ptr IncomingCallableDataKHR
%inData2 = OpVariable %inData_ptr IncomingCallableDataKHR
%main = OpFunction %void None %func
%label = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04706"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Entry-point has more than one variable with the "
"IncomingCallableDataKHR storage class in the interface"));
}
} // namespace
} // namespace val
} // namespace spvtools