aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/val/validate_decorations.cpp30
-rw-r--r--test/val/val_decoration_test.cpp82
2 files changed, 112 insertions, 0 deletions
diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp
index ed312f73..cfb38ef7 100644
--- a/source/val/validate_decorations.cpp
+++ b/source/val/validate_decorations.cpp
@@ -840,6 +840,34 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
return SPV_SUCCESS;
}
+spv_result_t CheckVulkanMemoryModelDeprecatedDecorations(
+ ValidationState_t& vstate) {
+ if (vstate.memory_model() != SpvMemoryModelVulkanKHR) return SPV_SUCCESS;
+
+ std::string msg;
+ std::ostringstream str(msg);
+ for (const auto& def : vstate.all_definitions()) {
+ const auto inst = def.second;
+ const auto id = inst->id();
+ for (const auto& dec : vstate.id_decorations(id)) {
+ const auto member = dec.struct_member_index();
+ if (dec.dec_type() == SpvDecorationCoherent ||
+ dec.dec_type() == SpvDecorationVolatile) {
+ str << (dec.dec_type() == SpvDecorationCoherent ? "Coherent"
+ : "Volatile");
+ str << " decoration targeting " << vstate.getIdName(id);
+ if (member != Decoration::kInvalidMember) {
+ str << " (member index " << member << ")";
+ }
+ str << " is banned when using the Vulkan memory model.";
+ return vstate.diag(SPV_ERROR_INVALID_ID, inst) << str.str();
+ }
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
} // namespace
// Validates that decorations have been applied properly.
@@ -849,6 +877,8 @@ spv_result_t ValidateDecorations(ValidationState_t& vstate) {
if (auto error = CheckDecorationsOfBuffers(vstate)) return error;
if (auto error = CheckLinkageAttrOfFunctions(vstate)) return error;
if (auto error = CheckDescriptorSetArrayOfArrays(vstate)) return error;
+ if (auto error = CheckVulkanMemoryModelDeprecatedDecorations(vstate))
+ return error;
return SPV_SUCCESS;
}
diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp
index c3429e6d..29105353 100644
--- a/test/val/val_decoration_test.cpp
+++ b/test/val/val_decoration_test.cpp
@@ -3055,6 +3055,88 @@ OpFunctionEnd
"Storage Class of Input(1) or Output(3). Found Storage "
"Class 4 for Entry Point id 1."));
}
+
+TEST_F(ValidateDecorations, VulkanMemoryModelNonCoherent) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability VulkanMemoryModelKHR
+OpCapability Linkage
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical VulkanKHR
+OpDecorate %1 Coherent
+%2 = OpTypeInt 32 0
+%3 = OpTypePointer StorageBuffer %2
+%1 = OpVariable %3 StorageBuffer
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Coherent decoration targeting 1 is banned when using "
+ "the Vulkan memory model."));
+}
+
+TEST_F(ValidateDecorations, VulkanMemoryModelNoCoherentMember) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability VulkanMemoryModelKHR
+OpCapability Linkage
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical VulkanKHR
+OpMemberDecorate %1 0 Coherent
+%2 = OpTypeInt 32 0
+%1 = OpTypeStruct %2 %2
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Coherent decoration targeting 1 (member index 0) is "
+ "banned when using "
+ "the Vulkan memory model."));
+}
+
+TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatile) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability VulkanMemoryModelKHR
+OpCapability Linkage
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical VulkanKHR
+OpDecorate %1 Volatile
+%2 = OpTypeInt 32 0
+%3 = OpTypePointer StorageBuffer %2
+%1 = OpVariable %3 StorageBuffer
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Volatile decoration targeting 1 is banned when using "
+ "the Vulkan memory model."));
+}
+
+TEST_F(ValidateDecorations, VulkanMemoryModelNoVolatileMember) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability VulkanMemoryModelKHR
+OpCapability Linkage
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical VulkanKHR
+OpMemberDecorate %1 1 Volatile
+%2 = OpTypeInt 32 0
+%1 = OpTypeStruct %2 %2
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Volatile decoration targeting 1 (member index 1) is "
+ "banned when using "
+ "the Vulkan memory model."));
+}
} // namespace
} // namespace val
} // namespace spvtools