diff options
-rw-r--r-- | source/val/validate_decorations.cpp | 30 | ||||
-rw-r--r-- | test/val/val_decoration_test.cpp | 82 |
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 |