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();