spirv-val: Add Vulkan ForwardPointer VUID (#4089)
diff --git a/source/val/validate_type.cpp b/source/val/validate_type.cpp
index 5924c69..8352301 100644
--- a/source/val/validate_type.cpp
+++ b/source/val/validate_type.cpp
@@ -555,8 +555,8 @@
<< "Pointer type in OpTypeForwardPointer is not a pointer type.";
}
- if (inst->GetOperandAs<uint32_t>(1) !=
- pointer_type_inst->GetOperandAs<uint32_t>(1)) {
+ const auto storage_class = inst->GetOperandAs<SpvStorageClass>(1);
+ if (storage_class != pointer_type_inst->GetOperandAs<uint32_t>(1)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Storage class in OpTypeForwardPointer does not match the "
<< "pointer definition.";
@@ -569,6 +569,15 @@
<< "Forward pointers must point to a structure";
}
+ if (spvIsVulkanEnv(_.context()->target_env)) {
+ if (storage_class != SpvStorageClassPhysicalStorageBuffer) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << _.VkErrorID(4711)
+ << "In Vulkan, OpTypeForwardPointer must have "
+ << "a storage class of PhysicalStorageBuffer.";
+ }
+ }
+
return SPV_SUCCESS;
}
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index e168c01..0fe9082 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -1671,6 +1671,8 @@
return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
case 4685:
return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
+ case 4711:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711);
default:
return ""; // unknown id
};
diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp
index 1080a59..99a9aa0 100644
--- a/test/val/val_data_test.cpp
+++ b/test/val/val_data_test.cpp
@@ -960,6 +960,26 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
}
+TEST_F(ValidateData, VulkanTypeForwardStorageClass) {
+ std::string test = R"(
+OpCapability Shader
+OpCapability PhysicalStorageBufferAddresses
+OpMemoryModel Logical GLSL450
+OpTypeForwardPointer %1 Uniform
+%2 = OpTypeStruct
+%3 = OpTypeRuntimeArray %1
+%1 = OpTypePointer Uniform %2
+)";
+
+ CompileSuccessfully(test, SPV_ENV_VULKAN_1_2);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpTypeForwardPointer-04711"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("In Vulkan, OpTypeForwardPointer must have "
+ "a storage class of PhysicalStorageBuffer."));
+}
+
TEST_F(ValidateData, TypeForwardReferenceMustBeForwardPointer) {
std::string test = R"(
OpCapability Shader