validate StorageImageMultisampled capability (#4062)
* validate StorageImageMultisampled capability
The StorageImageMultisampled capability is required when declaring
an image type with with Multisampled==1 and it's a storage image (Sampled == 2)
Fixes #4061
* Allow SubpassData with Multisampled and Sampled==2
diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp
index 299a3ef..17ddfc0 100644
--- a/source/val/validate_image.cpp
+++ b/source/val/validate_image.cpp
@@ -829,6 +829,15 @@
}
}
+ if (info.multisampled && (info.sampled == 2) &&
+ (info.dim != SpvDimSubpassData)) {
+ if (!_.HasCapability(SpvCapabilityStorageImageMultisample)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Capability StorageImageMultisample is required when using "
+ "multisampled storage image";
+ }
+ }
+
return SPV_SUCCESS;
}
diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp
index 2e84a29..d2e1a55 100644
--- a/test/val/val_image_test.cpp
+++ b/test/val/val_image_test.cpp
@@ -584,6 +584,43 @@
HasSubstr("Dim SubpassData requires format Unknown"));
}
+TEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
+ const std::string code = GetShaderHeader("", false) +
+ R"(
+%img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
+)";
+
+ CompileSuccessfully(code.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Capability StorageImageMultisample is required when "
+ "using multisampled storage image"));
+}
+
+TEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
+ const std::string code =
+ GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
+ R"(
+%img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
+)";
+
+ CompileSuccessfully(code.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
+ EXPECT_THAT(getDiagnosticString(), Eq(""));
+}
+
+TEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
+ const std::string code =
+ GetShaderHeader("OpCapability InputAttachment\n", false) +
+ R"(
+%img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
+)";
+
+ CompileSuccessfully(code.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
+ EXPECT_THAT(getDiagnosticString(), Eq(""));
+}
+
TEST_F(ValidateImage, TypeSampledImageNotImage) {
const std::string code = GetShaderHeader("", false) + R"(
%simg_type = OpTypeSampledImage %f32