Compat: Reject fragment shaders with sample_mask
Bug: dawn:1836
Change-Id: I5b1277a90d8411c9e17262de9b2b1518d43cb7a9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/133980
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Gregg Tavares <gman@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index 8d00eca..3ca9af5 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -495,6 +495,14 @@
format->format);
}
+ if (device->IsCompatibilityMode()) {
+ DAWN_INVALID_IF(
+ fragmentMetadata.usesSampleMaskOutput,
+ "sample_mask is not supported in compatibility mode in the fragment stage (%s, "
+ "entryPoint: %s)",
+ descriptor->module, descriptor->entryPoint);
+ }
+
return {};
}
diff --git a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
index bc16753..2bbf8a8 100644
--- a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
+++ b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
@@ -763,6 +763,9 @@
// Test using one multisampled color attachment with resolve target can render correctly
// with non-default sample mask and shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) {
+ // sample_mask is not supported in compat.
+ DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());
+
// TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not
// supported on some platforms.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_sample_variables"));
@@ -817,6 +820,9 @@
// Test doing MSAA resolve into multiple resolve targets works correctly with a non-default
// shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithShaderOutputMask) {
+ // sample_mask is not supported in compat.
+ DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());
+
// TODO(dawn:1550) Fails on ARM-based Android devices.
DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index a1ac4dc..1519d12 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -136,5 +136,55 @@
}
}
+TEST_F(CompatValidationTest, CanNotUseFragmentShaderWithSampleMask) {
+ wgpu::ShaderModule moduleSampleMaskOutput = utils::CreateShaderModule(device, R"(
+ @vertex fn vs() -> @builtin(position) vec4f {
+ return vec4f(1);
+ }
+ struct Output {
+ @builtin(sample_mask) mask_out: u32,
+ @location(0) color : vec4f,
+ }
+ @fragment fn fsWithoutSampleMaskUsage() -> @location(0) vec4f {
+ return vec4f(1.0, 1.0, 1.0, 1.0);
+ }
+ @fragment fn fsWithSampleMaskUsage() -> Output {
+ var o: Output;
+ // We need to make sure this sample_mask isn't optimized out even its value equals "no op".
+ o.mask_out = 0xFFFFFFFFu;
+ o.color = vec4f(1.0, 1.0, 1.0, 1.0);
+ return o;
+ }
+ )");
+
+ // Check we can use a fragment shader that doesn't use sample_mask from
+ // the same module as one that does.
+ {
+ utils::ComboRenderPipelineDescriptor descriptor;
+ descriptor.vertex.module = moduleSampleMaskOutput;
+ descriptor.vertex.entryPoint = "vs";
+ descriptor.cFragment.module = moduleSampleMaskOutput;
+ descriptor.cFragment.entryPoint = "fsWithoutSampleMaskUsage";
+ descriptor.multisample.count = 4;
+ descriptor.multisample.alphaToCoverageEnabled = false;
+
+ device.CreateRenderPipeline(&descriptor);
+ }
+
+ // Check we can not use a fragment shader that uses sample_mask.
+ {
+ utils::ComboRenderPipelineDescriptor descriptor;
+ descriptor.vertex.module = moduleSampleMaskOutput;
+ descriptor.vertex.entryPoint = "vs";
+ descriptor.cFragment.module = moduleSampleMaskOutput;
+ descriptor.cFragment.entryPoint = "fsWithSampleMaskUsage";
+ descriptor.multisample.count = 4;
+ descriptor.multisample.alphaToCoverageEnabled = false;
+
+ ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
+ testing::HasSubstr("sample_mask"));
+ }
+}
+
} // anonymous namespace
} // namespace dawn