OpenGL: Disable scissor during blit for MSAA resolve
Change-Id: Ie0d093e94403faf6a95cd4f12e4b42eb0b48bd2c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/211254
Commit-Queue: James Godfrey-Kittle <jamesgk@google.com>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index ba3b8c2..08b2d51 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -492,6 +492,9 @@
const BeginRenderPassCmd* renderPass) {
DAWN_ASSERT(renderPass != nullptr);
+ // Reset state that may affect glBlitFramebuffer().
+ gl.Disable(GL_SCISSOR_TEST);
+
GLuint readFbo = 0;
GLuint writeFbo = 0;
@@ -517,6 +520,7 @@
}
}
+ gl.Enable(GL_SCISSOR_TEST);
gl.DeleteFramebuffers(1, &readFbo);
gl.DeleteFramebuffers(1, &writeFbo);
}
diff --git a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
index 9d237c3..2ec4169 100644
--- a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
+++ b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
@@ -1304,6 +1304,61 @@
}
}
+// Test that setting a scissor rect does not affect multisample resolve.
+TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithScissor) {
+ constexpr bool kTestDepth = false;
+ wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
+ wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
+
+ constexpr wgpu::Color kRed = {1.0f, 0.0f, 0.0f, 1.0f};
+ constexpr wgpu::Color kGreen = {0.0f, 1.0f, 0.0f, 1.0f};
+
+ // Draw a green triangle, set a scissor for the bottom row of pixels, then draw a red triangle.
+ {
+ utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
+ {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
+ kTestDepth);
+
+ const float redUniformData[4] = {1.0f, 0.0f, 0.0f, 1.0f};
+ const float greenUniformData[4] = {0.0f, 1.0f, 0.0f, 1.0f};
+ const size_t uniformSize = sizeof(float) * 4;
+
+ wgpu::Buffer redUniformBuffer = utils::CreateBufferFromData(
+ device, redUniformData, uniformSize, wgpu::BufferUsage::Uniform);
+ wgpu::Buffer greenUniformBuffer = utils::CreateBufferFromData(
+ device, greenUniformData, uniformSize, wgpu::BufferUsage::Uniform);
+
+ wgpu::BindGroup redBindGroup = utils::MakeBindGroup(
+ device, pipeline.GetBindGroupLayout(0), {{0, redUniformBuffer, 0, uniformSize}});
+ wgpu::BindGroup greenBindGroup = utils::MakeBindGroup(
+ device, pipeline.GetBindGroupLayout(0), {{0, greenUniformBuffer, 0, uniformSize}});
+
+ wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
+ renderPassEncoder.SetPipeline(pipeline);
+
+ renderPassEncoder.SetBindGroup(0, greenBindGroup);
+ renderPassEncoder.Draw(3);
+
+ renderPassEncoder.SetScissorRect(0, 0, 3, 1);
+ renderPassEncoder.SetBindGroup(0, redBindGroup);
+ renderPassEncoder.Draw(3);
+
+ renderPassEncoder.End();
+ }
+
+ wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
+ queue.Submit(1, &commandBuffer);
+
+ // The bottom-right pixel should be red, but the pixel just above it should be green.
+ constexpr float kMSAACoverage = 1.0f;
+ constexpr uint32_t kRedX = 2;
+ constexpr uint32_t kRedY = 0;
+ constexpr uint32_t kGreenX = 2;
+ constexpr uint32_t kGreenY = 1;
+ VerifyResolveTarget(kRed, mResolveTexture, 0, 0, kMSAACoverage, kRedX, kRedY);
+ VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage, kGreenX, kGreenY);
+}
+
class MultisampledRenderingWithTransientAttachmentTest : public MultisampledRenderingTest {
void SetUp() override {
MultisampledRenderingTest::SetUp();