Add validation for SPV_EXT_shader_atomic_float_min_max (#4105)
* Add an "extra_defs" parameter to GenerateShaderCode in atomics_test
* Add validation for SPV_EXT_shader_atomic_float_min_max
diff --git a/source/opcode.cpp b/source/opcode.cpp
index d87e828..c96cde8 100644
--- a/source/opcode.cpp
+++ b/source/opcode.cpp
@@ -417,8 +417,10 @@
case SpvOpAtomicISub:
case SpvOpAtomicSMin:
case SpvOpAtomicUMin:
+ case SpvOpAtomicFMinEXT:
case SpvOpAtomicSMax:
case SpvOpAtomicUMax:
+ case SpvOpAtomicFMaxEXT:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
diff --git a/source/opt/code_sink.cpp b/source/opt/code_sink.cpp
index e49029f..cd77797 100644
--- a/source/opt/code_sink.cpp
+++ b/source/opt/code_sink.cpp
@@ -218,8 +218,10 @@
case SpvOpAtomicISub:
case SpvOpAtomicSMin:
case SpvOpAtomicUMin:
+ case SpvOpAtomicFMinEXT:
case SpvOpAtomicSMax:
case SpvOpAtomicUMax:
+ case SpvOpAtomicFMaxEXT:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
diff --git a/source/val/validate_atomics.cpp b/source/val/validate_atomics.cpp
index a9fc2b4..fa53ca1 100644
--- a/source/val/validate_atomics.cpp
+++ b/source/val/validate_atomics.cpp
@@ -61,6 +61,8 @@
bool HasOnlyFloatReturnType(uint32_t opcode) {
switch (opcode) {
case SpvOpAtomicFAddEXT:
+ case SpvOpAtomicFMinEXT:
+ case SpvOpAtomicFMaxEXT:
return true;
break;
default:
@@ -132,8 +134,10 @@
case SpvOpAtomicISub:
case SpvOpAtomicSMin:
case SpvOpAtomicUMin:
+ case SpvOpAtomicFMinEXT:
case SpvOpAtomicSMax:
case SpvOpAtomicUMax:
+ case SpvOpAtomicFMaxEXT:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
@@ -232,6 +236,29 @@
<< ": float add atomics require the AtomicFloat64AddEXT "
"capability";
}
+ } else if (opcode == SpvOpAtomicFMinEXT ||
+ opcode == SpvOpAtomicFMaxEXT) {
+ if ((_.GetBitWidth(result_type) == 16) &&
+ (!_.HasCapability(SpvCapabilityAtomicFloat16MinMaxEXT))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float min/max atomics require the "
+ "AtomicFloat16MinMaxEXT capability";
+ }
+ if ((_.GetBitWidth(result_type) == 32) &&
+ (!_.HasCapability(SpvCapabilityAtomicFloat32MinMaxEXT))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float min/max atomics require the "
+ "AtomicFloat32MinMaxEXT capability";
+ }
+ if ((_.GetBitWidth(result_type) == 64) &&
+ (!_.HasCapability(SpvCapabilityAtomicFloat64MinMaxEXT))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float min/max atomics require the "
+ "AtomicFloat64MinMaxEXT capability";
+ }
}
}
diff --git a/test/enum_string_mapping_test.cpp b/test/enum_string_mapping_test.cpp
index 9bbd8ca..52aa653 100644
--- a/test/enum_string_mapping_test.cpp
+++ b/test/enum_string_mapping_test.cpp
@@ -181,6 +181,8 @@
{SpvCapabilityDeviceGroup, "DeviceGroup"},
{SpvCapabilityAtomicFloat32AddEXT, "AtomicFloat32AddEXT"},
{SpvCapabilityAtomicFloat64AddEXT, "AtomicFloat64AddEXT"},
+ {SpvCapabilityAtomicFloat32MinMaxEXT, "AtomicFloat32MinMaxEXT"},
+ {SpvCapabilityAtomicFloat64MinMaxEXT, "AtomicFloat64MinMaxEXT"},
{SpvCapabilityMultiView, "MultiView"},
{SpvCapabilityInt64ImageEXT, "Int64ImageEXT"},
{SpvCapabilitySampleMaskOverrideCoverageNV,
diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp
index e60f596..e2ca71f 100644
--- a/test/val/val_atomics_test.cpp
+++ b/test/val/val_atomics_test.cpp
@@ -95,6 +95,7 @@
std::string GenerateShaderCode(
const std::string& body,
const std::string& capabilities_and_extensions = "",
+ const std::string& extra_defs = "",
const std::string& memory_model = "GLSL450") {
const std::string execution = R"(
OpEntryPoint Fragment %main "main"
@@ -113,7 +114,8 @@
%s64_var = OpVariable %s64_ptr Workgroup
)";
return GenerateShaderCodeImpl(
- body, "OpCapability Int64\n" + capabilities_and_extensions, defintions,
+ body, "OpCapability Int64\n" + capabilities_and_extensions,
+ defintions + extra_defs,
memory_model, execution);
}
@@ -304,6 +306,32 @@
"AtomicFloat32AddEXT AtomicFloat64AddEXT"));
}
+TEST_F(ValidateAtomics, AtomicMinFloatVulkan) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body));
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Opcode AtomicFMinEXT requires one of these capabilities: "
+ "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT"));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloatVulkan) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body));
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Opcode AtomicFMaxEXT requires one of these capabilities: "
+ "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT"));
+}
+
TEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType1) {
const std::string body = R"(
%val1 = OpAtomicFAddEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1
@@ -320,6 +348,38 @@
"expected Result Type to be float scalar type"));
}
+TEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType1) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMinEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType1) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMaxEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
TEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType2) {
const std::string body = R"(
%val1 = OpAtomicFAddEXT %u32 %u32_var %device %relaxed %u32_1
@@ -336,6 +396,38 @@
"expected Result Type to be float scalar type"));
}
+TEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType2) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %u32 %u32_var %device %relaxed %u32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMinEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType2) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %u32 %u32_var %device %relaxed %u32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMaxEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
TEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType3) {
const std::string body = R"(
%val1 = OpAtomicFAddEXT %u64 %u64_var %device %relaxed %u64_1
@@ -352,6 +444,38 @@
"expected Result Type to be float scalar type"));
}
+TEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType3) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %u64 %u64_var %device %relaxed %u64_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMinEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType3) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %u64 %u64_var %device %relaxed %u64_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMaxEXT: "
+ "expected Result Type to be float scalar type"));
+}
+
TEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongCapability) {
const std::string body = R"(
%val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1
@@ -368,6 +492,38 @@
"require the AtomicFloat32AddEXT capability"));
}
+TEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongCapability) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat64MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMinEXT: float min/max atomics "
+ "require the AtomicFloat32MinMaxEXT capability"));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongCapability) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat64MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicFMaxEXT: float min/max atomics "
+ "require the AtomicFloat32MinMaxEXT capability"));
+}
+
TEST_F(ValidateAtomics, AtomicAddFloatVulkanSuccess) {
const std::string body = R"(
%val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1
@@ -382,6 +538,112 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
+TEST_F(ValidateAtomics, AtomicMinFloat16VulkanSuccess) {
+ const std::string defs = R"(
+%f16 = OpTypeFloat 16
+%f16_1 = OpConstant %f16 1
+%f16_ptr = OpTypePointer Workgroup %f16
+%f16_var = OpVariable %f16_ptr Workgroup
+)";
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f16 %f16_var %device %relaxed %f16_1
+)";
+ const std::string extra = R"(
+OpCapability Float16
+OpCapability AtomicFloat16MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, defs), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloat16VulkanSuccess) {
+ const std::string defs = R"(
+%f16 = OpTypeFloat 16
+%f16_1 = OpConstant %f16 1
+%f16_ptr = OpTypePointer Workgroup %f16
+%f16_var = OpVariable %f16_ptr Workgroup
+)";
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f16 %f16_var %device %relaxed %f16_1
+)";
+ const std::string extra = R"(
+OpCapability Float16
+OpCapability AtomicFloat16MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, defs), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+TEST_F(ValidateAtomics, AtomicMinFloat32VulkanSuccess) {
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloat32VulkanSuccess) {
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1
+)";
+ const std::string extra = R"(
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+TEST_F(ValidateAtomics, AtomicMinFloat64VulkanSuccess) {
+ const std::string defs = R"(
+%f64 = OpTypeFloat 64
+%f64_1 = OpConstant %f64 1
+%f64_ptr = OpTypePointer Workgroup %f64
+%f64_var = OpVariable %f64_ptr Workgroup
+)";
+ const std::string body = R"(
+%val1 = OpAtomicFMinEXT %f64 %f64_var %device %relaxed %f64_1
+)";
+ const std::string extra = R"(
+OpCapability Float64
+OpCapability AtomicFloat64MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, defs), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+TEST_F(ValidateAtomics, AtomicMaxFloat64VulkanSuccess) {
+ const std::string defs = R"(
+%f64 = OpTypeFloat 64
+%f64_1 = OpConstant %f64 1
+%f64_ptr = OpTypePointer Workgroup %f64
+%f64_var = OpVariable %f64_ptr Workgroup
+)";
+ const std::string body = R"(
+%val1 = OpAtomicFMaxEXT %f64 %f64_var %device %relaxed %f64_1
+)";
+ const std::string extra = R"(
+OpCapability Float64
+OpCapability AtomicFloat64MinMaxEXT
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, defs), SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
TEST_F(ValidateAtomics, AtomicLoadFloatVulkan) {
const std::string body = R"(
%val1 = OpAtomicLoad %f32 %f32_var %device %relaxed
@@ -1479,7 +1741,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1498,7 +1760,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1518,7 +1780,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1538,7 +1800,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1558,7 +1820,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1578,7 +1840,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1598,7 +1860,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1617,7 +1879,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1636,7 +1898,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1655,7 +1917,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1674,7 +1936,28 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
+ SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("SequentiallyConsistent memory semantics cannot be "
+ "used with the VulkanKHR memory model."));
+}
+
+TEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicFMinEXT) {
+ const std::string body = R"(
+%max = OpAtomicFMinEXT %f32 %f32_var %workgroup %sequentially_consistent %f32_0
+)";
+
+ const std::string extra = R"(
+OpCapability VulkanMemoryModelKHR
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1693,7 +1976,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1712,7 +1995,28 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
+ SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("SequentiallyConsistent memory semantics cannot be "
+ "used with the VulkanKHR memory model."));
+}
+
+TEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicFMaxEXT) {
+ const std::string body = R"(
+%max = OpAtomicFMaxEXT %f32 %f32_var %workgroup %sequentially_consistent %f32_0
+)";
+
+ const std::string extra = R"(
+OpCapability VulkanMemoryModelKHR
+OpCapability AtomicFloat32MinMaxEXT
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpExtension "SPV_EXT_shader_atomic_float_min_max"
+)";
+
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1731,7 +2035,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1750,7 +2054,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1769,7 +2073,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1993,7 +2297,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
}
@@ -2121,7 +2425,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2141,7 +2445,7 @@
OpExtension "SPV_KHR_vulkan_memory_model"
)";
- CompileSuccessfully(GenerateShaderCode(body, extra, "VulkanKHR"),
+ CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"),
SPV_ENV_UNIVERSAL_1_3);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
}