Change validation of memory semantics for OpAtomics* in WebGPU (#2519)
Recent change to the spec restricted the valid values for Memory
Semantics in OpAtomics* in the WebGPU env. Implementing enforcing
these changes.
Fixes #2499
diff --git a/source/val/validate_memory_semantics.cpp b/source/val/validate_memory_semantics.cpp
index f90b5e4..5dece3f 100644
--- a/source/val/validate_memory_semantics.cpp
+++ b/source/val/validate_memory_semantics.cpp
@@ -48,21 +48,31 @@
}
if (spvIsWebGPUEnv(_.context()->target_env)) {
- uint32_t valid_bits = SpvMemorySemanticsAcquireMask |
- SpvMemorySemanticsReleaseMask |
- SpvMemorySemanticsAcquireReleaseMask |
- SpvMemorySemanticsUniformMemoryMask |
+ uint32_t valid_bits = SpvMemorySemanticsUniformMemoryMask |
SpvMemorySemanticsWorkgroupMemoryMask |
SpvMemorySemanticsImageMemoryMask |
SpvMemorySemanticsOutputMemoryKHRMask |
SpvMemorySemanticsMakeAvailableKHRMask |
SpvMemorySemanticsMakeVisibleKHRMask;
+ if (!spvOpcodeIsAtomicOp(inst->opcode())) {
+ valid_bits |= SpvMemorySemanticsAcquireMask |
+ SpvMemorySemanticsReleaseMask |
+ SpvMemorySemanticsAcquireReleaseMask;
+ }
+
if (value & ~valid_bits) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << "WebGPU spec disallows any bit masks in Memory Semantics that "
- "are not Acquire, Release, AcquireRelease, UniformMemory, "
- "WorkgroupMemory, ImageMemory, OutputMemoryKHR, "
- "MakeAvailableKHR, or MakeVisibleKHR";
+ if (spvOpcodeIsAtomicOp(inst->opcode())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "WebGPU spec disallows, for OpAtomic*, any bit masks in "
+ "Memory Semantics that are not UniformMemory, "
+ "WorkgroupMemory, ImageMemory, or OutputMemoryKHR";
+ } else {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "WebGPU spec disallows any bit masks in Memory Semantics "
+ "that are not Acquire, Release, AcquireRelease, "
+ "UniformMemory, WorkgroupMemory, ImageMemory, "
+ "OutputMemoryKHR, MakeAvailableKHR, or MakeVisibleKHR";
+ }
}
}
diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp
index 2090c13..1be19c5 100644
--- a/test/val/val_atomics_test.cpp
+++ b/test/val/val_atomics_test.cpp
@@ -373,30 +373,37 @@
"AtomicLoad: 64-bit atomics require the Int64Atomics capability"));
}
-TEST_F(ValidateAtomics, AtomicLoadWebGPUShaderSuccess) {
+TEST_F(ValidateAtomics, AtomicLoadWebGPUSuccess) {
const std::string body = R"(
%val1 = OpAtomicLoad %u32 %u32_var %queuefamily %relaxed
-%val2 = OpAtomicLoad %u32 %u32_var %workgroup %acquire
+%val2 = OpAtomicLoad %u32 %u32_var %workgroup %relaxed
)";
CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
}
-TEST_F(ValidateAtomics, AtomicLoadWebGPUShaderSequentiallyConsistentFailure) {
+TEST_F(ValidateAtomics, AtomicLoadWebGPUNonRelaxedFailure) {
+ const std::string body = R"(
+%val1 = OpAtomicLoad %u32 %u32_var %queuefamily %acquire
+%val2 = OpAtomicLoad %u32 %u32_var %workgroup %release
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows, for OpAtomic*, any bit masks"));
+}
+
+TEST_F(ValidateAtomics, AtomicLoadWebGPUSequentiallyConsistentFailure) {
const std::string body = R"(
%val3 = OpAtomicLoad %u32 %u32_var %subgroup %sequentially_consistent
)";
CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "WebGPU spec disallows any bit masks in Memory Semantics that are "
- "not Acquire, Release, AcquireRelease, UniformMemory, "
- "WorkgroupMemory, ImageMemory, OutputMemoryKHR, MakeAvailableKHR, or "
- "MakeVisibleKHR\n %34 = OpAtomicLoad %uint %29 %uint_3 %uint_16\n"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows, for OpAtomic*, any bit masks"));
}
TEST_F(ValidateAtomics, VK_KHR_shader_atomic_int64Success) {
@@ -579,13 +586,24 @@
TEST_F(ValidateAtomics, AtomicStoreWebGPUSuccess) {
const std::string body = R"(
-OpAtomicStore %u32_var %queuefamily %release %u32_1
+OpAtomicStore %u32_var %queuefamily %relaxed %u32_1
)";
CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
}
+TEST_F(ValidateAtomics, AtomicStoreWebGPUNonRelaxedFailure) {
+ const std::string body = R"(
+OpAtomicStore %u32_var %queuefamily %release %u32_1
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows, for OpAtomic*, any bit masks"));
+}
+
TEST_F(ValidateAtomics, AtomicStoreWebGPUSequentiallyConsistent) {
const std::string body = R"(
OpAtomicStore %u32_var %queuefamily %sequentially_consistent %u32_1
@@ -593,14 +611,8 @@
CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(
- "WebGPU spec disallows any bit masks in Memory Semantics that are "
- "not Acquire, Release, AcquireRelease, UniformMemory, "
- "WorkgroupMemory, ImageMemory, OutputMemoryKHR, MakeAvailableKHR, or "
- "MakeVisibleKHR\n"
- " OpAtomicStore %29 %uint_5 %uint_16 %uint_1\n"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows, for OpAtomic*, any bit masks"));
}
TEST_F(ValidateAtomics, AtomicStoreWrongPointerType) {