Remove Acquire, Release, and Relaxed from allowed Mem Sem bits for WebGPU (#2526)
Fixes #2524
diff --git a/source/val/validate_memory_semantics.cpp b/source/val/validate_memory_semantics.cpp
index 5dece3f..31154f5 100644
--- a/source/val/validate_memory_semantics.cpp
+++ b/source/val/validate_memory_semantics.cpp
@@ -55,9 +55,7 @@
SpvMemorySemanticsMakeAvailableKHRMask |
SpvMemorySemanticsMakeVisibleKHRMask;
if (!spvOpcodeIsAtomicOp(inst->opcode())) {
- valid_bits |= SpvMemorySemanticsAcquireMask |
- SpvMemorySemanticsReleaseMask |
- SpvMemorySemanticsAcquireReleaseMask;
+ valid_bits |= SpvMemorySemanticsAcquireReleaseMask;
}
if (value & ~valid_bits) {
@@ -69,11 +67,18 @@
} 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";
+ "that are not AcquireRelease, UniformMemory, "
+ "WorkgroupMemory, ImageMemory, OutputMemoryKHR, "
+ "MakeAvailableKHR, or MakeVisibleKHR";
}
}
+
+ if (!spvOpcodeIsAtomicOp(inst->opcode()) &&
+ !(value & SpvMemorySemanticsAcquireReleaseMask)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "WebGPU spec requires AcquireRelease to set in Memory "
+ "Semantics.";
+ }
}
const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits(
diff --git a/test/val/val_barriers_test.cpp b/test/val/val_barriers_test.cpp
index 264d130..0b28c45 100644
--- a/test/val/val_barriers_test.cpp
+++ b/test/val/val_barriers_test.cpp
@@ -78,9 +78,13 @@
%acquire_and_release = OpConstant %u32 6
%sequentially_consistent = OpConstant %u32 16
%acquire_release_uniform_workgroup = OpConstant %u32 328
+%acquire_uniform_workgroup = OpConstant %u32 322
+%release_uniform_workgroup = OpConstant %u32 324
%acquire_and_release_uniform = OpConstant %u32 70
%acquire_release_subgroup = OpConstant %u32 136
%uniform = OpConstant %u32 64
+%uniform_workgroup = OpConstant %u32 320
+
%main = OpFunction %void None %func
%main_entry = OpLabel
@@ -245,9 +249,8 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
-TEST_F(ValidateBarriers, OpControlBarrierWebGPUSuccess) {
+TEST_F(ValidateBarriers, OpControlBarrierWebGPUAcquireReleaseSuccess) {
const std::string body = R"(
-OpControlBarrier %workgroup %queuefamily %none
OpControlBarrier %workgroup %workgroup %acquire_release_uniform_workgroup
)";
@@ -255,6 +258,41 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
}
+TEST_F(ValidateBarriers, OpControlBarrierWebGPURelaxedFailure) {
+ const std::string body = R"(
+OpControlBarrier %workgroup %workgroup %uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec requires AcquireRelease to set"));
+}
+
+TEST_F(ValidateBarriers, OpControlBarrierWebGPUAcquireFailure) {
+ const std::string body = R"(
+OpControlBarrier %workgroup %workgroup %acquire_uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows any bit masks in Memory Semantics"));
+}
+
+TEST_F(ValidateBarriers, OpControlBarrierWebGPUReleaseFailure) {
+ const std::string body = R"(
+OpControlBarrier %workgroup %workgroup %release_uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows any bit masks in Memory Semantics"));
+}
+
TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv12) {
const std::string body = R"(
OpControlBarrier %device %device %none
@@ -630,6 +668,50 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
+TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUAcquireReleaseSuccess) {
+ const std::string body = R"(
+OpMemoryBarrier %workgroup %acquire_release_uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
+}
+
+TEST_F(ValidateBarriers, OpMemoryBarrierWebGPURelaxedFailure) {
+ const std::string body = R"(
+OpMemoryBarrier %workgroup %uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("WebGPU spec requires AcquireRelease to set"));
+}
+
+TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUAcquireFailure) {
+ const std::string body = R"(
+OpMemoryBarrier %workgroup %acquire_uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows any bit masks in Memory Semantics"));
+}
+
+TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUReleaseFailure) {
+ const std::string body = R"(
+OpMemoryBarrier %workgroup %release_uniform_workgroup
+)";
+
+ CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("WebGPU spec disallows any bit masks in Memory Semantics"));
+}
+
TEST_F(ValidateBarriers, OpMemoryBarrierFloatMemoryScope) {
const std::string body = R"(
OpMemoryBarrier %f32_1 %acquire_release_uniform_workgroup