Allow writeMask==0 && format==undefined when the shader outputs the target

The WebGPU spec says that a validation error is produced if there is a
color target in the pipeline descriptor that has writeMask!=0 while
there are no shader outputs for this target. In Dawn format==undefined
is used as a tag that the color target is not present, so writeMask is
allowed to be 0 if format==undefined. (the validation in the case where
format!=undefined was already present).

Fixed: dawn:1376
Change-Id: I7737b6557223e0fc31740fd4ec2cbfaa54b77a71
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90040
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
This commit is contained in:
Corentin Wallez 2022-05-12 18:09:46 +00:00 committed by Dawn LUCI CQ
parent e2d7f86872
commit c9ebe9104d
2 changed files with 20 additions and 19 deletions

View File

@ -348,10 +348,6 @@ MaybeError ValidateFragmentState(DeviceBase* device,
DAWN_INVALID_IF(target->blend, DAWN_INVALID_IF(target->blend,
"Color target[%u] blend state is set when the format is undefined.", "Color target[%u] blend state is set when the format is undefined.",
static_cast<uint8_t>(i)); static_cast<uint8_t>(i));
DAWN_INVALID_IF(
target->writeMask != wgpu::ColorWriteMask::None,
"Color target[%u] write mask is set to (%s) when the format is undefined.",
static_cast<uint8_t>(i), target->writeMask);
} }
} }

View File

@ -194,8 +194,8 @@ TEST_F(RenderPipelineValidationTest, ColorTargetStateRequired) {
} }
} }
// Tests that target blend and writeMasks must not be set if the format is undefined. // Tests that target blend must not be set if the format is undefined.
TEST_F(RenderPipelineValidationTest, UndefinedColorStateFormatWithBlendOrWriteMask) { TEST_F(RenderPipelineValidationTest, UndefinedColorStateFormatWithBlend) {
{ {
// Control case: Valid undefined format target. // Control case: Valid undefined format target.
utils::ComboRenderPipelineDescriptor descriptor; utils::ComboRenderPipelineDescriptor descriptor;
@ -203,7 +203,6 @@ TEST_F(RenderPipelineValidationTest, UndefinedColorStateFormatWithBlendOrWriteMa
descriptor.cFragment.module = fsModule; descriptor.cFragment.module = fsModule;
descriptor.cFragment.targetCount = 1; descriptor.cFragment.targetCount = 1;
descriptor.cTargets[0].format = wgpu::TextureFormat::Undefined; descriptor.cTargets[0].format = wgpu::TextureFormat::Undefined;
descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
device.CreateRenderPipeline(&descriptor); device.CreateRenderPipeline(&descriptor);
} }
@ -221,19 +220,25 @@ TEST_F(RenderPipelineValidationTest, UndefinedColorStateFormatWithBlendOrWriteMa
device.CreateRenderPipeline(&descriptor), device.CreateRenderPipeline(&descriptor),
testing::HasSubstr("Color target[0] blend state is set when the format is undefined.")); testing::HasSubstr("Color target[0] blend state is set when the format is undefined."));
} }
{ }
// Error case: undefined format target with write masking not being none.
utils::ComboRenderPipelineDescriptor descriptor;
descriptor.vertex.module = vsModule;
descriptor.cFragment.module = fsModule;
descriptor.cFragment.targetCount = 1;
descriptor.cTargets[0].format = wgpu::TextureFormat::Undefined;
descriptor.cTargets[0].blend = nullptr;
descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::All;
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor), // Tests that a color target that's present in the pipeline descriptor but not in the shader must
testing::HasSubstr("Color target[0] write mask is set to")); // have its writeMask set to 0.
} TEST_F(RenderPipelineValidationTest, WriteMaskMustBeZeroForColorTargetWithNoShaderOutput) {
utils::ComboRenderPipelineDescriptor descriptor;
descriptor.vertex.module = vsModule;
descriptor.cFragment.module = fsModule;
descriptor.cFragment.targetCount = 2;
descriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
descriptor.cTargets[1].format = wgpu::TextureFormat::RGBA8Unorm;
// Control case: Target 1 not output by the shader but has writeMask = 0
descriptor.cTargets[1].writeMask = wgpu::ColorWriteMask::None;
device.CreateRenderPipeline(&descriptor);
// Error case: the writeMask is not 0.
descriptor.cTargets[1].writeMask = wgpu::ColorWriteMask::Red;
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
} }
// Tests that the color formats must be renderable. // Tests that the color formats must be renderable.