From bff933affcffd6d907c5356237668ba755d4e266 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Fri, 12 Apr 2019 17:43:05 +0000 Subject: [PATCH] Clear glColorMask at the start of a RenderPass for LoadOp::Clear attachments Bug: dawn:133 Change-Id: Id8c6180f7a9ef2f7901aca6690d611fad4f13beb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6560 Commit-Queue: Kai Ninomiya Reviewed-by: Corentin Wallez Reviewed-by: Kai Ninomiya --- src/dawn_native/opengl/CommandBufferGL.cpp | 1 + src/tests/end2end/ColorStateTests.cpp | 60 ++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index 5b7e968adb..b2fecc4b7c 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp @@ -657,6 +657,7 @@ namespace dawn_native { namespace opengl { // Load op - color if (attachmentInfo.loadOp == dawn::LoadOp::Clear) { + glColorMaski(i, true, true, true, true); glClearBufferfv(GL_COLOR, i, &attachmentInfo.clearColor.r); } } diff --git a/src/tests/end2end/ColorStateTests.cpp b/src/tests/end2end/ColorStateTests.cpp index e83a57a37e..f71a5deaae 100644 --- a/src/tests/end2end/ColorStateTests.cpp +++ b/src/tests/end2end/ColorStateTests.cpp @@ -1001,4 +1001,64 @@ TEST_P(ColorStateTest, DefaultBlendColor) { } } +// This tests a problem in the OpenGL backend where a previous color write mask +// persisted and prevented a render pass loadOp from fully clearing the output +// attachment. +TEST_P(ColorStateTest, ColorWriteMaskDoesNotAffectRenderPassLoadOpClear) { + dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( + #version 450 + layout(set = 0, binding = 0) uniform myBlock { + vec4 color; + } myUbo; + + layout(location = 0) out vec4 fragColor; + + void main() { + fragColor = myUbo.color; + } + )"); + + utils::ComboRenderPipelineDescriptor baseDescriptor(device); + baseDescriptor.layout = pipelineLayout; + baseDescriptor.cVertexStage.module = vsModule; + baseDescriptor.cFragmentStage.module = fsModule; + baseDescriptor.cColorStates[0]->format = renderPass.colorFormat; + + basePipeline = device.CreateRenderPipeline(&baseDescriptor); + + utils::ComboRenderPipelineDescriptor testDescriptor(device); + testDescriptor.layout = pipelineLayout; + testDescriptor.cVertexStage.module = vsModule; + testDescriptor.cFragmentStage.module = fsModule; + testDescriptor.cColorStates[0]->format = renderPass.colorFormat; + testDescriptor.cColorStates[0]->colorWriteMask = dawn::ColorWriteMask::Red; + + testPipeline = device.CreateRenderPipeline(&testDescriptor); + + RGBA8 base(32, 64, 128, 192); + RGBA8 expected(0, 0, 0, 0); + + dawn::CommandEncoder encoder = device.CreateCommandEncoder(); + { + // Clear the output attachment to |base| + dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); + pass.SetPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({{base}})), 0, nullptr); + pass.Draw(3, 1, 0, 0); + + // Set a pipeline that will dirty the color write mask + pass.SetPipeline(testPipeline); + pass.EndPass(); + } + { + // This renderpass' loadOp should clear all channels of the output attachment + dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); + pass.EndPass(); + } + dawn::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); + + EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2); +} + DAWN_INSTANTIATE_TEST(ColorStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);