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 <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Austin Eng 2019-04-12 17:43:05 +00:00 committed by Commit Bot service account
parent 0c227e21d1
commit bff933affc
2 changed files with 61 additions and 0 deletions

View File

@ -657,6 +657,7 @@ namespace dawn_native { namespace opengl {
// Load op - color // Load op - color
if (attachmentInfo.loadOp == dawn::LoadOp::Clear) { if (attachmentInfo.loadOp == dawn::LoadOp::Clear) {
glColorMaski(i, true, true, true, true);
glClearBufferfv(GL_COLOR, i, &attachmentInfo.clearColor.r); glClearBufferfv(GL_COLOR, i, &attachmentInfo.clearColor.r);
} }
} }

View File

@ -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<RGBA8, 1>({{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); DAWN_INSTANTIATE_TEST(ColorStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);