// Copyright 2019 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <algorithm>
#include <array>
#include <vector>

#include "dawn/common/Assert.h"
#include "dawn/native/DawnNative.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

enum class PipelineMultisampleLoadOp {
    Ignore,
    ExpandResolveTarget,
    HasResolveTargetButLoadMultisampled,
};
using PipelineMultisampleLoadOps = std::array<PipelineMultisampleLoadOp, 16>;

class MultisampledRenderingTest : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();

        InitTexturesForTest();

        // TODO(crbug.com/468061892): Fails on Windows 11/NVIDIA GTX 1660.
        DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsNvidia() && IsD3D12() &&
                              IsBackendValidationEnabled());
    }

    void InitTexturesForTest() {
        mMultisampledColorTexture = CreateTextureForRenderAttachment(kColorFormat, kSampleCount);
        mMultisampledColorView = mMultisampledColorTexture.CreateView();
        mResolveTexture = CreateTextureForRenderAttachment(kColorFormat, 1);
        mResolveView = mResolveTexture.CreateView();

        mDepthStencilTexture = CreateTextureForRenderAttachment(kDepthStencilFormat, kSampleCount);
        mDepthStencilView = mDepthStencilTexture.CreateView();
    }

    wgpu::RenderPipeline CreateRenderPipelineWithOneOutputForTest(
        bool testDepth,
        uint32_t sampleMask = 0xFFFFFFFF,
        bool alphaToCoverageEnabled = false,
        bool flipTriangle = false,
        bool enableExpandResolveLoadOp = false) {
        const char* kFsOneOutputWithDepth = R"(
            struct U {
                color : vec4f,
                depth : f32,
            }
            @group(0) @binding(0) var<uniform> uBuffer : U;

            struct FragmentOut {
                @location(0) color : vec4f,
                @builtin(frag_depth) depth : f32,
            }

            @fragment fn main() -> FragmentOut {
                var output : FragmentOut;
                output.color = uBuffer.color;
                output.depth = uBuffer.depth;
                return output;
            })";

        const char* kFsOneOutputWithoutDepth = R"(
            struct U {
                color : vec4f
            }
            @group(0) @binding(0) var<uniform> uBuffer : U;

            @fragment fn main() -> @location(0) vec4f {
                return uBuffer.color;
            })";

        const char* fs = testDepth ? kFsOneOutputWithDepth : kFsOneOutputWithoutDepth;

        PipelineMultisampleLoadOps multisampleLoadOps{};
        if (enableExpandResolveLoadOp) {
            multisampleLoadOps[0] = PipelineMultisampleLoadOp::ExpandResolveTarget;
        }
        return CreateRenderPipelineForTest(fs, 1, testDepth, sampleMask, alphaToCoverageEnabled,
                                           flipTriangle, multisampleLoadOps);
    }

    wgpu::RenderPipeline CreateRenderPipelineWithTwoOutputsForTest(
        uint32_t sampleMask = 0xFFFFFFFF,
        bool alphaToCoverageEnabled = false,
        bool depthTest = false,
        PipelineMultisampleLoadOp loadOpForColor0 = PipelineMultisampleLoadOp::Ignore,
        PipelineMultisampleLoadOp loadOpForColor1 = PipelineMultisampleLoadOp::Ignore) {
        const char* kFsTwoOutputs = R"(
            struct U {
                color0 : vec4f,
                color1 : vec4f,
            }
            @group(0) @binding(0) var<uniform> uBuffer : U;

            struct FragmentOut {
                @location(0) color0 : vec4f,
                @location(1) color1 : vec4f,
            }

            @fragment fn main() -> FragmentOut {
                var output : FragmentOut;
                output.color0 = uBuffer.color0;
                output.color1 = uBuffer.color1;
                return output;
            })";

        PipelineMultisampleLoadOps multisampleLoadOps{};
        multisampleLoadOps[0] = loadOpForColor0;
        multisampleLoadOps[1] = loadOpForColor1;

        return CreateRenderPipelineForTest(kFsTwoOutputs, 2, depthTest, sampleMask,
                                           alphaToCoverageEnabled, /*flipTriangle=*/false,
                                           multisampleLoadOps);
    }

    wgpu::RenderPipeline CreateRenderPipelineWithNonZeroLocationOutputForTest(
        uint32_t sampleMask = 0xFFFFFFFF,
        bool alphaToCoverageEnabled = false,
        bool enableExpandResolveLoadOp = false) {
        const char* kFsNonZeroLocationOutputs = R"(
            struct U {
                color : vec4f
            }
            @group(0) @binding(0) var<uniform> uBuffer : U;

            @fragment fn main() -> @location(1) vec4f {
                return uBuffer.color;
            })";

        PipelineMultisampleLoadOps multisampleLoadOps{};
        if (enableExpandResolveLoadOp) {
            multisampleLoadOps[1] = PipelineMultisampleLoadOp::ExpandResolveTarget;
        }
        return CreateRenderPipelineForTest(kFsNonZeroLocationOutputs, 1, false, sampleMask,
                                           alphaToCoverageEnabled, /*flipTriangle=*/false,
                                           multisampleLoadOps, 1);
    }

    wgpu::Texture CreateTextureForRenderAttachment(wgpu::TextureFormat format,
                                                   uint32_t sampleCount,
                                                   uint32_t mipLevelCount = 1,
                                                   uint32_t arrayLayerCount = 1,
                                                   bool transientAttachment = false,
                                                   bool supportsTextureBinding = false,
                                                   bool supportsCopyDst = false,
                                                   uint32_t width = kWidth,
                                                   uint32_t height = kHeight) {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = width << (mipLevelCount - 1);
        descriptor.size.height = height << (mipLevelCount - 1);
        descriptor.size.depthOrArrayLayers = arrayLayerCount;
        descriptor.sampleCount = sampleCount;
        descriptor.format = format;
        descriptor.mipLevelCount = mipLevelCount;
        if (transientAttachment) {
            descriptor.usage =
                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment;
        } else {
            descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        }

        if (supportsTextureBinding) {
            descriptor.usage |= wgpu::TextureUsage::TextureBinding;
        }

        if (supportsCopyDst) {
            descriptor.usage |= wgpu::TextureUsage::CopyDst;
        }

        return device.CreateTexture(&descriptor);
    }

    void EncodeRenderPassForTest(wgpu::CommandEncoder commandEncoder,
                                 const wgpu::RenderPassDescriptor& renderPass,
                                 const wgpu::RenderPipeline& pipeline,
                                 const float* uniformData,
                                 uint32_t uniformDataSize) {
        wgpu::Buffer uniformBuffer = utils::CreateBufferFromData(
            device, uniformData, uniformDataSize, wgpu::BufferUsage::Uniform);
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                         {{0, uniformBuffer, 0, uniformDataSize}});

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(pipeline);
        renderPassEncoder.SetBindGroup(0, bindGroup);
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
    }

    void EncodeRenderPassForTest(wgpu::CommandEncoder commandEncoder,
                                 const wgpu::RenderPassDescriptor& renderPass,
                                 const wgpu::RenderPipeline& pipeline,
                                 const wgpu::Color& color) {
        const float uniformData[4] = {static_cast<float>(color.r), static_cast<float>(color.g),
                                      static_cast<float>(color.b), static_cast<float>(color.a)};
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, uniformData,
                                sizeof(float) * 4);
    }

    utils::ComboRenderPassDescriptor CreateComboRenderPassDescriptorForTest(
        std::initializer_list<wgpu::TextureView> colorViews,
        std::initializer_list<wgpu::TextureView> resolveTargetViews,
        wgpu::LoadOp colorLoadOp,
        wgpu::LoadOp depthStencilLoadOp,
        bool hasDepthStencilAttachment) {
        DAWN_ASSERT(colorViews.size() == resolveTargetViews.size());

        constexpr float kClearDepth = 1.0f;

        utils::ComboRenderPassDescriptor renderPass(colorViews);
        uint32_t i = 0;
        for (const wgpu::TextureView& resolveTargetView : resolveTargetViews) {
            renderPass.cColorAttachments[i].loadOp = colorLoadOp;
            renderPass.cColorAttachments[i].clearValue = kClearColor;
            renderPass.cColorAttachments[i].resolveTarget = resolveTargetView;
            ++i;
        }

        renderPass.cDepthStencilAttachmentInfo.depthClearValue = kClearDepth;
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = depthStencilLoadOp;

        if (hasDepthStencilAttachment) {
            renderPass.cDepthStencilAttachmentInfo.view = mDepthStencilView;
            renderPass.depthStencilAttachment = &renderPass.cDepthStencilAttachmentInfo;
        }

        return renderPass;
    }

    void VerifyResolveTarget(const wgpu::Color& inputColor,
                             wgpu::Texture resolveTexture,
                             uint32_t mipmapLevel = 0,
                             uint32_t arrayLayer = 0,
                             const float msaaCoverage = 0.5f,
                             uint32_t x = (kWidth - 1) / 2,
                             uint32_t y = (kHeight - 1) / 2) {
        utils::RGBA8 expectedColor = ExpectedMSAAColor(inputColor, msaaCoverage);
        EXPECT_TEXTURE_EQ(&expectedColor, resolveTexture, {x, y, arrayLayer}, {1, 1}, mipmapLevel,
                          wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                          /* tolerance */ utils::RGBA8(1, 1, 1, 1));
    }

    constexpr static uint32_t kWidth = 3;
    constexpr static uint32_t kHeight = 3;
    constexpr static uint32_t kSampleCount = 4;
    constexpr static wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
    constexpr static wgpu::TextureFormat kDepthStencilFormat =
        wgpu::TextureFormat::Depth24PlusStencil8;

    constexpr static uint32_t kFirstSampleMaskBit = 0x00000001;
    constexpr static uint32_t kSecondSampleMaskBit = 0x00000002;
    constexpr static uint32_t kThirdSampleMaskBit = 0x00000004;
    constexpr static uint32_t kFourthSampleMaskBit = 0x00000008;

    constexpr static wgpu::Color kClearColor = {0.0f, 0.0f, 0.0f, 0.0f};
    constexpr static wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};
    constexpr static wgpu::Color kRed = {0.8f, 0.0f, 0.0f, 0.8f};

    wgpu::Texture mMultisampledColorTexture;
    wgpu::TextureView mMultisampledColorView;
    wgpu::Texture mResolveTexture;
    wgpu::TextureView mResolveView;
    wgpu::Texture mDepthStencilTexture;
    wgpu::TextureView mDepthStencilView;

    wgpu::RenderPipeline CreateRenderPipelineForTest(
        const char* fs,
        uint32_t numColorAttachments,
        bool hasDepthStencilAttachment,
        uint32_t sampleMask = 0xFFFFFFFF,
        bool alphaToCoverageEnabled = false,
        bool flipTriangle = false,
        PipelineMultisampleLoadOps multisampleLoadOps = {},
        uint32_t firstAttachmentLocation = 0) {
        utils::ComboRenderPipelineDescriptor pipelineDescriptor;

        // Draw a bottom-right triangle. In standard 4xMSAA pattern, for the pixels on diagonal,
        // only two of the samples will be touched.
        const char* vs = R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec2f(-1.0,  1.0),
                    vec2f( 1.0,  1.0),
                    vec2f( 1.0, -1.0)
                );
                return vec4f(pos[VertexIndex], 0.0, 1.0);
            })";

        // Draw a bottom-left triangle.
        const char* vsFlipped = R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec2f(-1.0,  1.0),
                    vec2f( 1.0,  1.0),
                    vec2f(-1.0, -1.0)
                );
                return vec4f(pos[VertexIndex], 0.0, 1.0);
            })";

        if (flipTriangle) {
            pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, vsFlipped);
        } else {
            pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, vs);
        }

        pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, fs);

        if (hasDepthStencilAttachment) {
            wgpu::DepthStencilState* depthStencil =
                pipelineDescriptor.EnableDepthStencil(kDepthStencilFormat);
            depthStencil->depthWriteEnabled = wgpu::OptionalBool::True;
            depthStencil->depthCompare = wgpu::CompareFunction::Less;
        }

        pipelineDescriptor.multisample.count = kSampleCount;
        pipelineDescriptor.multisample.mask = sampleMask;
        pipelineDescriptor.multisample.alphaToCoverageEnabled = alphaToCoverageEnabled;

        pipelineDescriptor.cFragment.targetCount = numColorAttachments + firstAttachmentLocation;

        std::array<wgpu::ColorTargetStateExpandResolveTextureDawn, 16> msaaExpandResolveDescs;
        for (uint32_t i = 0; i < numColorAttachments + firstAttachmentLocation; ++i) {
            if (i < firstAttachmentLocation) {
                pipelineDescriptor.cTargets[i].writeMask = wgpu::ColorWriteMask::None;
                pipelineDescriptor.cTargets[i].format = wgpu::TextureFormat::Undefined;
            } else {
                pipelineDescriptor.cTargets[i].format = kColorFormat;
                if (multisampleLoadOps[i] != PipelineMultisampleLoadOp::Ignore) {
                    msaaExpandResolveDescs[i].enabled =
                        multisampleLoadOps[i] == PipelineMultisampleLoadOp::ExpandResolveTarget;
                    pipelineDescriptor.cTargets[i].nextInChain = &msaaExpandResolveDescs[i];
                }
            }
        }

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);
        return pipeline;
    }

    utils::RGBA8 ExpectedMSAAColor(const wgpu::Color color, const double msaaCoverage) {
        utils::RGBA8 result;
        result.r = static_cast<uint8_t>(std::min(255.0, 256 * color.r * msaaCoverage));
        result.g = static_cast<uint8_t>(std::min(255.0, 256 * color.g * msaaCoverage));
        result.b = static_cast<uint8_t>(std::min(255.0, 256 * color.b * msaaCoverage));
        result.a = static_cast<uint8_t>(std::min(255.0, 256 * color.a * msaaCoverage));
        return result;
    }
};

// Test using one multisampled color attachment with resolve target can render correctly.
TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    constexpr bool kTestDepth = false;
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);

    // storeOp should not affect the result in the resolve target.
    for (wgpu::StoreOp storeOp : {wgpu::StoreOp::Store, wgpu::StoreOp::Discard}) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

        // Draw a green triangle.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
                kTestDepth);
            renderPass.cColorAttachments[0].storeOp = storeOp;
            std::array<float, 4> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a};
            constexpr uint32_t kSize = sizeof(kUniformData);
            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(),
                                    kSize);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyResolveTarget(kGreen, mResolveTexture);
    }
}

// Test multisampled rendering with depth test works correctly.
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTest) {
    constexpr bool kTestDepth = true;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);

    // In first render pass we draw a green triangle with depth value == 0.2f.
    {
        utils::ComboRenderPassDescriptor renderPass =
            CreateComboRenderPassDescriptorForTest({mMultisampledColorView}, {mResolveView},
                                                   wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, true);
        std::array<float, 8> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a,  // Color
                                             0.2f};                                   // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In second render pass we draw a red triangle with depth value == 0.5f.
    // This red triangle should not be displayed because it is behind the green one that is drawn in
    // the last render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a,  // color
                                             0.5f};                           // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // The color of the pixel in the middle of mResolveTexture should be green if MSAA resolve runs
    // correctly with depth test.
    VerifyResolveTarget(kGreen, mResolveTexture);
}

// Test rendering into a multisampled color attachment and doing MSAA resolve in another render pass
// works correctly.
TEST_P(MultisampledRenderingTest, ResolveInAnotherRenderPass) {
    // TODO(dawn:1549) Fails on Qualcomm-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());

    constexpr bool kTestDepth = false;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);

    // In first render pass we draw a green triangle and do not set the resolve target.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {nullptr}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass we ony do MSAA resolve with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            kTestDepth);

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, mResolveTexture);
}

// Test doing MSAA resolve into multiple resolve targets works correctly.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargets) {
    // TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();
    wgpu::Texture resolveTexture2 = CreateTextureForRenderAttachment(kColorFormat, 1);
    wgpu::TextureView resolveView2 = resolveTexture2.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest();

    constexpr bool kTestDepth = false;

    // Draw a red triangle to the first color attachment, and a blue triangle to the second color
    // attachment, and do MSAA resolve on two render targets in one render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        std::array<float, 8> kUniformData = {
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, mResolveTexture);
    VerifyResolveTarget(kGreen, resolveTexture2);
}

// Test that resolving only one of multiple MSAA targets works correctly. (dawn:1550)
TEST_P(MultisampledRenderingTest, ResolveOneOfMultipleTargets) {
    // TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();

    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest();

    constexpr bool kTestDepth = false;

    std::array<float, 8> kUniformData = {
        static_cast<float>(kRed.r),   static_cast<float>(kRed.g),   static_cast<float>(kRed.b),
        static_cast<float>(kRed.a),   static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
        static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
    constexpr uint32_t kSize = sizeof(kUniformData);

    // Draws a red triangle to the first color attachment, and a blue triangle to the second color
    // attachment.

    // Do MSAA resolve on the first render target.
    {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {mResolveView, nullptr},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyResolveTarget(kRed, mResolveTexture);
    }

    // Do MSAA resolve on the second render target.
    {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {nullptr, mResolveView},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyResolveTarget(kGreen, mResolveTexture);
    }
}

// Test that resolving a single render target at a non-zero location works correctly.
TEST_P(MultisampledRenderingTest, ResolveIntoNonZeroLocation) {
    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();

    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithNonZeroLocationOutputForTest();

    constexpr bool kTestDepth = false;

    // Draws a red triangle to the first color attachment, and a blue triangle to the second color
    // attachment.

    // Do MSAA resolve on the first render target.
    {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {nullptr, mMultisampledColorView}, {nullptr, mResolveView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear, kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kRed);

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyResolveTarget(kRed, mResolveTexture);
    }
}

// Test doing MSAA resolve on one multisampled texture twice works correctly.
TEST_P(MultisampledRenderingTest, ResolveOneMultisampledTextureTwice) {
    // TODO(dawn:1549) Fails on Qualcomm-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());

    constexpr bool kTestDepth = false;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    wgpu::Texture resolveTexture2 = CreateTextureForRenderAttachment(kColorFormat, 1);

    // In first render pass we draw a green triangle and specify mResolveView as the resolve target.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass we do MSAA resolve into resolveTexture2.
    {
        wgpu::TextureView resolveView2 = resolveTexture2.CreateView();
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {resolveView2}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            kTestDepth);

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, mResolveTexture);
    VerifyResolveTarget(kGreen, resolveTexture2);
}

// Test using a layer of a 2D texture as resolve target works correctly.
TEST_P(MultisampledRenderingTest, ResolveIntoOneMipmapLevelOf2DTexture) {
    constexpr uint32_t kBaseMipLevel = 2;

    wgpu::TextureViewDescriptor textureViewDescriptor;
    textureViewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
    textureViewDescriptor.format = kColorFormat;
    textureViewDescriptor.baseArrayLayer = 0;
    textureViewDescriptor.arrayLayerCount = 1;
    textureViewDescriptor.mipLevelCount = 1;
    textureViewDescriptor.baseMipLevel = kBaseMipLevel;

    wgpu::Texture resolveTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, kBaseMipLevel + 1, 1);
    wgpu::TextureView resolveView = resolveTexture.CreateView(&textureViewDescriptor);

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};
    constexpr bool kTestDepth = false;

    // Draw a green triangle and do MSAA resolve.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {resolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, resolveTexture, kBaseMipLevel, 0);
}

// Test using a level or a layer of a 2D array texture as resolve target works correctly.
TEST_P(MultisampledRenderingTest, ResolveInto2DArrayTexture) {
    // TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));

    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();

    wgpu::TextureViewDescriptor baseTextureViewDescriptor;
    baseTextureViewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
    baseTextureViewDescriptor.format = kColorFormat;
    baseTextureViewDescriptor.arrayLayerCount = 1;
    baseTextureViewDescriptor.mipLevelCount = 1;

    // Create resolveTexture1 with only 1 mipmap level.
    constexpr uint32_t kBaseArrayLayer1 = 2;
    constexpr uint32_t kBaseMipLevel1 = 0;
    wgpu::Texture resolveTexture1 =
        CreateTextureForRenderAttachment(kColorFormat, 1, kBaseMipLevel1 + 1, kBaseArrayLayer1 + 1);
    wgpu::TextureViewDescriptor resolveViewDescriptor1 = baseTextureViewDescriptor;
    resolveViewDescriptor1.baseArrayLayer = kBaseArrayLayer1;
    resolveViewDescriptor1.baseMipLevel = kBaseMipLevel1;
    wgpu::TextureView resolveView1 = resolveTexture1.CreateView(&resolveViewDescriptor1);

    // Create resolveTexture2 with (kBaseMipLevel2 + 1) mipmap levels and resolve into its last
    // mipmap level.
    constexpr uint32_t kBaseArrayLayer2 = 5;
    constexpr uint32_t kBaseMipLevel2 = 3;
    wgpu::Texture resolveTexture2 =
        CreateTextureForRenderAttachment(kColorFormat, 1, kBaseMipLevel2 + 1, kBaseArrayLayer2 + 1);
    wgpu::TextureViewDescriptor resolveViewDescriptor2 = baseTextureViewDescriptor;
    resolveViewDescriptor2.baseArrayLayer = kBaseArrayLayer2;
    resolveViewDescriptor2.baseMipLevel = kBaseMipLevel2;
    wgpu::TextureView resolveView2 = resolveTexture2.CreateView(&resolveViewDescriptor2);

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest();

    constexpr bool kTestDepth = false;

    // Draw a red triangle to the first color attachment, and a green triangle to the second color
    // attachment, and do MSAA resolve on two render targets in one render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {resolveView1, resolveView2},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r,   kRed.g,   kRed.b,   kRed.a,     // color1
                                             kGreen.r, kGreen.g, kGreen.b, kGreen.a};  // color2
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, resolveTexture1, kBaseMipLevel1, kBaseArrayLayer1);
    VerifyResolveTarget(kGreen, resolveTexture2, kBaseMipLevel2, kBaseArrayLayer2);
}

// Test using one multisampled color attachment with resolve target can render correctly
// with a non-default sample mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMask) {
    constexpr bool kTestDepth = false;
    // The second and third samples are included,
    // only the second one is covered by the triangle.
    constexpr uint32_t kSampleMask = kSecondSampleMaskBit | kThirdSampleMaskBit;
    constexpr float kMSAACoverage = 0.25f;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMask);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // Draw a green triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage);
}

// Test using one multisampled color attachment with resolve target can render correctly
// with the final sample mask empty.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithEmptyFinalSampleMask) {
    constexpr bool kTestDepth = false;
    // The third and fourth samples are included,
    // none of which is covered by the triangle.
    constexpr uint32_t kSampleMask = kThirdSampleMaskBit | kFourthSampleMaskBit;
    constexpr float kMSAACoverage = 0.00f;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMask);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // Draw a green triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage);
}

// Test doing MSAA resolve into multiple resolve targets works correctly with a non-default sample
// mask.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMask) {
    /// TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));

    // TODO(crbug.com/454796308): Produces incorrect output on Mac/Intel with
    // the WebGPU on WebGPU on Metal backend.
    DAWN_SUPPRESS_TEST_IF(IsMacOS() && IsIntel() && IsWebGPUOn(wgpu::BackendType::Metal));

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();
    wgpu::Texture resolveTexture2 = CreateTextureForRenderAttachment(kColorFormat, 1);
    wgpu::TextureView resolveView2 = resolveTexture2.CreateView();

    // The first and fourth samples are included,
    // only the first one is covered by the triangle.
    constexpr uint32_t kSampleMask = kFirstSampleMaskBit | kFourthSampleMaskBit;
    constexpr float kMSAACoverage = 0.25f;

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest(kSampleMask);

    constexpr bool kTestDepth = false;

    // Draw a red triangle to the first color attachment, and a blue triangle to the second color
    // attachment, and do MSAA resolve on two render targets in one render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r,   kRed.g,   kRed.b,   kRed.a,     // color1
                                             kGreen.r, kGreen.g, kGreen.b, kGreen.a};  // color2
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // TODO(crbug.com/dawn/1462): Work around that a sample mask of zero is used for all
    // color targets except the last one.
    VerifyResolveTarget(
        HasToggleEnabled("no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target")
            ? wgpu::Color{}
            : kRed,
        mResolveTexture, 0, 0, kMSAACoverage);
    VerifyResolveTarget(kGreen, resolveTexture2, 0, 0, kMSAACoverage);
}

// Test multisampled rendering with depth test works correctly with a non-default sample mask.
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndSampleMask) {
    // TODO(dawn:1549) Fails on Qualcomm-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());

    constexpr bool kTestDepth = true;
    // The second sample is included in the first render pass and it's covered by the triangle.
    constexpr uint32_t kSampleMaskGreen = kSecondSampleMaskBit;
    // The first and second samples are included in the second render pass,
    // both are covered by the triangle.
    constexpr uint32_t kSampleMaskRed = kFirstSampleMaskBit | kSecondSampleMaskBit;
    constexpr float kMSAACoverage = 0.50f;

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipelineGreen =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMaskGreen);
    wgpu::RenderPipeline pipelineRed =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMaskRed);

    // In first render pass we draw a green triangle with depth value == 0.2f.
    // We will only write to the second sample.
    {
        utils::ComboRenderPassDescriptor renderPass =
            CreateComboRenderPassDescriptorForTest({mMultisampledColorView}, {mResolveView},
                                                   wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, true);
        std::array<float, 8> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a,  // Color
                                             0.2f};                                   // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipelineGreen, kUniformData.data(),
                                kSize);
    }

    // In second render pass we draw a red triangle with depth value == 0.5f.
    // We will only write to the first sample, since the second one is red with a smaller depth
    // value.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a,  // color
                                             0.5f};                           // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipelineRed, kUniformData.data(),
                                kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    constexpr wgpu::Color kHalfGreenHalfRed = {(kGreen.r + kRed.r) / 2.0, (kGreen.g + kRed.g) / 2.0,
                                               (kGreen.b + kRed.b) / 2.0,
                                               (kGreen.a + kRed.a) / 2.0};

    // The color of the pixel in the middle of mResolveTexture should be half green and half
    // red if MSAA resolve runs correctly with depth test.
    VerifyResolveTarget(kHalfGreenHalfRed, mResolveTexture, 0, 0, kMSAACoverage);
}

// Test using one multisampled color attachment with resolve target can render correctly
// with non-default sample mask and shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) {
    // sample_mask is not supported in compat.
    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());

    // TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not
    // supported on some platforms.
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_sample_variables"));

    constexpr bool kTestDepth = false;
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

    // The second and third samples are included in the shader-output mask.
    // The first and third samples are included in the sample mask.
    // Since we're now looking at a fully covered pixel, the rasterization mask
    // includes all the samples.
    // Thus the final mask includes only the third sample.
    constexpr float kMSAACoverage = 0.25f;
    constexpr uint32_t kSampleMask = kFirstSampleMaskBit | kThirdSampleMaskBit;
    const char* fs = R"(
        struct U {
            color : vec4f
        }
        @group(0) @binding(0) var<uniform> uBuffer : U;

        struct FragmentOut {
            @location(0) color : vec4f,
            @builtin(sample_mask) sampleMask : u32,
        }

        @fragment fn main() -> FragmentOut {
            var output : FragmentOut;
            output.color = uBuffer.color;
            output.sampleMask = 6u;
            return output;
        })";

    wgpu::RenderPipeline pipeline = CreateRenderPipelineForTest(fs, 1, false, kSampleMask);
    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // Draw a green triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    utils::RGBA8 expectedColor = ExpectedMSAAColor(kGreen, kMSAACoverage);
    EXPECT_TEXTURE_EQ(&expectedColor, mResolveTexture, {1, 0}, {1, 1});
}

// Test doing MSAA resolve into multiple resolve targets works correctly with a non-default
// shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithShaderOutputMask) {
    // sample_mask is not supported in compat.
    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());

    // TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not
    // supported on some platforms.
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_sample_variables"));

    // TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));

    // TODO(crbug.com/454796308): Produces incorrect output on Mac/Intel with
    // the WebGPU on WebGPU on Metal backend.
    DAWN_SUPPRESS_TEST_IF(IsMacOS() && IsIntel() && IsWebGPUOn(wgpu::BackendType::Metal));

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();
    wgpu::Texture resolveTexture2 = CreateTextureForRenderAttachment(kColorFormat, 1);
    wgpu::TextureView resolveView2 = resolveTexture2.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    // The second and third samples are included in the shader-output mask,
    // only the first one is covered by the triangle.
    constexpr float kMSAACoverage = 0.25f;
    const char* fs = R"(
        struct U {
            color0 : vec4f,
            color1 : vec4f,
        }
        @group(0) @binding(0) var<uniform> uBuffer : U;

        struct FragmentOut {
            @location(0) color0 : vec4f,
            @location(1) color1 : vec4f,
            @builtin(sample_mask) sampleMask : u32,
        }

        @fragment fn main() -> FragmentOut {
            var output : FragmentOut;
            output.color0 = uBuffer.color0;
            output.color1 = uBuffer.color1;
            output.sampleMask = 6u;
            return output;
        })";

    wgpu::RenderPipeline pipeline = CreateRenderPipelineForTest(fs, 2, false);
    constexpr bool kTestDepth = false;

    // Draw a red triangle to the first color attachment, and a blue triangle to the second color
    // attachment, and do MSAA resolve on two render targets in one render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r,   kRed.g,   kRed.b,   kRed.a,     // color1
                                             kGreen.r, kGreen.g, kGreen.b, kGreen.a};  // color2
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // TODO(crbug.com/dawn/1462): Work around that a sample mask of zero is used for all
    // color targets except the last one.
    VerifyResolveTarget(
        HasToggleEnabled("no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target")
            ? wgpu::Color{}
            : kRed,
        mResolveTexture, 0, 0, kMSAACoverage);
    VerifyResolveTarget(kGreen, resolveTexture2, 0, 0, kMSAACoverage);
}

// Test using one multisampled color attachment with resolve target can render correctly
// with alphaToCoverageEnabled.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithAlphaToCoverage) {
    // TODO(crbug.com/458113207): Flaky w/ WARP.
    DAWN_SUPPRESS_TEST_IF(IsWindows() && IsWARP());

    constexpr bool kTestDepth = false;
    constexpr uint32_t kSampleMask = 0xFFFFFFFF;
    constexpr bool kAlphaToCoverageEnabled = true;

    // Setting alpha <= 0 must result in alpha-to-coverage mask being empty.
    // Setting alpha = 0.5f should result in alpha-to-coverage mask including half the samples,
    // but this is not guaranteed by the spec. The Metal spec seems to guarantee that this is
    // indeed the case.
    // Setting alpha >= 1 must result in alpha-to-coverage mask being full.
    for (float alpha : {-1.0f, 0.0f, 0.5f, 1.0f, 2.0f}) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
            kTestDepth, kSampleMask, kAlphaToCoverageEnabled);

        const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, alpha};

        // Draw a green triangle.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
                kTestDepth);

            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        // For alpha = {0, 0.5, 1} we expect msaaCoverage to correspond to the value of alpha.
        float msaaCoverage = alpha;
        if (alpha < 0.0f) {
            msaaCoverage = 0.0f;
        }
        if (alpha > 1.0f) {
            msaaCoverage = 1.0f;
        }

        utils::RGBA8 expectedColor = ExpectedMSAAColor(kGreen, msaaCoverage);
        EXPECT_TEXTURE_EQ(&expectedColor, mResolveTexture, {1, 0}, {1, 1});
    }
}

// Test doing MSAA resolve into multiple resolve targets works correctly with
// alphaToCoverage. The alphaToCoverage mask is computed based on the alpha
// component of the first color render attachment.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithAlphaToCoverage) {
    // TODO(dawn:1550) Workaround introduces a bug on Qualcomm GPUs, but is necessary for ARM GPUs.
    DAWN_TEST_UNSUPPORTED_IF(IsAndroid() && IsQualcomm() &&
                             HasToggleEnabled("resolve_multiple_attachments_in_separate_passes"));

    // TODO(crbug.com/458113207): Flaky w/ WARP.
    DAWN_SUPPRESS_TEST_IF(IsWindows() && IsWARP());

    wgpu::TextureView multisampledColorView2 =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount).CreateView();
    wgpu::Texture resolveTexture2 = CreateTextureForRenderAttachment(kColorFormat, 1);
    wgpu::TextureView resolveView2 = resolveTexture2.CreateView();
    constexpr uint32_t kSampleMask = 0xFFFFFFFF;
    constexpr float kMSAACoverage = 0.50f;
    constexpr bool kAlphaToCoverageEnabled = true;

    // The alpha-to-coverage mask should not depend on the alpha component of the
    // second color render attachment.
    // We test alpha = 0.51f and 0.99f instead of 0.50f and 1.00f because there are some rounding
    // differences on QuadroP400 devices in that case.
    for (float alpha : {0.0f, 0.51f, 0.99f}) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPipeline pipeline =
            CreateRenderPipelineWithTwoOutputsForTest(kSampleMask, kAlphaToCoverageEnabled);

        constexpr wgpu::Color kRed = {0.8f, 0.0f, 0.0f, 0.51f};
        const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, alpha};
        constexpr bool kTestDepth = false;

        // Draw a red triangle to the first color attachment, and a blue triangle to the second
        // color attachment, and do MSAA resolve on two render targets in one render pass.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
                wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);

            std::array<float, 8> kUniformData = {
                static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
                static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
                static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
                static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
            constexpr uint32_t kSize = sizeof(kUniformData);
            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(),
                                    kSize);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        // Alpha to coverage affects both the color outputs, but the mask is computed
        // using only the first one.
        utils::RGBA8 expectedRed = ExpectedMSAAColor(kRed, kMSAACoverage);
        utils::RGBA8 expectedGreen = ExpectedMSAAColor(kGreen, kMSAACoverage);
        EXPECT_TEXTURE_EQ(&expectedRed, mResolveTexture, {1, 0}, {1, 1},
                          /* level */ 0, wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                          /* tolerance */ utils::RGBA8(1, 1, 1, 1));
        EXPECT_TEXTURE_EQ(&expectedGreen, resolveTexture2, {1, 0}, {1, 1},
                          /* level */ 0, wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                          /* tolerance */ utils::RGBA8(1, 1, 1, 1));
    }
}

// Test multisampled rendering with depth test works correctly with alphaToCoverage.
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndAlphaToCoverage) {
    // TODO(dawn:1549) Fails on Qualcomm-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());

    constexpr bool kTestDepth = true;
    constexpr uint32_t kSampleMask = 0xFFFFFFFF;

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipelineGreen =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMask, true);
    wgpu::RenderPipeline pipelineRed =
        CreateRenderPipelineWithOneOutputForTest(kTestDepth, kSampleMask, false);

    // We test alpha = 0.51f and 0.81f instead of 0.50f and 0.80f because there are some
    // rounding differences on QuadroP400 devices in that case.
    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.51f};
    constexpr wgpu::Color kRed = {0.8f, 0.0f, 0.0f, 0.81f};

    // In first render pass we draw a green triangle with depth value == 0.2f.
    // We will only write to half the samples since the alphaToCoverage mode
    // is enabled for that render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            kTestDepth);
        std::array<float, 8> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a,  // Color
                                             0.2f};                                   // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipelineGreen, kUniformData.data(),
                                kSize);
    }

    // In second render pass we draw a red triangle with depth value == 0.5f.
    // We will write to all the samples since the alphaToCoverageMode is diabled for
    // that render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            kTestDepth);

        std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a,  // color
                                             0.5f};                           // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipelineRed, kUniformData.data(),
                                kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    constexpr wgpu::Color kHalfGreenHalfRed = {(kGreen.r + kRed.r) / 2.0, (kGreen.g + kRed.g) / 2.0,
                                               (kGreen.b + kRed.b) / 2.0,
                                               (kGreen.a + kRed.a) / 2.0};
    utils::RGBA8 expectedColor = ExpectedMSAAColor(kHalfGreenHalfRed, 1.0f);

    EXPECT_TEXTURE_EQ(&expectedColor, mResolveTexture, {1, 0}, {1, 1},
                      /* level */ 0, wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                      /* tolerance */ utils::RGBA8(1, 1, 1, 1));
}

// Test using one multisampled color attachment with resolve target can render correctly
// with alphaToCoverageEnabled and a sample mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithAlphaToCoverageAndSampleMask) {
    // TODO(dawn:1550) Fails on ARM-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    // TODO(dawn:491): This doesn't work on non-Apple GPU Metal, because we're using both
    // the shader-output mask (emulting the sampleMask from RenderPipeline) and alpha-to-coverage
    // at the same time. See the issue: https://github.com/gpuweb/gpuweb/issues/959.
    DAWN_SUPPRESS_TEST_IF(IsMetal() && !IsApple());

    // TODO(crbug.com/458113207): Flaky w/ WARP.
    DAWN_SUPPRESS_TEST_IF(IsWindows() && IsWARP());

    constexpr bool kTestDepth = false;
    constexpr float kMSAACoverage = 0.50f;
    constexpr uint32_t kSampleMask = kFirstSampleMaskBit | kThirdSampleMaskBit;
    constexpr bool kAlphaToCoverageEnabled = true;

    // For those values of alpha we expect the proportion of samples to be covered
    // to correspond to the value of alpha.
    // We're assuming in the case of alpha = 0.50f that the implementation
    // dependendent algorithm will choose exactly one of the first and third samples.
    for (float alpha : {0.0f, 0.50f, 1.00f}) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
            kTestDepth, kSampleMask, kAlphaToCoverageEnabled);

        const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, alpha - 0.01f};

        // Draw a green triangle.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
                kTestDepth);

            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        utils::RGBA8 expectedColor = ExpectedMSAAColor(kGreen, kMSAACoverage * alpha);
        EXPECT_TEXTURE_EQ(&expectedColor, mResolveTexture, {1, 0}, {1, 1},
                          /* level */ 0, wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                          /* tolerance */ utils::RGBA8(1, 1, 1, 1));
    }
}

// Test using one multisampled color attachment with resolve target can render correctly
// with alphaToCoverageEnabled and a rasterization mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithAlphaToCoverageAndRasterizationMask) {
    // TODO(dawn:1550) Fails on ARM-based Android devices.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    // TODO(crbug.com/458113207): Flaky w/ WARP.
    DAWN_SUPPRESS_TEST_IF(IsWindows() && IsWARP());

    constexpr bool kTestDepth = false;
    constexpr float kMSAACoverage = 0.50f;
    constexpr uint32_t kSampleMask = 0xFFFFFFFF;
    constexpr bool kAlphaToCoverageEnabled = true;
    constexpr bool kFlipTriangle = true;

    // For those values of alpha we expect the proportion of samples to be covered
    // to correspond to the value of alpha.
    // We're assuming in the case of alpha = 0.50f that the implementation
    // dependendent algorithm will choose exactly one of the samples covered by the
    // triangle.
    for (float alpha : {0.0f, 0.50f, 1.00f}) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
            kTestDepth, kSampleMask, kAlphaToCoverageEnabled, kFlipTriangle);

        const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, alpha - 0.01f};

        // Draw a green triangle.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
                kTestDepth);

            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage * alpha);
    }
}

// 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 {};

// Test using one multisampled color transient attachment with resolve target can render correctly.
TEST_P(MultisampledRenderingWithTransientAttachmentTest, ResolveTransientAttachmentInto2DTexture) {
    constexpr bool kTestDepth = false;
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);

    auto transientMultisampledColorTexture =
        CreateTextureForRenderAttachment(kColorFormat, kSampleCount,
                                         /*mipLevelCount=*/1,
                                         /*arrayLayerCount=*/1,
                                         /*transientAttachment=*/true);
    auto transientMultisampledColorView = transientMultisampledColorTexture.CreateView();
    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

    // Draw a green triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {transientMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear, kTestDepth);

        // Note: It is not possible to store into a transient attachment.
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 4> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a};
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, mResolveTexture);
}

class MultisampledRenderToSingleSampledTest : public MultisampledRenderingTest {
    void SetUp() override {
        MultisampledRenderingTest::SetUp();

        // Skip all tests if the MSAARenderToSingleSampled feature is not supported.
        DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::MSAARenderToSingleSampled}));
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        std::vector<wgpu::FeatureName> requiredFeatures = {};
        if (SupportsFeatures({wgpu::FeatureName::MSAARenderToSingleSampled})) {
            requiredFeatures.push_back(wgpu::FeatureName::MSAARenderToSingleSampled);
        }
        return requiredFeatures;
    }
};

// Test rendering into a color attachment and start another render pass with LoadOp::Load
// will have the content preserved.
TEST_P(MultisampledRenderToSingleSampledTest, DrawThenLoad) {
    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false);

    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    wgpu::DawnRenderPassSampleCount renderPassSampleCount;
    renderPassSampleCount.sampleCount = kSampleCount;

    // In first render pass we draw a green triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.nextInChain = &renderPassSampleCount;

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass we only use LoadOp::Load with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            /*testDepth=*/false);
        renderPass.nextInChain = &renderPassSampleCount;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, singleSampledTexture);
}

// Test clear a color attachment (without implicit sample count) and start another render pass (with
// implicit sample count) with LoadOp::Load plus additional drawing works correctly. The final
// result should contain the combination of the loaded content from 1st pass and the 2nd pass.
TEST_P(MultisampledRenderToSingleSampledTest, ClearThenLoadThenDraw) {
    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false);

    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    constexpr wgpu::Color kRed = {1.0f, 0.0f, 0.0f, 1.0f};
    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    wgpu::DawnRenderPassSampleCount renderPassSampleCount;
    renderPassSampleCount.sampleCount = kSampleCount;

    // In first render pass we clear to red without using implicit sample count.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].clearValue = kRed;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    // In second render pass (with implicit sample count) we use LoadOp::Load then draw a green
    // triangle.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            /*testDepth=*/false);
        renderPass.nextInChain = &renderPassSampleCount;

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    auto commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    constexpr wgpu::Color kHalfGreenHalfRed = {(kGreen.r + kRed.r) / 2.0, (kGreen.g + kRed.g) / 2.0,
                                               (kGreen.b + kRed.b) / 2.0,
                                               (kGreen.a + kRed.a) / 2.0};
    utils::RGBA8 expectedColor = ExpectedMSAAColor(kHalfGreenHalfRed, 1.0f);

    EXPECT_TEXTURE_EQ(&expectedColor, singleSampledTexture, {1, 1}, {1, 1},
                      /* level */ 0, wgpu::TextureAspect::All, /* bytesPerRow */ 0,
                      /* tolerance */ utils::RGBA8(1, 1, 1, 1));
}

// Test multisampled rendering with depth test works correctly.
TEST_P(MultisampledRenderToSingleSampledTest, DrawWithDepthTest) {
    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false);

    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/true, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    wgpu::DawnRenderPassSampleCount renderPassSampleCount;
    renderPassSampleCount.sampleCount = kSampleCount;

    // In first render pass we draw a green triangle with depth value == 0.2f.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            /*testDepth=*/true);
        renderPass.nextInChain = &renderPassSampleCount;

        std::array<float, 8> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a,  // Color
                                             0.2f};                                   // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In second render pass we draw a red triangle with depth value == 0.5f.
    // This red triangle should not be displayed because it is behind the green one that is drawn in
    // the last render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {singleSampledTextureView}, {nullptr}, wgpu::LoadOp::Load, wgpu::LoadOp::Load,
            /*testDepth=*/true);
        renderPass.nextInChain = &renderPassSampleCount;

        std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a,  // color
                                             0.5f};                           // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // The color of the pixel in the middle of mResolveTexture should be green if MSAA resolve runs
    // correctly with depth test.
    VerifyResolveTarget(kGreen, singleSampledTexture);
}

struct Point {
    uint32_t x;
    uint32_t y;
    wgpu::Color color;
    float msaaCoverage = 1.0f;
};

class DawnLoadResolveTextureTest : public MultisampledRenderingTest {
  protected:
    void SetUp() override {
        MultisampledRenderingTest::SetUp();

        // Skip all tests if the DawnLoadResolveTexture feature is not supported.
        DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnLoadResolveTexture}));
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        std::vector<wgpu::FeatureName> requiredFeatures = {};
        if (SupportsFeatures({wgpu::FeatureName::DawnLoadResolveTexture})) {
            requiredFeatures.push_back(wgpu::FeatureName::DawnLoadResolveTexture);
        }
        if (SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture})) {
            requiredFeatures.push_back(wgpu::FeatureName::DawnPartialLoadResolveTexture);
        }
        if (SupportsFeatures({wgpu::FeatureName::TransientAttachments})) {
            requiredFeatures.push_back(wgpu::FeatureName::TransientAttachments);
        }
        return requiredFeatures;
    }

    bool HasResolveMultipleAttachmentInSeparatePassesToggle() {
        return HasToggleEnabled("resolve_multiple_attachments_in_separate_passes");
    }

    void TestExpandAndResolveWithRect(const wgpu::RenderPassDescriptorResolveRect& rect,
                                      const std::vector<Point>& points) {
        DAWN_TEST_UNSUPPORTED_IF(
            !SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

        const uint32_t resolveWidth = 8;
        const uint32_t resolveHeight = 8;
        auto multiSampledTexture =
            CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                             /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/false,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ resolveWidth,
                                             /*height*/ resolveHeight);
        auto multiSampledTextureView = multiSampledTexture.CreateView();

        const uint32_t approxMsaaWidth = 7;
        const uint32_t approxMsaaHeight = 7;
        auto approxMultiSampledTexture =
            CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                             /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/false,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ approxMsaaWidth,
                                             /*height*/ approxMsaaHeight);
        auto approxMultiSampledTextureView = approxMultiSampledTexture.CreateView();

        mResolveTexture =
            CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/true,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ resolveWidth,
                                             /*height*/ resolveHeight);
        auto singleSampledTextureView = mResolveTexture.CreateView();

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
            /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
            /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

        wgpu::RenderPipeline redPipeline = CreateRenderPipelineWithOneOutputForTest(
            /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
            /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

        // In first render pass we draw a red triangle. StoreOp=Discard to discard the MSAA
        // texture's content.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
                wgpu::LoadOp::Clear,
                /*hasDepthStencilAttachment=*/false);
            renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
            EncodeRenderPassForTest(commandEncoder, renderPass, redPipeline, kRed);
        }
        // In the second render pass, we draw a green triangle with LoadOp::ExpandResolveTexture. We
        // also specify a scissor rect requiring the pixels in the right and bottom edges untouched
        // during expanding and resolving.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {approxMultiSampledTextureView}, {singleSampledTextureView},
                wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
                /*hasDepthStencilAttachment=*/false);
            renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
            renderPass.nextInChain = &rect;
            EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyPoints(points);
    }

    // Test that wgpu::LoadOp::Clear or wgpu::LoadOp::Load works with
    // wgpu::RenderPassDescriptorResolveRect.
    void TestLoadOrClearThenPartialResolve(
        const wgpu::RenderPassDescriptorResolveRect& rect,
        const std::vector<Point>& points,
        wgpu::LoadOp loadOp,
        const wgpu::Color& initialColor,
        const std::optional<wgpu::Color>& userDrawColor = std::nullopt) {
        DAWN_TEST_UNSUPPORTED_IF(
            !SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

        constexpr uint32_t msaaWidth = 3;
        constexpr uint32_t msaaHeight = 3;
        constexpr uint32_t resolveWidth = 4;
        constexpr uint32_t resolveHeight = 4;

        auto multiSampledTexture =
            CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                             /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/false,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ msaaWidth,
                                             /*height*/ msaaHeight);
        auto multiSampledTextureView = multiSampledTexture.CreateView();

        mResolveTexture =
            CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/true,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ resolveWidth,
                                             /*height*/ resolveHeight);
        auto singleSampledTextureView = mResolveTexture.CreateView();

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

        // Initial clear of MSAA texture if loading.
        if (loadOp == wgpu::LoadOp::Load) {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {multiSampledTextureView}, {nullptr}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
                /*testDepth=*/false);
            renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
            renderPass.cColorAttachments[0].clearValue = initialColor;

            wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
            renderPassEncoder.End();
        }

        // Create render pass with configurable wgpu::LoadOp and
        // wgpu::RenderPassDescriptorResolveRect.
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {multiSampledTextureView}, {singleSampledTextureView}, loadOp, wgpu::LoadOp::Clear,
                /*testDepth=*/false);
            renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
            // The clearValue takes effect only when the load operation is set to
            // wgpu::LoadOp::Clear.
            renderPass.cColorAttachments[0].clearValue = initialColor;
            renderPass.nextInChain = &rect;
            if (userDrawColor) {
                wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
                    /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF,
                    /*alphaToCoverageEnabled=*/false,
                    /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);
                EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, *userDrawColor);
            } else {
                wgpu::RenderPassEncoder renderPassEncoder =
                    commandEncoder.BeginRenderPass(&renderPass);
                renderPassEncoder.End();
            }
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);

        VerifyPoints(points);
        // When no user drawing is performed (userDrawColor is not set) verify the entire MSAA
        // texture has uniform color (initialColor).
        if (!userDrawColor) {
            VerifyAllMSAAPointsOfSameColor(initialColor, multiSampledTexture);
        }
    }

    void VerifyPoints(const std::vector<Point>& points,
                      const std::optional<wgpu::Texture>& resolveTexture = std::nullopt) {
        const auto& texture = resolveTexture.value_or(mResolveTexture);
        for (const Point& point : points) {
            VerifyResolveTarget(point.color, texture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                                /*msaaCoverage=*/point.msaaCoverage, /*x=*/point.x, /*y=*/point.y);
        }
    }

    // Verify the points of an MSAA teture.
    void VerifyMSAAPoints(const std::vector<Point>& points, const wgpu::Texture& msaaTexture) {
        // Resolve the MSAA texture to single sampled texture.
        auto singleSampledTexture =
            CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1,
                                             /*transientAttachment=*/false,
                                             /*supportsTextureBinding=*/true,
                                             /*supportsCopyDst=*/false,
                                             /*width*/ msaaTexture.GetWidth(),
                                             /*height*/ msaaTexture.GetHeight());
        auto singleSampledTextureView = singleSampledTexture.CreateView();
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        {
            utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
                {msaaTexture.CreateView()}, {singleSampledTextureView}, wgpu::LoadOp::Load,
                wgpu::LoadOp::Clear,
                /*testDepth=*/false);
            renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

            wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
            renderPassEncoder.End();
        }

        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
        queue.Submit(1, &commandBuffer);
        VerifyPoints(points, singleSampledTexture);
    }

    // Verify all the points of an MSAA teture are of the same color.
    void VerifyAllMSAAPointsOfSameColor(const wgpu::Color& color,
                                        const wgpu::Texture& msaaTexture) {
        auto textureWidth = msaaTexture.GetWidth();
        auto textureHeight = msaaTexture.GetHeight();
        std::vector<Point> points(textureWidth * textureHeight);
        for (size_t i = 0; i < points.size(); ++i) {
            uint32_t x = i % (textureWidth);
            uint32_t y = i / (textureWidth);
            points[i] = {x, y, color};
        }
        VerifyMSAAPoints(points, msaaTexture);
    }

    void TestLoadOrClearThenPartialResolve(wgpu::LoadOp loadOp,
                                           const wgpu::Color& initialColor,
                                           const wgpu::Color& userDrawColor) {
        constexpr wgpu::Color kBlack = {0.0f, 0.0f, 0.0f, 0.0f};
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = 1;
        rect.colorOffsetY = 2;
        rect.resolveOffsetX = 2;
        rect.resolveOffsetY = 2;
        rect.width = 1;
        rect.height = 1;

        // Only the single point at coordinate {resolveOffsetX, resolveOffsetY} in the resolve
        // texture is modified. All other points in the resolve texture remain unchanged.
        std::vector<Point> points = {
            {1, 1, kBlack}, {2, 1, kBlack}, {3, 1, kBlack}, {1, 2, kBlack}, {2, 2, initialColor},
            {3, 2, kBlack}, {1, 3, kBlack}, {2, 3, kBlack}, {3, 3, kBlack},
        };

        // Test wgpu::LoadOp::Clear or wgpu::LoadOp::Load without user draw.
        TestLoadOrClearThenPartialResolve(rect, points, loadOp, initialColor);

        // If user draws, the resolve texture color is mixed with initial color and user draw color.
        const wgpu::Color finalColor = {
            (initialColor.r + userDrawColor.r) / 2.0, (initialColor.g + userDrawColor.g) / 2.0,
            (initialColor.b + userDrawColor.b) / 2.0, (initialColor.a + userDrawColor.a) / 2.0};
        points[4] = {2, 2, finalColor};
        rect.colorOffsetX = 1;
        rect.colorOffsetY = 1;

        // Test wgpu::LoadOp::Clear or wgpu::LoadOp::Load  with user draw.
        TestLoadOrClearThenPartialResolve(rect, points, loadOp, initialColor, userDrawColor);
    }
};

// Test rendering into a resolve texture then start another render pass with
// LoadOp::ExpandResolveTexture. The resolve texture will have its content preserved between
// passes.
TEST_P(DawnLoadResolveTextureTest, DrawThenLoad) {
    auto multiSampledTexture = CreateTextureForRenderAttachment(
        kColorFormat, 4, 1, 1,
        /*transientAttachment=*/device.HasFeature(wgpu::FeatureName::TransientAttachments),
        /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // In first render pass we draw a green triangle. StoreOp=Discard to discard the MSAA texture's
    // content.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass, we only use LoadOp::ExpandResolveTexture with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Load,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, singleSampledTexture);
}

// Test using ExpandResolveTexture load op for non-zero indexed attachment.
TEST_P(DawnLoadResolveTextureTest, DrawThenLoadNonZeroIndexedAttachment) {
    auto multiSampledTexture = CreateTextureForRenderAttachment(
        kColorFormat, 4, 1, 1,
        /*transientAttachment=*/device.HasFeature(wgpu::FeatureName::TransientAttachments),
        /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithNonZeroLocationOutputForTest(
        /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*enableExpandResolveLoadOp=*/false);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // In first render pass we draw a green triangle. StoreOp=Discard to discard the MSAA texture's
    // content.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {nullptr, multiSampledTextureView}, {nullptr, singleSampledTextureView},
            wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass, we only use LoadOp::ExpandResolveTexture with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {nullptr, multiSampledTextureView}, {nullptr, singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Load,
            /*testDepth=*/false);
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, singleSampledTexture);
}

// Test rendering into 2 attachments. The 1st attachment will use
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, TwoOutputsDrawThenLoadColor0) {
    // TODO(42240662): "resolve_multiple_attachments_in_separate_passes" is currently not working
    // with DawnLoadResolveTexture feature if there are more than one attachment.
    DAWN_TEST_UNSUPPORTED_IF(HasResolveMultipleAttachmentInSeparatePassesToggle());

    // TODO(383731610): multiple outputs are not working in compat mode.
    DAWN_SUPPRESS_TEST_IF(IsCompatibilityMode());

    auto multiSampledTexture1 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView1 = multiSampledTexture1.CreateView();

    auto multiSampledTexture2 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView2 = multiSampledTexture2.CreateView();

    auto singleSampledTexture1 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView1 = singleSampledTexture1.CreateView();

    auto singleSampledTexture2 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView2 = singleSampledTexture2.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest(
        /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false);

    // In first render pass:
    // - we draw a red triangle to attachment0. StoreOp=Discard to discard the MSAA texture's
    // content.
    // - we draw a green triangle to attachment1. StoreOp=Store.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Store;

        std::array<float, 8> kUniformData = {
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In second render pass:
    // - we only use LoadOp::ExpandResolveTexture for attachment0 with no draw call.
    // - we only use LoadOp::Load for attachment1 with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::Load;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, singleSampledTexture1);
    VerifyResolveTarget(kGreen, singleSampledTexture2);
}

// Test rendering into 2 attachments. The 2nd attachment will use
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, TwoOutputsDrawThenLoadColor1) {
    // TODO(42240662): "resolve_multiple_attachments_in_separate_passes" is currently not working
    // with DawnLoadResolveTexture feature if there are more than one attachment.
    DAWN_TEST_UNSUPPORTED_IF(HasResolveMultipleAttachmentInSeparatePassesToggle());

    // TODO(383731610): multiple outputs are not working in compat mode.
    DAWN_SUPPRESS_TEST_IF(IsCompatibilityMode());

    auto multiSampledTexture1 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView1 = multiSampledTexture1.CreateView();

    auto multiSampledTexture2 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView2 = multiSampledTexture2.CreateView();

    auto singleSampledTexture1 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView1 = singleSampledTexture1.CreateView();

    auto singleSampledTexture2 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView2 = singleSampledTexture2.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest(
        /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false);

    // In first render pass:
    // - we draw a red triangle to attachment0. StoreOp=Store.
    // - we draw a green triangle to attachment1. StoreOp=Discard.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In second render pass:
    // - we only use LoadOp::Load for attachment0 with no draw call.
    // - we only use LoadOp::ExpandResolveTexture for attachment1 with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Load;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, singleSampledTexture1);
    VerifyResolveTarget(kGreen, singleSampledTexture2);
}

// Test rendering into 2 attachments. The both attachments will use
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, TwoOutputsDrawThenLoadColor0AndColor1) {
    // TODO(42240662): "resolve_multiple_attachments_in_separate_passes" is currently not working
    // with DawnLoadResolveTexture feature if there are more than one attachment.
    DAWN_TEST_UNSUPPORTED_IF(HasResolveMultipleAttachmentInSeparatePassesToggle());

    auto multiSampledTexture1 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView1 = multiSampledTexture1.CreateView();

    auto multiSampledTexture2 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView2 = multiSampledTexture2.CreateView();

    auto singleSampledTexture1 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView1 = singleSampledTexture1.CreateView();

    auto singleSampledTexture2 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView2 = singleSampledTexture2.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest(
        /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false);

    // In first render pass:
    // - we draw a red triangle to attachment0. StoreOp=Discard.
    // - we draw a green triangle to attachment1. StoreOp=Discard.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In second render pass:
    // - we only use LoadOp::ExpandResolveTexture for attachment0 with no draw call.
    // - we only use LoadOp::ExpandResolveTexture for attachment1 with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, singleSampledTexture1);
    VerifyResolveTarget(kGreen, singleSampledTexture2);
}

// Test ExpandResolveTexture load op rendering with depth test works correctly.
TEST_P(DawnLoadResolveTextureTest, DrawWithDepthTest) {
    auto multiSampledTexture = CreateTextureForRenderAttachment(
        kColorFormat, 4, 1, 1,
        /*transientAttachment=*/device.HasFeature(wgpu::FeatureName::TransientAttachments),
        /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);

    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/true, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

    // In first render pass we clear the render pass without drawing anything
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    // In 2nd render pass we draw a green triangle with depth value == 0.2f.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a,  // Color
                                             0.2f};                                   // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In 3rd render pass we draw a red triangle with depth value == 0.5f.
    // This red triangle should not be displayed because it is behind the green one that is drawn in
    // the last render pass.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Load,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a,  // color
                                             0.5f};                           // depth
        constexpr uint32_t kSize = sizeof(kUniformData);
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // The color of the pixel in the middle of mResolveTexture should be green if MSAA resolve runs
    // correctly with depth test.
    VerifyResolveTarget(kGreen, singleSampledTexture);
}

// Test ExpandResolveTexture load op rendering with depth test works correctly with
// two outputs both use ExpandResolveTexture load op.
TEST_P(DawnLoadResolveTextureTest, TwoOutputsDrawWithDepthTestColor0AndColor1) {
    // TODO(42240662): "resolve_multiple_attachments_in_separate_passes" is currently not working
    // with DawnLoadResolveTexture feature if there are more than one attachment.
    DAWN_TEST_UNSUPPORTED_IF(HasResolveMultipleAttachmentInSeparatePassesToggle());

    auto multiSampledTexture1 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView1 = multiSampledTexture1.CreateView();

    auto multiSampledTexture2 = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                 /*transientAttachment=*/false,
                                                                 /*supportsTextureBinding=*/false);
    auto multiSampledTextureView2 = multiSampledTexture2.CreateView();

    auto singleSampledTexture1 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView1 = singleSampledTexture1.CreateView();

    auto singleSampledTexture2 =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView2 = singleSampledTexture2.CreateView();

    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithTwoOutputsForTest(
        /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*depthTest=*/true,
        /*loadOpForColor0=*/PipelineMultisampleLoadOp::ExpandResolveTarget,
        /*loadOpForColor1=*/PipelineMultisampleLoadOp::ExpandResolveTarget);

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

    // In first render pass we clear the render pass without drawing anything
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    // In 2nd render pass:
    // - we draw a red triangle to attachment0.
    // - we draw a green triangle to attachment1.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a),
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    // In 3rd render pass:
    // - we draw a green triangle to attachment0.
    // - we draw a red triangle to attachment1.
    // Both triangles should not pass the depth test.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView1, multiSampledTextureView2},
            {singleSampledTextureView1, singleSampledTextureView2},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Load,
            /*testDepth=*/true);
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::ExpandResolveTexture;
        renderPass.cColorAttachments[1].storeOp = wgpu::StoreOp::Discard;

        std::array<float, 8> kUniformData = {
            static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
            static_cast<float>(kGreen.b), static_cast<float>(kGreen.a),
            static_cast<float>(kRed.r),   static_cast<float>(kRed.g),
            static_cast<float>(kRed.b),   static_cast<float>(kRed.a)};
        constexpr uint32_t kSize = sizeof(kUniformData);

        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, singleSampledTexture1);
    VerifyResolveTarget(kGreen, singleSampledTexture2);
}

// Test rendering into a layer of a 2D array texture and load op=LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, DrawThenLoad2DArrayTextureLayer) {
    // Creating 2D view from 2D array texture is not supported in compat mode.
    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture = CreateTextureForRenderAttachment(
        kColorFormat, 1, 1, /*arrayCount=*/2, /*transientAttachment=*/false,
        /*supportsTextureBinding=*/true);
    wgpu::TextureViewDescriptor resolveViewDescriptor2;
    resolveViewDescriptor2.dimension = wgpu::TextureViewDimension::e2D;
    resolveViewDescriptor2.format = kColorFormat;
    resolveViewDescriptor2.baseArrayLayer = 1;
    resolveViewDescriptor2.baseMipLevel = 0;
    auto singleSampledTextureView = singleSampledTexture.CreateView(&resolveViewDescriptor2);

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // In first render pass we draw a green triangle. StoreOp=Discard to discard the MSAA texture's
    // content.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    // In second render pass, we only use LoadOp::ExpandResolveTexture with no draw call.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Load,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, singleSampledTexture, 0, 1);
}

// Test RenderPassDescriptorResolveRect works correctly
// when rendering with LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ClearThenLoadAndDrawWithRect) {
    DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};

    // In the first render pass we clear the attachment without drawing anything.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    // In the second render pass, we draw a green triangle with LoadOp::ExpandResolveTexture. We
    // also specify a scissor rect requiring the pixels in the right and bottom edges untouched
    // during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = rect.colorOffsetY = 0;
        rect.resolveOffsetX = rect.resolveOffsetY = 0;
        rect.width = kWidth - 1;
        rect.height = kHeight - 1;
        renderPass.nextInChain = &rect;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // Verify the center is green.
    VerifyResolveTarget(kGreen, singleSampledTexture);
    // Verify the right-bottom corner, which is outside the rect, stays untouched.
    VerifyResolveTarget(kClearColor, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/kWidth - 1, /*y=*/kHeight - 1);
}

// Test RenderPassDescriptorResolveRect works correctly with StoreOp::Discard.
TEST_P(DawnLoadResolveTextureTest, StoreOpDiscardWithRect) {
    DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/true);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline greenPipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    wgpu::RenderPipeline redPipelineWithExpandResolve = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    // In the first render pass, we draw a green triangle, and keep it stored in the multisampled
    // texture.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        EncodeRenderPassForTest(commandEncoder, renderPass, greenPipeline, kGreen);
    }

    // In the second render pass, we draw a red triangle with LoadOp::ExpandResolveTexture and
    // StoreOp::Discard. We also specify a scissor rect requiring the pixels in the right and bottom
    // edges untouched during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*testDepth=*/false);

        // Discard the multisampled texture at the end of this pass.
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = rect.colorOffsetY = 0;
        rect.resolveOffsetX = rect.resolveOffsetY = 0;
        rect.width = kWidth - 1;
        rect.height = kHeight - 1;
        renderPass.nextInChain = &rect;
        EncodeRenderPassForTest(commandEncoder, renderPass, redPipelineWithExpandResolve, kRed);
    }

    // The third render pass is simply a resolve pass so that we can check the contents of the
    // multisample via the resolve target. As the multisampled texture was discarded in the second
    // pass, it must be wholly cleared before being resolved into the singlesampled texture.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Load,
            wgpu::LoadOp::Clear,
            /*testDepth=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;

        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.End();
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    // The center, inside the rect, must be cleared.
    VerifyResolveTarget(kClearColor, singleSampledTexture);
    // The right-bottom corner, outside of the rect, must be cleared as well.
    VerifyResolveTarget(kClearColor, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/kWidth - 1, /*y=*/kHeight - 1);
}

// Test RenderPassDescriptorResolveRect works correctly when rendering with
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ExpandResolve) {
    DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    const uint32_t approxMsaaWidth = 3;
    const uint32_t approxMsaaHeight = 3;
    auto approxMultiSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                         /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/false,
                                         /*supportsCopyDst=*/false,
                                         /*width*/ approxMsaaWidth,
                                         /*height*/ approxMsaaHeight);
    auto approxMultiSampledTextureView = approxMultiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    wgpu::RenderPipeline redPipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    // In first render pass we draw a red triangle. StoreOp=Discard to discard the MSAA texture's
    // content.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        EncodeRenderPassForTest(commandEncoder, renderPass, redPipeline, kRed);
    }

    // In the second render pass, we draw a green triangle with LoadOp::ExpandResolveTexture. We
    // also specify a scissor rect requiring the pixels in the right and bottom edges untouched
    // during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {approxMultiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = rect.colorOffsetY = 1;
        rect.resolveOffsetX = rect.resolveOffsetY = 1;
        rect.width = rect.height = 2;
        renderPass.nextInChain = &rect;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kRed, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/1, /*y=*/0);
    VerifyResolveTarget(kRed, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/2, /*y=*/0);
    VerifyResolveTarget(kGreen, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/2, /*y=*/1);
}

// Test RenderPassDescriptorResolveRect works correctly when rendering at different offset with
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ExpandResolveDifferentOffset) {
    DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    const uint32_t approxMsaaWidth = 5;
    const uint32_t approxMsaaHeight = 5;
    auto approxMultiSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                         /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/false,
                                         /*supportsCopyDst=*/false,
                                         /*width*/ approxMsaaWidth,
                                         /*height*/ approxMsaaHeight);
    auto approxMultiSampledTextureView = approxMultiSampledTexture.CreateView();

    auto singleSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true);
    auto singleSampledTextureView = singleSampledTexture.CreateView();

    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    wgpu::RenderPipeline redPipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/false);

    // In first render pass we draw a red triangle. StoreOp=Discard to discard the MSAA texture's
    // content.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {multiSampledTextureView}, {singleSampledTextureView}, wgpu::LoadOp::Clear,
            wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        EncodeRenderPassForTest(commandEncoder, renderPass, redPipeline, kRed);
    }

    // In the second render pass, we draw a green triangle with LoadOp::ExpandResolveTexture. We
    // also specify a scissor rect requiring the pixels in the right and bottom edges touched
    // during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {approxMultiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = rect.colorOffsetY = 1;
        rect.resolveOffsetX = rect.resolveOffsetY = 0;
        rect.width = rect.height = 2;
        renderPass.nextInChain = &rect;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);

    VerifyResolveTarget(kGreen, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/1, /*y=*/0);
    VerifyResolveTarget(kRed, singleSampledTexture, /*mipmapLevel=*/0, /*arrayLayer=*/0,
                        /*msaaCoverage=*/1.0f, /*x=*/2, /*y=*/1);
}

// Test RenderPassDescriptorResolveRect works correctly when texture as input with
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ExpandResolveTextureAsInput) {
    DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DawnPartialLoadResolveTexture}));

    const uint32_t resolveWidth = 5;
    const uint32_t resolveHeight = 5;
    const uint32_t updateSize = 2;
    mResolveTexture =
        CreateTextureForRenderAttachment(kColorFormat, 1, 1, 1, /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/true,
                                         /*supportsCopyDst*/ true,
                                         /*width*/ resolveWidth,
                                         /*height*/ resolveHeight);
    auto singleSampledTextureView = mResolveTexture.CreateView();

    wgpu::TexelCopyTextureInfo dst = {};
    dst.texture = mResolveTexture;
    std::array<utils::RGBA8, resolveWidth * resolveHeight> rgbaTextureData;
    for (size_t i = 0; i < rgbaTextureData.size(); ++i) {
        rgbaTextureData[i] = utils::RGBA8(0, 0, 0, 255);
    }
    rgbaTextureData[1] = utils::RGBA8(255, 0, 0, 255);
    rgbaTextureData[resolveWidth] = utils::RGBA8(0, 255, 0, 255);
    rgbaTextureData[resolveWidth + 1] = utils::RGBA8(0, 0, 255, 255);
    rgbaTextureData[resolveWidth * 2 + updateSize] = utils::RGBA8(255, 0, 255, 255);
    rgbaTextureData[resolveWidth * 2 + updateSize + 1] = utils::RGBA8(255, 255, 0, 255);
    rgbaTextureData[resolveWidth * 3 + updateSize] = utils::RGBA8(0, 0, 255, 255);
    rgbaTextureData[resolveWidth * 3 + updateSize + 1] = utils::RGBA8(0, 0, 255, 255);
    wgpu::TexelCopyBufferLayout dataLayout = {};
    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size = {resolveWidth, resolveHeight, 1};
    dataLayout.bytesPerRow = textureDesc.size.width * sizeof(utils::RGBA8);
    queue.WriteTexture(&dst, rgbaTextureData.data(), rgbaTextureData.size() * sizeof(utils::RGBA8),
                       &dataLayout, &textureDesc.size);

    auto multiSampledTexture = CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                                                /*transientAttachment=*/false,
                                                                /*supportsTextureBinding=*/false);
    auto multiSampledTextureView = multiSampledTexture.CreateView();

    const uint32_t approxMsaaWidth = 6;
    const uint32_t approxMsaaHeight = 6;
    auto approxMultiSampledTexture =
        CreateTextureForRenderAttachment(kColorFormat, 4, 1, 1,
                                         /*transientAttachment=*/false,
                                         /*supportsTextureBinding=*/false,
                                         /*supportsCopyDst=*/false,
                                         /*width*/ approxMsaaWidth,
                                         /*height*/ approxMsaaHeight);
    auto approxMultiSampledTextureView = approxMultiSampledTexture.CreateView();
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(
        /*testDepth=*/false, /*sampleMask=*/0xFFFFFFFF, /*alphaToCoverageEnabled=*/false,
        /*flipTriangle=*/false, /*enableExpandResolveLoadOp=*/true);

    // In the first render pass, we draw a green triangle with LoadOp::ExpandResolveTexture. We
    // also specify a scissor rect requiring the pixels in the left and top edges touched
    // during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {approxMultiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = rect.colorOffsetY = 0;
        rect.resolveOffsetX = rect.resolveOffsetY = 0;
        rect.width = rect.height = updateSize;
        renderPass.nextInChain = &rect;
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
    }
    // In the second render pass, we draw a blue triangle with LoadOp::ExpandResolveTexture. We
    // also specify a scissor rect requiring the pixels in the middle touched
    // during expanding and resolving.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
            {approxMultiSampledTextureView}, {singleSampledTextureView},
            wgpu::LoadOp::ExpandResolveTexture, wgpu::LoadOp::Clear,
            /*hasDepthStencilAttachment=*/false);
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        wgpu::RenderPassDescriptorResolveRect rect{};
        rect.colorOffsetX = 3;
        rect.colorOffsetY = 4;
        rect.resolveOffsetX = 1;
        rect.resolveOffsetY = 2;
        rect.width = rect.height = updateSize;
        renderPass.nextInChain = &rect;
        constexpr wgpu::Color kBlue = {0.0f, 0.0f, 0.8f, 0.8f};
        EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kBlue);
    }

    wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
    queue.Submit(1, &commandBuffer);
    std::vector<Point> points = {
        {1, 0, kGreen},
        {0, 1, {0.0f, 1.0f, 0.0f, 1.0f}},
        {3, 2, {1.0f, 1.0f, 0.0f, 1.0f}},
        {2, 3, {0.0f, 0.0f, 1.0f, 1.0f}},
        {1, 2, {0.0f, 0.0f, 0.0f, 1.0f}},
        {2, 1, {0.0f, 0.0f, 0.0f, 1.0f}},
    };
    VerifyPoints(points);
}

// Test RenderPassDescriptorResolveRect works correctly with smaller msaa texture when rendering
// with LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ExpandResolveWithSmallerMSAATexture) {
    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = 3;
    rect.height = 3;

    std::vector<Point> points = {
        {1, 0, kGreen},
        {2, 0, kGreen},
        {2, 1, kGreen},
        {3, 0, kRed},
    };
    TestExpandAndResolveWithRect(rect, points);
}

// Test RenderPassDescriptorResolveRect works correctly with non zero offset when rendering with
// LoadOp::ExpandResolveTexture.
TEST_P(DawnLoadResolveTextureTest, ExpandResolveDifferentNonZeroOffsetsWithSmallerMSAATexture) {
    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = 1;
    rect.colorOffsetY = 2;
    rect.resolveOffsetX = 3;
    rect.resolveOffsetY = 4;
    rect.width = 3;
    rect.height = 3;
    std::vector<Point> points = {
        {5, 4, kGreen},
    };
    TestExpandAndResolveWithRect(rect, points);
    points = {
        {4, 4, kGreen},
    };
    // Test when resolveOffsetX - colorOffsetX and resolveOffsetY - colorOffsetY are different.
    rect.resolveOffsetX = 2;
    TestExpandAndResolveWithRect(rect, points);
}

// Test that RenderPassDescriptorResolveRect works with wgpu::LoadOp::Clear.
TEST_P(DawnLoadResolveTextureTest, ClearThenPartialResolve) {
    TestLoadOrClearThenPartialResolve(wgpu::LoadOp::Clear, /*initialColor*/ kRed,
                                      /*userDrawColor*/ kGreen);
}

// Test that RenderPassDescriptorResolveRect works with wgpu::LoadOp::Load.
TEST_P(DawnLoadResolveTextureTest, LoadThenPartialResolve) {
    TestLoadOrClearThenPartialResolve(wgpu::LoadOp::Clear, /*initialColor*/ kGreen,
                                      /*userDrawColor*/ kRed);
}

DAWN_INSTANTIATE_TEST(MultisampledRenderingTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      D3D12Backend({}, {"use_d3d12_resource_heap_tier2"}),
                      D3D12Backend({}, {"use_d3d12_render_pass"}),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      WebGPUBackend(),
                      VulkanBackend(),
                      VulkanBackend({"always_resolve_into_zero_level_and_layer"}),
                      VulkanBackend({"resolve_multiple_attachments_in_separate_passes"}),
                      MetalBackend({"emulate_store_and_msaa_resolve"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer",
                                    "emulate_store_and_msaa_resolve"}));

DAWN_INSTANTIATE_TEST(MultisampledRenderingWithTransientAttachmentTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      D3D12Backend({}, {"use_d3d12_resource_heap_tier2"}),
                      D3D12Backend({}, {"use_d3d12_render_pass"}),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      WebGPUBackend(),
                      VulkanBackend(),
                      VulkanBackend({"always_resolve_into_zero_level_and_layer"}),
                      VulkanBackend({"resolve_multiple_attachments_in_separate_passes"}),
                      MetalBackend({"emulate_store_and_msaa_resolve"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer",
                                    "emulate_store_and_msaa_resolve"}));

DAWN_INSTANTIATE_TEST(MultisampledRenderToSingleSampledTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      D3D12Backend({}, {"use_d3d12_resource_heap_tier2"}),
                      D3D12Backend({}, {"use_d3d12_render_pass"}),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      WebGPUBackend(),
                      VulkanBackend(),
                      VulkanBackend({"always_resolve_into_zero_level_and_layer"}),
                      VulkanBackend({"resolve_multiple_attachments_in_separate_passes"}),
                      MetalBackend({"emulate_store_and_msaa_resolve"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer",
                                    "emulate_store_and_msaa_resolve"}));

DAWN_INSTANTIATE_TEST(DawnLoadResolveTextureTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      D3D12Backend({}, {"use_d3d12_resource_heap_tier2"}),
                      D3D12Backend({}, {"use_d3d12_render_pass"}),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      WebGPUBackend(),
                      VulkanBackend(),
                      VulkanBackend({"always_resolve_into_zero_level_and_layer"}),
                      VulkanBackend({"resolve_multiple_attachments_in_separate_passes"}),
                      MetalBackend({"emulate_store_and_msaa_resolve"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer"}),
                      MetalBackend({"always_resolve_into_zero_level_and_layer",
                                    "emulate_store_and_msaa_resolve"}));

}  // anonymous namespace
}  // namespace dawn
