// Copyright 2018 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 <cmath>
#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/ComboRenderBundleEncoderDescriptor.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

class RenderPassDescriptorValidationTest : public ValidationTest {
  public:
    void AssertBeginRenderPassSuccess(const wgpu::RenderPassDescriptor* descriptor) {
        wgpu::CommandEncoder commandEncoder = TestBeginRenderPass(descriptor);
        commandEncoder.Finish();
    }
    void AssertBeginRenderPassError(const wgpu::RenderPassDescriptor* descriptor) {
        wgpu::CommandEncoder commandEncoder = TestBeginRenderPass(descriptor);
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }

    void AssertBeginRenderPassError(const wgpu::RenderPassDescriptor* descriptor,
                                    testing::Matcher<std::string> errorMatcher) {
        wgpu::CommandEncoder commandEncoder = TestBeginRenderPass(descriptor);
        ASSERT_DEVICE_ERROR(commandEncoder.Finish(), errorMatcher);
    }

  private:
    wgpu::CommandEncoder TestBeginRenderPass(const wgpu::RenderPassDescriptor* descriptor) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(descriptor);
        renderPassEncoder.End();
        return commandEncoder;
    }
};

wgpu::Texture CreateTexture(wgpu::Device& device,
                            wgpu::TextureDimension dimension,
                            wgpu::TextureFormat format,
                            uint32_t width,
                            uint32_t height,
                            uint32_t arrayLayerCount,
                            uint32_t mipLevelCount,
                            uint32_t sampleCount = 1,
                            wgpu::TextureUsage usage = wgpu::TextureUsage::RenderAttachment) {
    wgpu::TextureDescriptor descriptor;
    descriptor.dimension = dimension;
    descriptor.size.width = width;
    descriptor.size.height = height;
    descriptor.size.depthOrArrayLayers = arrayLayerCount;
    descriptor.sampleCount = sampleCount;
    descriptor.format = format;
    descriptor.mipLevelCount = mipLevelCount;
    descriptor.usage = usage;

    return device.CreateTexture(&descriptor);
}

wgpu::TextureView Create2DAttachment(wgpu::Device& device,
                                     uint32_t width,
                                     uint32_t height,
                                     wgpu::TextureFormat format) {
    wgpu::Texture texture =
        CreateTexture(device, wgpu::TextureDimension::e2D, format, width, height, 1, 1);
    return texture.CreateView();
}

// Using BeginRenderPass with no attachments isn't valid
TEST_F(RenderPassDescriptorValidationTest, Empty) {
    utils::ComboRenderPassDescriptor renderPass({}, nullptr);
    AssertBeginRenderPassError(&renderPass);
}

// A render pass with only one color or one depth attachment is ok
TEST_F(RenderPassDescriptorValidationTest, OneAttachment) {
    // One color attachment
    {
        wgpu::TextureView color = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
        utils::ComboRenderPassDescriptor renderPass({color});

        AssertBeginRenderPassSuccess(&renderPass);
    }
    // One depth-stencil attachment
    {
        wgpu::TextureView depthStencil =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencil);

        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Regression test for chromium:1487788 were cached attachment states used in a pass encoder created
// from an error command encoder are not cleaned up if the device's last reference is dropped before
// the pass.
TEST_F(RenderPassDescriptorValidationTest, ErrorEncoderLingeringAttachmentState) {
    utils::ComboRenderPassDescriptor descriptor(
        {Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm)});

    // Purposely add a bad chain to the command encoder to force an error command encoder.
    wgpu::CommandEncoderDescriptor commandEncoderDesc = {};
    wgpu::ChainedStruct chain = {};
    commandEncoderDesc.nextInChain = &chain;

    wgpu::CommandEncoder commandEncoder;
    ASSERT_DEVICE_ERROR(commandEncoder = device.CreateCommandEncoder(&commandEncoderDesc));
    commandEncoder.BeginRenderPass(&descriptor);

    ExpectDeviceDestruction();
    device = nullptr;
}

// Test OOB color attachment indices are handled
TEST_F(RenderPassDescriptorValidationTest, ColorAttachmentOutOfBounds) {
    std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments + 1> colorAttachments;
    for (uint32_t i = 0; i < colorAttachments.size(); i++) {
        colorAttachments[i].view = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::R8Unorm);
        colorAttachments[i].resolveTarget = nullptr;
        colorAttachments[i].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
        colorAttachments[i].loadOp = wgpu::LoadOp::Clear;
        colorAttachments[i].storeOp = wgpu::StoreOp::Store;
    }

    // Control case: kMaxColorAttachments is valid.
    {
        wgpu::RenderPassDescriptor renderPass;
        renderPass.colorAttachmentCount = kMaxColorAttachments;
        renderPass.colorAttachments = colorAttachments.data();
        renderPass.depthStencilAttachment = nullptr;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Error case: kMaxColorAttachments + 1 is an error.
    {
        wgpu::RenderPassDescriptor renderPass;
        renderPass.colorAttachmentCount = kMaxColorAttachments + 1;
        renderPass.colorAttachments = colorAttachments.data();
        renderPass.depthStencilAttachment = nullptr;
        AssertBeginRenderPassError(&renderPass);
    }
}

// Test sparse color attachment validations
TEST_F(RenderPassDescriptorValidationTest, SparseColorAttachment) {
    // Having sparse color attachment is valid.
    {
        std::array<wgpu::RenderPassColorAttachment, 2> colorAttachments;
        colorAttachments[0].view = nullptr;

        colorAttachments[1].view =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
        colorAttachments[1].loadOp = wgpu::LoadOp::Load;
        colorAttachments[1].storeOp = wgpu::StoreOp::Store;

        wgpu::RenderPassDescriptor renderPass;
        renderPass.colorAttachmentCount = colorAttachments.size();
        renderPass.colorAttachments = colorAttachments.data();
        renderPass.depthStencilAttachment = nullptr;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // When all color attachments are null
    {
        std::array<wgpu::RenderPassColorAttachment, 2> colorAttachments;
        colorAttachments[0].view = nullptr;
        colorAttachments[1].view = nullptr;

        // Control case: depth stencil attachment is not null is valid.
        {
            wgpu::TextureView depthStencilView =
                Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8);
            wgpu::RenderPassDepthStencilAttachment depthStencilAttachment;
            depthStencilAttachment.view = depthStencilView;
            depthStencilAttachment.depthClearValue = 1.0f;
            depthStencilAttachment.stencilClearValue = 0;
            depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Clear;
            depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store;
            depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Clear;
            depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store;

            wgpu::RenderPassDescriptor renderPass;
            renderPass.colorAttachmentCount = colorAttachments.size();
            renderPass.colorAttachments = colorAttachments.data();
            renderPass.depthStencilAttachment = &depthStencilAttachment;
            AssertBeginRenderPassSuccess(&renderPass);
        }

        // Error case: depth stencil attachment being null is invalid.
        {
            wgpu::RenderPassDescriptor renderPass;
            renderPass.colorAttachmentCount = colorAttachments.size();
            renderPass.colorAttachments = colorAttachments.data();
            renderPass.depthStencilAttachment = nullptr;
            AssertBeginRenderPassError(&renderPass);
        }
    }
}

// Check that the render pass color attachment must have the RenderAttachment usage.
TEST_F(RenderPassDescriptorValidationTest, ColorAttachmentInvalidUsage) {
    // Control case: using a texture with RenderAttachment is valid.
    {
        wgpu::TextureView renderView =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
        utils::ComboRenderPassDescriptor renderPass({renderView});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Error case: using a texture with Sampled is invalid.
    {
        wgpu::TextureDescriptor texDesc;
        texDesc.usage = wgpu::TextureUsage::TextureBinding;
        texDesc.size = {1, 1, 1};
        texDesc.format = wgpu::TextureFormat::RGBA8Unorm;
        wgpu::Texture sampledTex = device.CreateTexture(&texDesc);

        utils::ComboRenderPassDescriptor renderPass({sampledTex.CreateView()});
        AssertBeginRenderPassError(&renderPass);
    }
}

// Attachments must have the same size
TEST_F(RenderPassDescriptorValidationTest, SizeMustMatch) {
    wgpu::TextureView color1x1A = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::TextureView color1x1B = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::TextureView color2x2 = Create2DAttachment(device, 2, 2, wgpu::TextureFormat::RGBA8Unorm);

    wgpu::TextureView depthStencil1x1 =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8);
    wgpu::TextureView depthStencil2x2 =
        Create2DAttachment(device, 2, 2, wgpu::TextureFormat::Depth24PlusStencil8);

    // Control case: all the same size (1x1)
    {
        utils::ComboRenderPassDescriptor renderPass({color1x1A, color1x1B}, depthStencil1x1);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // One of the color attachments has a different size
    {
        utils::ComboRenderPassDescriptor renderPass({color1x1A, color2x2});
        AssertBeginRenderPassError(&renderPass);
    }

    // The depth stencil attachment has a different size
    {
        utils::ComboRenderPassDescriptor renderPass({color1x1A, color1x1B}, depthStencil2x2);
        AssertBeginRenderPassError(&renderPass);
    }
}

// Attachments formats must match whether they are used for color or depth-stencil
TEST_F(RenderPassDescriptorValidationTest, FormatMismatch) {
    wgpu::TextureView color = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::TextureView depthStencil =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8);

    // Using depth-stencil for color
    {
        utils::ComboRenderPassDescriptor renderPass({depthStencil});
        AssertBeginRenderPassError(&renderPass);
    }

    // Using color for depth-stencil
    {
        utils::ComboRenderPassDescriptor renderPass({}, color);
        AssertBeginRenderPassError(&renderPass);
    }
}

// Depth and stencil storeOps can be different
TEST_F(RenderPassDescriptorValidationTest, DepthStencilStoreOpMismatch) {
    constexpr uint32_t kArrayLayers = 1;
    constexpr uint32_t kLevelCount = 1;
    constexpr uint32_t kSize = 32;
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
    constexpr wgpu::TextureFormat kDepthStencilFormat = wgpu::TextureFormat::Depth24PlusStencil8;

    wgpu::Texture colorTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                               kSize, kSize, kArrayLayers, kLevelCount);
    wgpu::Texture depthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kDepthStencilFormat, kSize, kSize,
                      kArrayLayers, kLevelCount);

    wgpu::TextureViewDescriptor descriptor;
    descriptor.dimension = wgpu::TextureViewDimension::e2D;
    descriptor.baseArrayLayer = 0;
    descriptor.arrayLayerCount = kArrayLayers;
    descriptor.baseMipLevel = 0;
    descriptor.mipLevelCount = kLevelCount;
    wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
    wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);

    // Base case: StoreOps match so render pass is a success
    {
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Base case: StoreOps match so render pass is a success
    {
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Discard;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // StoreOps mismatch still is a success
    {
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Currently only texture views with arrayLayerCount == 1 are allowed to be color and depth
// stencil attachments
TEST_F(RenderPassDescriptorValidationTest, TextureViewLayerCountForColorAndDepthStencil) {
    constexpr uint32_t kLevelCount = 1;
    constexpr uint32_t kSize = 32;
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
    constexpr wgpu::TextureFormat kDepthStencilFormat = wgpu::TextureFormat::Depth24PlusStencil8;

    constexpr uint32_t kArrayLayers = 10;

    wgpu::Texture colorTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                               kSize, kSize, kArrayLayers, kLevelCount);
    wgpu::Texture depthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kDepthStencilFormat, kSize, kSize,
                      kArrayLayers, kLevelCount);

    wgpu::TextureViewDescriptor baseDescriptor;
    baseDescriptor.dimension = wgpu::TextureViewDimension::e2DArray;
    baseDescriptor.baseArrayLayer = 0;
    baseDescriptor.arrayLayerCount = kArrayLayers;
    baseDescriptor.baseMipLevel = 0;
    baseDescriptor.mipLevelCount = kLevelCount;

    // Using 2D array texture view with arrayLayerCount > 1 is not allowed for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.arrayLayerCount = 5;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassError(&renderPass);
    }

    // Using 2D array texture view with arrayLayerCount > 1 is not allowed for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.arrayLayerCount = 5;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassError(&renderPass);
    }

    // Using 2D array texture view that covers the first layer of the texture is OK for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.baseArrayLayer = 0;
        descriptor.arrayLayerCount = 1;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D array texture view that covers the first layer is OK for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.baseArrayLayer = 0;
        descriptor.arrayLayerCount = 1;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D array texture view that covers the last layer is OK for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.baseArrayLayer = kArrayLayers - 1;
        descriptor.arrayLayerCount = 1;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D array texture view that covers the last layer is OK for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.baseArrayLayer = kArrayLayers - 1;
        descriptor.arrayLayerCount = 1;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Check that depthSlice must be set correctly for 3D color attachments and must not be set for
// non-3D color attachments.
TEST_F(RenderPassDescriptorValidationTest, TextureViewDepthSliceForColor) {
    constexpr uint32_t kSize = 8;
    constexpr uint32_t kDepthOrArrayLayers = 4;
    constexpr uint32_t kMipLevelCounts = 4;
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;

    wgpu::Texture colorTexture3D =
        CreateTexture(device, wgpu::TextureDimension::e3D, kColorFormat, kSize, kSize,
                      kDepthOrArrayLayers, kMipLevelCounts);

    wgpu::TextureView colorView2D = Create2DAttachment(device, kSize, kSize, kColorFormat);

    wgpu::TextureViewDescriptor baseDescriptor;
    baseDescriptor.dimension = wgpu::TextureViewDimension::e3D;
    baseDescriptor.baseArrayLayer = 0;
    baseDescriptor.arrayLayerCount = 1;
    baseDescriptor.baseMipLevel = 0;
    baseDescriptor.mipLevelCount = 1;

    // Control case: It's valid if depthSlice is set within the depth range of a 3D color
    // attachment.
    {
        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        utils::ComboRenderPassDescriptor renderPass({view});
        renderPass.cColorAttachments[0].depthSlice = kDepthOrArrayLayers - 1;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It's invalid if depthSlice is not set for a 3D color attachment.
    {
        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        utils::ComboRenderPassDescriptor renderPass({view});
        AssertBeginRenderPassError(&renderPass);
    }

    // It's invalid if depthSlice is out of the depth range of a 3D color attachment.
    {
        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        utils::ComboRenderPassDescriptor renderPass({view});
        renderPass.cColorAttachments[0].depthSlice = kDepthOrArrayLayers;
        AssertBeginRenderPassError(&renderPass);
    }

    // It's invalid if depthSlice is out of the depth range of a 3D color attachment with non-zero
    // mip level.
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.baseMipLevel = 2;
        wgpu::TextureView view = colorTexture3D.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({view});
        renderPass.cColorAttachments[0].depthSlice = kDepthOrArrayLayers >> 2;
        AssertBeginRenderPassError(&renderPass);
    }

    // Control case: It's valid if depthSlice is unset for a non-3D color attachment.
    {
        utils::ComboRenderPassDescriptor renderPass({colorView2D});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It's invalid if depthSlice is set for a non-3D color attachment.
    {
        utils::ComboRenderPassDescriptor renderPass({colorView2D});
        renderPass.cColorAttachments[0].depthSlice = 0;
        AssertBeginRenderPassError(&renderPass);
    }
}

// Check that the depth slices of a 3D color attachment cannot overlap in same render pass.
TEST_F(RenderPassDescriptorValidationTest, TextureViewDepthSliceOverlaps) {
    constexpr uint32_t kSize = 8;
    constexpr uint32_t kDepthOrArrayLayers = 2;
    constexpr uint32_t kMipLevelCounts = 2;
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;

    wgpu::Texture colorTexture3D =
        CreateTexture(device, wgpu::TextureDimension::e3D, kColorFormat, kSize, kSize,
                      kDepthOrArrayLayers, kMipLevelCounts);

    wgpu::TextureViewDescriptor baseDescriptor;
    baseDescriptor.dimension = wgpu::TextureViewDimension::e3D;
    baseDescriptor.baseArrayLayer = 0;
    baseDescriptor.arrayLayerCount = 1;
    baseDescriptor.baseMipLevel = 0;
    baseDescriptor.mipLevelCount = 1;

    // Control case: It's valid if different depth slices of a texture are set in a render pass.
    {
        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        utils::ComboRenderPassDescriptor renderPass({view, view});
        renderPass.cColorAttachments[0].depthSlice = 0;
        renderPass.cColorAttachments[1].depthSlice = 1;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It's valid if same depth slice of different mip levels from a texture with size [1, 1, n] is
    // set in a render pass.
    {
        wgpu::Texture texture = CreateTexture(device, wgpu::TextureDimension::e3D, kColorFormat, 1,
                                              1, kDepthOrArrayLayers, kMipLevelCounts);
        wgpu::TextureView view = texture.CreateView(&baseDescriptor);
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.baseMipLevel = 1;
        wgpu::TextureView view2 = texture.CreateView(&descriptor);

        utils::ComboRenderPassDescriptor renderPass({view, view2});
        renderPass.cColorAttachments[0].depthSlice = 0;
        renderPass.cColorAttachments[1].depthSlice = 0;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It's valid if same depth slice of different textures is set in a render pass.
    {
        wgpu::Texture otherColorTexture3D =
            CreateTexture(device, wgpu::TextureDimension::e3D, kColorFormat, kSize, kSize,
                          kDepthOrArrayLayers, kMipLevelCounts);

        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        wgpu::TextureView view2 = otherColorTexture3D.CreateView(&baseDescriptor);

        utils::ComboRenderPassDescriptor renderPass({view, view2});
        renderPass.cColorAttachments[0].depthSlice = 0;
        renderPass.cColorAttachments[1].depthSlice = 0;
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It's invalid if same depth slice of a texture is set twice in a render pass.
    {
        wgpu::TextureView view = colorTexture3D.CreateView(&baseDescriptor);
        utils::ComboRenderPassDescriptor renderPass({view, view});
        renderPass.cColorAttachments[0].depthSlice = 0;
        renderPass.cColorAttachments[1].depthSlice = 0;
        AssertBeginRenderPassError(&renderPass);
    }
}

// Check that the render pass depth attachment should not have any chained structs on it.
TEST_F(RenderPassDescriptorValidationTest, DepthAttachmentChained) {
    wgpu::TextureView renderView =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth32Float);
    utils::ComboRenderPassDescriptor renderPass({}, renderView);
    renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
    renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

    wgpu::ChainedStruct chain = {};
    renderPass.cDepthStencilAttachmentInfo.nextInChain = &chain;

    AssertBeginRenderPassError(&renderPass);
}

// Check that the render pass depth attachment must have the RenderAttachment usage.
TEST_F(RenderPassDescriptorValidationTest, DepthAttachmentInvalidUsage) {
    // Control case: using a texture with RenderAttachment is valid.
    {
        wgpu::TextureView renderView =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth32Float);
        utils::ComboRenderPassDescriptor renderPass({}, renderView);
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Error case: using a texture with Sampled is invalid.
    {
        wgpu::TextureDescriptor texDesc;
        texDesc.usage = wgpu::TextureUsage::TextureBinding;
        texDesc.size = {1, 1, 1};
        texDesc.format = wgpu::TextureFormat::Depth32Float;
        wgpu::Texture sampledTex = device.CreateTexture(&texDesc);
        wgpu::TextureView sampledView = sampledTex.CreateView();

        utils::ComboRenderPassDescriptor renderPass({}, sampledView);
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassError(&renderPass);
    }
}

// Only 2D texture views with mipLevelCount == 1 are allowed to be color attachments
TEST_F(RenderPassDescriptorValidationTest, TextureViewLevelCountForColorAndDepthStencil) {
    constexpr uint32_t kArrayLayers = 1;
    constexpr uint32_t kSize = 32;
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
    constexpr wgpu::TextureFormat kDepthStencilFormat = wgpu::TextureFormat::Depth24PlusStencil8;

    constexpr uint32_t kLevelCount = 4;

    wgpu::Texture colorTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                               kSize, kSize, kArrayLayers, kLevelCount);
    wgpu::Texture depthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kDepthStencilFormat, kSize, kSize,
                      kArrayLayers, kLevelCount);

    wgpu::TextureViewDescriptor baseDescriptor;
    baseDescriptor.dimension = wgpu::TextureViewDimension::e2D;
    baseDescriptor.baseArrayLayer = 0;
    baseDescriptor.arrayLayerCount = kArrayLayers;
    baseDescriptor.baseMipLevel = 0;
    baseDescriptor.mipLevelCount = kLevelCount;

    // Using 2D texture view with mipLevelCount > 1 is not allowed for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.mipLevelCount = 2;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassError(&renderPass);
    }

    // Using 2D texture view with mipLevelCount > 1 is not allowed for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.mipLevelCount = 2;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassError(&renderPass);
    }

    // Using 2D texture view that covers the first level of the texture is OK for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.baseMipLevel = 0;
        descriptor.mipLevelCount = 1;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D texture view that covers the first level is OK for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.baseMipLevel = 0;
        descriptor.mipLevelCount = 1;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D texture view that covers the last level is OK for color
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kColorFormat;
        descriptor.baseMipLevel = kLevelCount - 1;
        descriptor.mipLevelCount = 1;

        wgpu::TextureView colorTextureView = colorTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({colorTextureView});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using 2D texture view that covers the last level is OK for depth stencil
    {
        wgpu::TextureViewDescriptor descriptor = baseDescriptor;
        descriptor.format = kDepthStencilFormat;
        descriptor.baseMipLevel = kLevelCount - 1;
        descriptor.mipLevelCount = 1;

        wgpu::TextureView depthStencilView = depthStencilTexture.CreateView(&descriptor);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// It is not allowed to set resolve target when the color attachment is non-multisampled.
TEST_F(RenderPassDescriptorValidationTest, NonMultisampledColorWithResolveTarget) {
    static constexpr uint32_t kArrayLayers = 1;
    static constexpr uint32_t kLevelCount = 1;
    static constexpr uint32_t kSize = 32;
    static constexpr uint32_t kSampleCount = 1;
    static constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;

    wgpu::Texture colorTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, kSampleCount);
    wgpu::Texture resolveTargetTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, kSampleCount);
    wgpu::TextureView colorTextureView = colorTexture.CreateView();
    wgpu::TextureView resolveTargetTextureView = resolveTargetTexture.CreateView();

    utils::ComboRenderPassDescriptor renderPass({colorTextureView});
    renderPass.cColorAttachments[0].resolveTarget = resolveTargetTextureView;
    AssertBeginRenderPassError(&renderPass);
}

class TextureFormatsTier1RenderPassTest : public RenderPassDescriptorValidationTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::TextureFormatsTier1};
    }

    void RunRenderPassMultisampleTest(wgpu::TextureFormat colorFormat, bool withResolveTarget) {
        static constexpr uint32_t kArrayLayers = 1;
        static constexpr uint32_t kLevelCount = 1;
        static constexpr uint32_t kSize = 32;
        static constexpr uint32_t kMultiSampleCount = 4;
        static constexpr uint32_t kSingleSampleCount = 1;

        wgpu::Texture colorTexture =
            CreateTexture(device, wgpu::TextureDimension::e2D, colorFormat, kSize, kSize,
                          kArrayLayers, kLevelCount, kMultiSampleCount);
        wgpu::TextureView colorTextureView = colorTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({colorTextureView});

        wgpu::Texture resolveTargetTexture;
        wgpu::TextureView resolveTargetTextureView;
        if (withResolveTarget) {
            resolveTargetTexture =
                CreateTexture(device, wgpu::TextureDimension::e2D, colorFormat, kSize, kSize,
                              kArrayLayers, kLevelCount, kSingleSampleCount);
            resolveTargetTextureView = resolveTargetTexture.CreateView();
            renderPass.cColorAttachments[0].resolveTarget = resolveTargetTextureView;
        }

        AssertBeginRenderPassSuccess(&renderPass);
    }
};

// Tests that kTier1TestFormats8Bit color attachments support multisampling and resolve
// targets when TextureFormatsTier1 is enabled.
TEST_F(TextureFormatsTier1RenderPassTest, MultisampledColor8bitSnormWithResolveTarget) {
    for (const auto format : utils::kTier1TestFormats8Bit) {
        SCOPED_TRACE(absl::StrFormat("Test format: %s", format));
        RunRenderPassMultisampleTest(format, true);
    }
}

// Tests that kTier1TestFormats16Bit color attachments support multisampling targets when
// TextureFormatsTier1 is enabled.
TEST_F(TextureFormatsTier1RenderPassTest, MultisampledColor16bitWithoutResolveTarget) {
    for (const auto format : utils::kTier1TestFormats16Bit) {
        SCOPED_TRACE(absl::StrFormat("Test format: %s", format));
        RunRenderPassMultisampleTest(format, false);
    }
}

// Tests that RG11B10Ufloat color attachment supports multisampling and resolve targets
// when TextureFormatsTier1 is enabled.
TEST_F(TextureFormatsTier1RenderPassTest, MultisampledColorRG11B10UfloatWithResolveTarget) {
    RunRenderPassMultisampleTest(wgpu::TextureFormat::RG11B10Ufloat, true);
}

class RG11B10UfloatRenderableRenderPassTest : public TextureFormatsTier1RenderPassTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::RG11B10UfloatRenderable};
    }
};

// Tests that RG11B10Ufloat color attachment supports multisampling and resolve targets
// when RG11B10UfloatRenderable is enabled.
TEST_F(RG11B10UfloatRenderableRenderPassTest, MultisampledColorWithResolveTarget) {
    RunRenderPassMultisampleTest(wgpu::TextureFormat::RG11B10Ufloat, true);
}

// drawCount must not exceed maxDrawCount
TEST_F(RenderPassDescriptorValidationTest, MaxDrawCount) {
    constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
    constexpr uint64_t kMaxDrawCount = 16;

    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4f {
            return vec4f(0.0, 0.0, 0.0, 1.0);
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4f {
            return vec4f(0.0, 1.0, 0.0, 1.0);
        })");

    utils::ComboRenderPipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.vertex.module = vsModule;
    pipelineDescriptor.cFragment.module = fsModule;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);

    wgpu::TextureDescriptor colorTextureDescriptor;
    colorTextureDescriptor.size = {1, 1};
    colorTextureDescriptor.format = kColorFormat;
    colorTextureDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
    wgpu::Texture colorTexture = device.CreateTexture(&colorTextureDescriptor);

    utils::ComboRenderBundleEncoderDescriptor bundleEncoderDescriptor;
    bundleEncoderDescriptor.colorFormatCount = 1;
    bundleEncoderDescriptor.cColorFormats[0] = kColorFormat;

    wgpu::Buffer indexBuffer =
        utils::CreateBufferFromData<uint32_t>(device, wgpu::BufferUsage::Index, {0, 1, 2});
    wgpu::Buffer indirectBuffer =
        utils::CreateBufferFromData<uint32_t>(device, wgpu::BufferUsage::Indirect, {3, 1, 0, 0});
    wgpu::Buffer indexedIndirectBuffer =
        utils::CreateBufferFromData<uint32_t>(device, wgpu::BufferUsage::Indirect, {3, 1, 0, 0, 0});

    wgpu::RenderPassMaxDrawCount maxDrawCount;
    maxDrawCount.maxDrawCount = kMaxDrawCount;

    // Valid. drawCount is less than the default maxDrawCount.

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.Draw(3);
        }

        renderPass.End();
        encoder.Finish();
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);
        renderPass.SetIndexBuffer(indexBuffer, wgpu::IndexFormat::Uint32);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndexed(3);
        }

        renderPass.End();
        encoder.Finish();
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndirect(indirectBuffer, 0);
        }

        renderPass.End();
        encoder.Finish();
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);
        renderPass.SetIndexBuffer(indexBuffer, wgpu::IndexFormat::Uint32);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndexedIndirect(indexedIndirectBuffer, 0);
        }

        renderPass.End();
        encoder.Finish();
    }

    {
        wgpu::RenderBundleEncoder renderBundleEncoder =
            device.CreateRenderBundleEncoder(&bundleEncoderDescriptor);
        renderBundleEncoder.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderBundleEncoder.Draw(3);
        }

        wgpu::RenderBundle renderBundle = renderBundleEncoder.Finish();

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.ExecuteBundles(1, &renderBundle);
        renderPass.End();
        encoder.Finish();
    }

    // Invalid. drawCount counts up with draw calls and
    // it is greater than maxDrawCount.

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        renderPassDescriptor.nextInChain = &maxDrawCount;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.Draw(3);
        }

        renderPass.End();
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        renderPassDescriptor.nextInChain = &maxDrawCount;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);
        renderPass.SetIndexBuffer(indexBuffer, wgpu::IndexFormat::Uint32);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndexed(3);
        }

        renderPass.End();
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        renderPassDescriptor.nextInChain = &maxDrawCount;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndirect(indirectBuffer, 0);
        }

        renderPass.End();
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        renderPassDescriptor.nextInChain = &maxDrawCount;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.SetPipeline(pipeline);
        renderPass.SetIndexBuffer(indexBuffer, wgpu::IndexFormat::Uint32);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderPass.DrawIndexedIndirect(indexedIndirectBuffer, 0);
        }

        renderPass.End();
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }

    {
        wgpu::RenderBundleEncoder renderBundleEncoder =
            device.CreateRenderBundleEncoder(&bundleEncoderDescriptor);
        renderBundleEncoder.SetPipeline(pipeline);

        for (uint64_t i = 0; i <= kMaxDrawCount; i++) {
            renderBundleEncoder.Draw(3);
        }

        wgpu::RenderBundle renderBundle = renderBundleEncoder.Finish();

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassDescriptor({colorTexture.CreateView()});
        renderPassDescriptor.nextInChain = &maxDrawCount;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.ExecuteBundles(1, &renderBundle);
        renderPass.End();
        ASSERT_DEVICE_ERROR(encoder.Finish());
    }
}

class MultisampledRenderPassDescriptorValidationTest : public RenderPassDescriptorValidationTest {
  public:
    utils::ComboRenderPassDescriptor CreateMultisampledRenderPass() {
        return utils::ComboRenderPassDescriptor({CreateMultisampledColorTextureView()});
    }

    wgpu::TextureView CreateMultisampledColorTextureView() {
        return CreateColorTextureView(kSampleCount);
    }

    wgpu::TextureView CreateNonMultisampledColorTextureView() { return CreateColorTextureView(1); }

    static constexpr uint32_t kArrayLayers = 1;
    static constexpr uint32_t kLevelCount = 1;
    static constexpr uint32_t kSize = 32;
    static constexpr uint32_t kSampleCount = 4;
    static constexpr wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;

  private:
    wgpu::TextureView CreateColorTextureView(uint32_t sampleCount) {
        wgpu::Texture colorTexture =
            CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize,
                          kArrayLayers, kLevelCount, sampleCount);

        return colorTexture.CreateView();
    }
};

// Tests on the use of multisampled textures as color attachments
TEST_F(MultisampledRenderPassDescriptorValidationTest, MultisampledColorAttachments) {
    wgpu::TextureView colorTextureView = CreateNonMultisampledColorTextureView();
    wgpu::TextureView resolveTargetTextureView = CreateNonMultisampledColorTextureView();
    wgpu::TextureView multisampledColorTextureView = CreateMultisampledColorTextureView();

    // It is allowed to use a multisampled color attachment without setting resolve target.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It is not allowed to use multiple color attachments with different sample counts.
    {
        utils::ComboRenderPassDescriptor renderPass(
            {multisampledColorTextureView, colorTextureView});
        AssertBeginRenderPassError(&renderPass);
    }
}

// It is not allowed to use a multisampled resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, MultisampledResolveTarget) {
    wgpu::TextureView multisampledResolveTargetView = CreateMultisampledColorTextureView();

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = multisampledResolveTargetView;
    AssertBeginRenderPassError(&renderPass);
}

// Test the view dimension of resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetDimension) {
    wgpu::Texture resolveTexture2D = CreateTexture(
        device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers, kLevelCount);

    // It is allowed to use a 2d texture view as resolve target.
    {
        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        renderPass.cColorAttachments[0].resolveTarget = resolveTexture2D.CreateView();
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It is allowed to use a 2d-array texture view as resolve target.
    {
        wgpu::TextureViewDescriptor viewDesc;
        viewDesc.dimension = wgpu::TextureViewDimension::e2DArray;

        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        renderPass.cColorAttachments[0].resolveTarget = resolveTexture2D.CreateView(&viewDesc);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It is not allowed to use a 3d texture view as resolve target.
    {
        wgpu::Texture resolveTexture3D =
            CreateTexture(device, wgpu::TextureDimension::e3D, kColorFormat, kSize, kSize,
                          kArrayLayers, kLevelCount);
        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        renderPass.cColorAttachments[0].resolveTarget = resolveTexture3D.CreateView();
        AssertBeginRenderPassError(&renderPass);
    }
}

// It is not allowed to use a resolve target with array layer count > 1.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetArrayLayerMoreThanOne) {
    constexpr uint32_t kArrayLayers2 = 2;
    wgpu::Texture resolveTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                                 kSize, kSize, kArrayLayers2, kLevelCount);
    wgpu::TextureViewDescriptor viewDesc;
    viewDesc.dimension = wgpu::TextureViewDimension::e2DArray;
    wgpu::TextureView resolveTextureView = resolveTexture.CreateView(&viewDesc);

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
    AssertBeginRenderPassError(&renderPass);
}

// It is not allowed to use a resolve target with mipmap level count > 1.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetMipmapLevelMoreThanOne) {
    constexpr uint32_t kLevelCount2 = 2;
    wgpu::Texture resolveTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                                 kSize, kSize, kArrayLayers, kLevelCount2);
    wgpu::TextureView resolveTextureView = resolveTexture.CreateView();

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
    AssertBeginRenderPassError(&renderPass);
}

// It is not allowed to use a resolve target which is created from a texture whose usage does
// not include wgpu::TextureUsage::RenderAttachment.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetUsageNoRenderAttachment) {
    constexpr wgpu::TextureUsage kUsage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
    wgpu::Texture nonColorUsageResolveTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, 1, kUsage);
    wgpu::TextureView nonColorUsageResolveTextureView = nonColorUsageResolveTexture.CreateView();

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = nonColorUsageResolveTextureView;
    AssertBeginRenderPassError(&renderPass);
}

// It is not allowed to use a resolve target which is in error state.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetInErrorState) {
    wgpu::Texture resolveTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                                 kSize, kSize, kArrayLayers, kLevelCount);
    wgpu::TextureViewDescriptor errorTextureView;
    errorTextureView.dimension = wgpu::TextureViewDimension::e2D;
    errorTextureView.format = kColorFormat;
    errorTextureView.baseArrayLayer = kArrayLayers + 1;
    ASSERT_DEVICE_ERROR(wgpu::TextureView errorResolveTarget =
                            resolveTexture.CreateView(&errorTextureView));

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = errorResolveTarget;
    AssertBeginRenderPassError(&renderPass);
}

// It is allowed to use a multisampled color attachment and a non-multisampled resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, MultisampledColorWithResolveTarget) {
    wgpu::TextureView resolveTargetTextureView = CreateNonMultisampledColorTextureView();

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = resolveTargetTextureView;
    AssertBeginRenderPassSuccess(&renderPass);
}

// It is not allowed to use a resolve target in a format different from the color attachment.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetDifferentFormat) {
    constexpr wgpu::TextureFormat kColorFormat2 = wgpu::TextureFormat::BGRA8Unorm;
    wgpu::Texture resolveTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat2,
                                                 kSize, kSize, kArrayLayers, kLevelCount);
    wgpu::TextureView resolveTextureView = resolveTexture.CreateView();

    utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
    AssertBeginRenderPassError(&renderPass);
}

// Tests on the size of the resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest,
       ColorAttachmentResolveTargetDimensionMismatch) {
    constexpr uint32_t kSize2 = kSize * 2;
    wgpu::Texture resolveTexture = CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat,
                                                 kSize2, kSize2, kArrayLayers, kLevelCount + 1);

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

    {
        wgpu::TextureViewDescriptor firstMipLevelDescriptor = textureViewDescriptor;
        firstMipLevelDescriptor.baseMipLevel = 0;

        wgpu::TextureView resolveTextureView = resolveTexture.CreateView(&firstMipLevelDescriptor);

        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        wgpu::TextureViewDescriptor secondMipLevelDescriptor = textureViewDescriptor;
        secondMipLevelDescriptor.baseMipLevel = 1;

        wgpu::TextureView resolveTextureView = resolveTexture.CreateView(&secondMipLevelDescriptor);

        utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
        renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Test the overlaps of multiple resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetUsedTwice) {
    wgpu::TextureView resolveTextureView = CreateNonMultisampledColorTextureView();
    wgpu::TextureView colorTextureView1 = CreateMultisampledColorTextureView();
    wgpu::TextureView colorTextureView2 = CreateMultisampledColorTextureView();

    // It is allowed to use different resolve targets in a render pass.
    {
        wgpu::TextureView anotherResolveTextureView = CreateNonMultisampledColorTextureView();
        utils::ComboRenderPassDescriptor renderPass =
            utils::ComboRenderPassDescriptor({colorTextureView1, colorTextureView2});
        renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
        renderPass.cColorAttachments[1].resolveTarget = anotherResolveTextureView;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It is not allowed to use a resolve target twice in a render pass.
    {
        utils::ComboRenderPassDescriptor renderPass =
            utils::ComboRenderPassDescriptor({colorTextureView1, colorTextureView2});
        renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
        renderPass.cColorAttachments[1].resolveTarget = resolveTextureView;

        AssertBeginRenderPassError(&renderPass);
    }
}

// Tests the texture format of the resolve target must support being used as resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetFormat) {
    for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
        if (!utils::TextureFormatSupportsMultisampling(device, format, UseCompatibilityMode()) ||
            utils::IsDepthOrStencilFormat(format)) {
            continue;
        }

        wgpu::Texture colorTexture =
            CreateTexture(device, wgpu::TextureDimension::e2D, format, kSize, kSize, kArrayLayers,
                          kLevelCount, kSampleCount);
        wgpu::Texture resolveTarget = CreateTexture(device, wgpu::TextureDimension::e2D, format,
                                                    kSize, kSize, kArrayLayers, kLevelCount, 1);

        utils::ComboRenderPassDescriptor renderPass({colorTexture.CreateView()});
        renderPass.cColorAttachments[0].resolveTarget = resolveTarget.CreateView();
        if (utils::TextureFormatSupportsResolveTarget(device, format)) {
            AssertBeginRenderPassSuccess(&renderPass);
        } else {
            AssertBeginRenderPassError(&renderPass);
        }
    }
}

// Tests on the sample count of depth stencil attachment.
TEST_F(MultisampledRenderPassDescriptorValidationTest, DepthStencilAttachmentSampleCount) {
    constexpr wgpu::TextureFormat kDepthStencilFormat = wgpu::TextureFormat::Depth24PlusStencil8;
    wgpu::Texture multisampledDepthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kDepthStencilFormat, kSize, kSize,
                      kArrayLayers, kLevelCount, kSampleCount);
    wgpu::TextureView multisampledDepthStencilTextureView =
        multisampledDepthStencilTexture.CreateView();

    // It is not allowed to use a depth stencil attachment whose sample count is different from
    // the one of the color attachment.
    {
        wgpu::Texture depthStencilTexture =
            CreateTexture(device, wgpu::TextureDimension::e2D, kDepthStencilFormat, kSize, kSize,
                          kArrayLayers, kLevelCount);
        wgpu::TextureView depthStencilTextureView = depthStencilTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPass({CreateMultisampledColorTextureView()},
                                                    depthStencilTextureView);
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({CreateNonMultisampledColorTextureView()},
                                                    multisampledDepthStencilTextureView);
        AssertBeginRenderPassError(&renderPass);
    }

    // It is allowed to use a multisampled depth stencil attachment whose sample count is equal
    // to the one of the color attachment.
    {
        utils::ComboRenderPassDescriptor renderPass({CreateMultisampledColorTextureView()},
                                                    multisampledDepthStencilTextureView);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // It is allowed to use a multisampled depth stencil attachment while there is no color
    // attachment.
    {
        utils::ComboRenderPassDescriptor renderPass({}, multisampledDepthStencilTextureView);
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Creating a render pass with DawnRenderPassSampleCount chained struct without
// MSAARenderToSingleSampled feature enabled should result in error.
TEST_F(MultisampledRenderPassDescriptorValidationTest,
       CreateMSAARenderToSingleSampledRenderPassWithoutFeatureEnabled) {
    wgpu::TextureView colorTextureView = CreateNonMultisampledColorTextureView();

    wgpu::DawnRenderPassSampleCount renderPassSampleCount;
    renderPassSampleCount.sampleCount = 4;
    utils::ComboRenderPassDescriptor renderPass({colorTextureView});
    renderPass.nextInChain = &renderPassSampleCount;

    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("feature is not enabled"));
}

// Creating a render pass with LoadOp::ExpandResolveTexture without DawnLoadResolveTexture feature
// enabled should result in error.
TEST_F(MultisampledRenderPassDescriptorValidationTest, LoadResolveTextureWithoutFeatureEnabled) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();
    auto resolveTarget = CreateNonMultisampledColorTextureView();

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;

    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("is not enabled"));
}

// Creating a render pass with ExpandResolveRect and no DawnLoadResolveTexture feature
// enabled should result in error.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ExpandResolveRectWithoutFeatureEnabled) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();
    auto resolveTarget = CreateNonMultisampledColorTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;

    AssertBeginRenderPassError(&renderPass);
}

// Tests that NaN cannot be accepted as a valid color or depth clear value and INFINITY is valid
// in both color and depth clear values.
TEST_F(RenderPassDescriptorValidationTest, UseNaNOrINFINITYAsColorOrDepthClearValue) {
    wgpu::TextureView color = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);

    // Tests that NaN cannot be used in clearColor.
    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.r = NAN;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.g = NAN;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.b = NAN;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.a = NAN;
        AssertBeginRenderPassError(&renderPass);
    }

    // Tests that INFINITY cannot be used in clearColor.
    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.r = INFINITY;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.g = INFINITY;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.b = INFINITY;
        AssertBeginRenderPassError(&renderPass);
    }

    {
        utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
        renderPass.cColorAttachments[0].clearValue.a = INFINITY;
        AssertBeginRenderPassError(&renderPass);
    }

    // Tests that NaN cannot be used in depthClearValue if depthLoadOp is Clear.
    {
        wgpu::TextureView depth =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
        utils::ComboRenderPassDescriptor renderPass({color}, depth);
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.depthClearValue = NAN;
        AssertBeginRenderPassError(&renderPass);
    }

    // Tests that INFINITY cannot be used in depthClearValue.
    {
        wgpu::TextureView depth =
            Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
        utils::ComboRenderPassDescriptor renderPass({color}, depth);
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.depthClearValue = INFINITY;
        AssertBeginRenderPassError(&renderPass);
    }

    // TODO(https://crbug.com/dawn/666): Add a test case for clearStencil for stencilOnly
    // once stencil8 is supported.
}

// Tests that depth clear values mut be between 0 and 1, inclusive.
TEST_F(RenderPassDescriptorValidationTest, ValidateDepthClearValueRange) {
    wgpu::TextureView depth = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);

    utils::ComboRenderPassDescriptor renderPass({}, depth);
    renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
    renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

    // 0, 1, and any value in between are be valid.
    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0.1;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0.5;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0.82;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 1;
    AssertBeginRenderPassSuccess(&renderPass);

    // Values less than 0 or greater than 1 are invalid.
    renderPass.cDepthStencilAttachmentInfo.depthClearValue = -1;
    AssertBeginRenderPassError(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 2;
    AssertBeginRenderPassError(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = -0.001;
    AssertBeginRenderPassError(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 1.001;
    AssertBeginRenderPassError(&renderPass);

    // Clear values are not validated if the depthLoadOp is Load.
    renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = -1;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 2;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = -0.001;
    AssertBeginRenderPassSuccess(&renderPass);

    renderPass.cDepthStencilAttachmentInfo.depthClearValue = 1.001;
    AssertBeginRenderPassSuccess(&renderPass);
}

// Tests that default depthClearValue is required if attachment has a depth aspect and depthLoadOp
// is clear.
TEST_F(RenderPassDescriptorValidationTest, DefaultDepthClearValue) {
    wgpu::TextureView depthView =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
    wgpu::TextureView stencilView = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Stencil8);

    wgpu::RenderPassDepthStencilAttachment depthStencilAttachment;

    wgpu::RenderPassDescriptor renderPassDescriptor;
    renderPassDescriptor.colorAttachmentCount = 0;
    renderPassDescriptor.colorAttachments = nullptr;
    renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;

    // Default depthClearValue should be accepted if attachment doesn't have
    // a depth aspect.
    depthStencilAttachment.view = stencilView;
    depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Load;
    depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store;
    AssertBeginRenderPassSuccess(&renderPassDescriptor);

    // Default depthClearValue should be accepted if depthLoadOp is not clear.
    depthStencilAttachment.view = depthView;
    depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Undefined;
    depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Undefined;
    depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Load;
    depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store;
    AssertBeginRenderPassSuccess(&renderPassDescriptor);

    // Default depthClearValue should fail the validation
    // if attachment has a depth aspect and depthLoadOp is clear.
    depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Clear;
    AssertBeginRenderPassError(&renderPassDescriptor);

    // The validation should pass if valid depthClearValue is provided.
    depthStencilAttachment.depthClearValue = 0.0f;
    AssertBeginRenderPassSuccess(&renderPassDescriptor);
}

// Check the validation rules around depth/stencilReadOnly
TEST_F(RenderPassDescriptorValidationTest, ValidateDepthStencilReadOnly) {
    wgpu::TextureView colorView = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::TextureView depthStencilView =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8);
    wgpu::TextureView depthStencilViewNoStencil =
        Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
    wgpu::TextureView stencilView = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Stencil8);

    using Aspect = wgpu::TextureAspect;
    struct TestSpec {
        wgpu::TextureFormat format;
        Aspect formatAspects;
        Aspect testAspect;
    };

    TestSpec specs[] = {
        {wgpu::TextureFormat::Depth24PlusStencil8, Aspect::All, Aspect::StencilOnly},
        {wgpu::TextureFormat::Depth24PlusStencil8, Aspect::All, Aspect::DepthOnly},
        {wgpu::TextureFormat::Depth24Plus, Aspect::DepthOnly, Aspect::DepthOnly},
        {wgpu::TextureFormat::Stencil8, Aspect::All, Aspect::StencilOnly},
    };
    for (const auto& spec : specs) {
        wgpu::TextureView depthStencil = Create2DAttachment(device, 1, 1, spec.format);
        utils::ComboRenderPassDescriptor renderPass({}, depthStencilView);

        Aspect testAspect = spec.testAspect;
        Aspect otherAspect =
            testAspect == Aspect::DepthOnly ? Aspect::StencilOnly : Aspect::DepthOnly;

        auto Set = [&](Aspect aspect, wgpu::LoadOp loadOp, wgpu::StoreOp storeOp, bool readonly) {
            if (aspect == Aspect::DepthOnly) {
                renderPass.cDepthStencilAttachmentInfo.depthLoadOp = loadOp;
                renderPass.cDepthStencilAttachmentInfo.depthStoreOp = storeOp;
                renderPass.cDepthStencilAttachmentInfo.depthReadOnly = readonly;
            } else {
                DAWN_ASSERT(aspect == Aspect::StencilOnly);
                renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = loadOp;
                renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = storeOp;
                renderPass.cDepthStencilAttachmentInfo.stencilReadOnly = readonly;
            }
        };

        // Tests that a read-only pass with depth/stencilReadOnly both set to true succeeds.
        Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassSuccess(&renderPass);

        // Tests that readOnly with LoadOp not undefined is invalid.
        Set(testAspect, wgpu::LoadOp::Clear, wgpu::StoreOp::Undefined, true);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassError(&renderPass);

        Set(testAspect, wgpu::LoadOp::Load, wgpu::StoreOp::Undefined, true);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassError(&renderPass);

        // Tests that readOnly with StoreOp not undefined is invalid.
        Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Store, true);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassError(&renderPass);

        Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Discard, true);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassError(&renderPass);

        // Test for the aspect's not present in the format, if applicable.
        if (testAspect != spec.formatAspects) {
            // Tests that readOnly with LoadOp not undefined is invalid even if the aspect is not in
            // the format.
            Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
            Set(otherAspect, wgpu::LoadOp::Clear, wgpu::StoreOp::Undefined, true);
            AssertBeginRenderPassError(&renderPass);

            Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
            Set(otherAspect, wgpu::LoadOp::Load, wgpu::StoreOp::Undefined, true);
            AssertBeginRenderPassError(&renderPass);

            // Tests that readOnly with StoreOp not undefined is invalid even if the aspect is not
            // in the format.
            Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
            Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Store, true);
            AssertBeginRenderPassError(&renderPass);

            Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
            Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Discard, true);
            AssertBeginRenderPassError(&renderPass);
        }

        // Test that it is allowed to set only one of the aspects readonly.
        Set(testAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        Set(otherAspect, wgpu::LoadOp::Load, wgpu::StoreOp::Store, false);
        AssertBeginRenderPassSuccess(&renderPass);

        Set(testAspect, wgpu::LoadOp::Load, wgpu::StoreOp::Store, false);
        Set(otherAspect, wgpu::LoadOp::Undefined, wgpu::StoreOp::Undefined, true);
        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Check that the depth stencil attachment must use all aspects.
TEST_F(RenderPassDescriptorValidationTest, ValidateDepthStencilAllAspects) {
    wgpu::TextureDescriptor texDesc;
    texDesc.usage = wgpu::TextureUsage::RenderAttachment;
    texDesc.size = {1, 1, 1};

    wgpu::TextureViewDescriptor viewDesc;
    viewDesc.baseMipLevel = 0;
    viewDesc.mipLevelCount = 1;
    viewDesc.baseArrayLayer = 0;
    viewDesc.arrayLayerCount = 1;

    // Using all aspects of a depth+stencil texture is allowed.
    {
        texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        viewDesc.format = wgpu::TextureFormat::Undefined;
        viewDesc.aspect = wgpu::TextureAspect::All;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using only depth of a depth+stencil texture is an error, case without format
    // reinterpretation.
    {
        texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        viewDesc.format = wgpu::TextureFormat::Undefined;
        viewDesc.aspect = wgpu::TextureAspect::DepthOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassError(&renderPass);
    }

    // Using only depth of a depth+stencil texture is an error, case with format reinterpretation.
    {
        texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        viewDesc.format = wgpu::TextureFormat::Depth24Plus;
        viewDesc.aspect = wgpu::TextureAspect::DepthOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassError(&renderPass);
    }

    // Using only stencil of a depth+stencil texture is an error, case without format
    // reinterpration.
    {
        texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        viewDesc.format = wgpu::TextureFormat::Undefined;
        viewDesc.aspect = wgpu::TextureAspect::StencilOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassError(&renderPass);
    }

    // Using only stencil of a depth+stencil texture is an error, case with format reinterpretation.
    {
        texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        viewDesc.format = wgpu::TextureFormat::Stencil8;
        viewDesc.aspect = wgpu::TextureAspect::StencilOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassError(&renderPass);
    }

    // Using DepthOnly of a depth only texture is allowed.
    {
        texDesc.format = wgpu::TextureFormat::Depth24Plus;
        viewDesc.format = wgpu::TextureFormat::Undefined;
        viewDesc.aspect = wgpu::TextureAspect::DepthOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Using StencilOnly of a stencil only texture is allowed.
    {
        texDesc.format = wgpu::TextureFormat::Stencil8;
        viewDesc.format = wgpu::TextureFormat::Undefined;
        viewDesc.aspect = wgpu::TextureAspect::StencilOnly;

        wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
        utils::ComboRenderPassDescriptor renderPass({}, view);
        renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
        renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;

        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// Tests validation for per-pixel accounting for render targets. The tests currently assume that the
// default maxColorAttachmentBytesPerSample limit of 32 is used.
TEST_F(RenderPassDescriptorValidationTest, RenderPassColorAttachmentBytesPerSample) {
    struct TestCase {
        std::vector<wgpu::TextureFormat> formats;
        bool success;
    };
    static std::vector<TestCase> kTestCases = {
        // Simple 1 format cases.

        // R8Unorm take 1 byte and are aligned to 1 byte so we can have 8 (max).
        {{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
          wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
          wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm},
         true},
        // RGBA8Uint takes 4 bytes and are aligned to 1 byte so we can have 8 (max).
        {{wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
          wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
          wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
          wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint},
         true},
        // RGBA8Unorm takes 8 bytes (special case) and are aligned to 1 byte so only 4 allowed.
        {{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
          wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm},
         true},
        {{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
          wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
          wgpu::TextureFormat::RGBA8Unorm},
         false},
        // RGBA32Float takes 16 bytes and are aligned to 4 bytes so only 2 are allowed.
        {{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float}, true},
        {{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float,
          wgpu::TextureFormat::RGBA32Float},
         false},

        // Different format alignment cases.

        // Alignment causes the first 1 byte R8Unorm to become 4 bytes. So even though 1+4+8+16+1 <
        // 32, the 4 byte alignment requirement of R32Float makes the first R8Unorm become 4 and
        // 4+4+8+16+1 > 32. Re-ordering this so the R8Unorm's are at the end, however is allowed:
        // 4+8+16+1+1 < 32.
        {{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R32Float,
          wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA32Float,
          wgpu::TextureFormat::R8Unorm},
         false},
        {{wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RGBA8Unorm,
          wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::R8Unorm,
          wgpu::TextureFormat::R8Unorm},
         true},
    };

    for (const TestCase& testCase : kTestCases) {
        std::vector<wgpu::TextureView> colorAttachmentInfo;
        for (size_t i = 0; i < testCase.formats.size(); i++) {
            colorAttachmentInfo.push_back(Create2DAttachment(device, 1, 1, testCase.formats.at(i)));
        }
        utils::ComboRenderPassDescriptor descriptor(colorAttachmentInfo);
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&descriptor);
        renderPassEncoder.End();
        if (testCase.success) {
            commandEncoder.Finish();
        } else {
            ASSERT_DEVICE_ERROR(commandEncoder.Finish());
        }
    }
}

// Test that chaining RenderPassRenderAreaRect is rejected when RenderPassRenderArea feature is
// disabled.
TEST_F(RenderPassDescriptorValidationTest, RenderAreaNotAllowed) {
    wgpu::TextureView color = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});

    // Control case without render area.
    AssertBeginRenderPassSuccess(&renderPass);

    wgpu::RenderPassRenderAreaRect renderArea;
    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = 1;
    renderArea.size.height = 1;
    renderPass.nextInChain = &renderArea;

    AssertBeginRenderPassError(&renderPass);
}

// TODO(cwallez@chromium.org): Constraints on attachment aliasing?

class MSAARenderToSingleSampledRenderPassDescriptorValidationTest
    : public MultisampledRenderPassDescriptorValidationTest {
  protected:
    void SetUp() override {
        MultisampledRenderPassDescriptorValidationTest::SetUp();

        mRenderPassSampleCount.sampleCount = kSampleCount;
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::MSAARenderToSingleSampled};
    }

    utils::ComboRenderPassDescriptor CreateMultisampledRenderToSingleSampledRenderPass(
        wgpu::TextureView colorAttachment,
        wgpu::TextureView depthStencilAttachment = nullptr) {
        utils::ComboRenderPassDescriptor renderPass({colorAttachment}, depthStencilAttachment);
        renderPass.nextInChain = &mRenderPassSampleCount;

        return renderPass;
    }

    utils::ComboRenderPassDescriptor CreateMultisampledRenderToSingleSampledRenderPass(
        std::vector<wgpu::TextureView> colorAttachments,
        wgpu::TextureView depthStencilAttachment = nullptr) {
        utils::ComboRenderPassDescriptor renderPass(std::move(colorAttachments),
                                                    depthStencilAttachment);
        renderPass.nextInChain = &mRenderPassSampleCount;

        return renderPass;
    }

    // Create a view for a texture that can be used with a MSAA render to single sampled render
    // pass.
    wgpu::TextureView CreateCompatibleColorTextureView(uint32_t sampleCount = 1) {
        wgpu::Texture colorTexture = CreateTexture(
            device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
            kLevelCount, sampleCount, wgpu::TextureUsage::RenderAttachment);

        return colorTexture.CreateView();
    }

  private:
    wgpu::DawnRenderPassSampleCount mRenderPassSampleCount;
};

// Test that using a valid color attachment with enabled MSAARenderToSingleSampled doesn't raise any
// error.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, ColorAttachmentValid) {
    // Create a texture with sample count = 1.
    auto textureView = CreateCompatibleColorTextureView();

    auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(textureView);
    AssertBeginRenderPassSuccess(&renderPass);
}

TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, ColorAttachmentNull) {
    // Error: single attachment is nullptr
    {
        auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(nullptr);
        AssertBeginRenderPassError(&renderPass,
                                   testing::HasSubstr("Render pass has no attachments"));
    }

    // Success: one of two attachments is nullptr
    {
        auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(
            {nullptr, CreateCompatibleColorTextureView()});
        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Error: two of two attachments are nullptr
    {
        auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass({nullptr, nullptr});
        AssertBeginRenderPassError(&renderPass,
                                   testing::HasSubstr("Render pass has no attachments"));
    }
}

// When MSAARenderToSingleSampled is enabled for a color attachment, there must be no explicit
// resolve target specified for it.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, ErrorSettingResolveTarget) {
    // Create a texture with sample count = 1.
    auto textureView1 = CreateCompatibleColorTextureView();
    auto textureView2 = CreateCompatibleColorTextureView();

    auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(textureView1);
    renderPass.cColorAttachments[0].resolveTarget = textureView2;
    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("as a resolve target"));
}

// Using unsupported implicit sample count in DawnRenderPassSampleCount chained struct should result
// in error.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, UnsupportedSampleCountError) {
    // Create a texture with sample count = 1.
    auto textureView = CreateCompatibleColorTextureView();

    // Create a render pass with implicit sample count = 3. Which is not supported.
    wgpu::DawnRenderPassSampleCount renderPassSampleCount;
    renderPassSampleCount.sampleCount = 3;
    utils::ComboRenderPassDescriptor renderPass({textureView});
    renderPass.nextInChain = &renderPassSampleCount;

    AssertBeginRenderPassError(&renderPass,
                               testing::HasSubstr("sample count (3) is not supported"));

    // Create a render pass with implicit sample count = 1. Which is also not supported.
    renderPassSampleCount.sampleCount = 1;
    renderPass.nextInChain = &renderPassSampleCount;

    AssertBeginRenderPassError(&renderPass,
                               testing::HasSubstr("sample count (1) is not supported"));
}

// When MSAARenderToSingleSampled it only applies to attachments with a sample count of 1.
// Attachments can also have a sample count matching the MSAARenderToSingleSampled sample count.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, MixedSampleCounts) {
    auto textureView1 = CreateCompatibleColorTextureView(1);
    auto textureView2 = CreateCompatibleColorTextureView(4);
    auto resolveTextureView = CreateCompatibleColorTextureView(1);

    // Render passes may contain a mix of both attachments matching the pass sample count and 1
    {
        wgpu::DawnRenderPassSampleCount renderPassSampleCount;
        renderPassSampleCount.sampleCount = 4;
        utils::ComboRenderPassDescriptor renderPass({textureView1, textureView2});
        renderPass.nextInChain = &renderPassSampleCount;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Order does not matter
    {
        wgpu::DawnRenderPassSampleCount renderPassSampleCount;
        renderPassSampleCount.sampleCount = 4;
        utils::ComboRenderPassDescriptor renderPass({textureView2, textureView1});
        renderPass.nextInChain = &renderPassSampleCount;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Single-sample attachments (still) cannot have resolve targets
    {
        wgpu::DawnRenderPassSampleCount renderPassSampleCount;
        renderPassSampleCount.sampleCount = 4;
        utils::ComboRenderPassDescriptor renderPass({textureView1, textureView2});
        renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
        renderPass.nextInChain = &renderPassSampleCount;

        AssertBeginRenderPassError(&renderPass, testing::HasSubstr("has a sample count of 1"));
    }

    // Multisample attachments can have resolve targets as usual
    {
        wgpu::DawnRenderPassSampleCount renderPassSampleCount;
        renderPassSampleCount.sampleCount = 4;
        utils::ComboRenderPassDescriptor renderPass({textureView1, textureView2});
        renderPass.cColorAttachments[1].resolveTarget = resolveTextureView;
        renderPass.nextInChain = &renderPassSampleCount;

        AssertBeginRenderPassSuccess(&renderPass);
    }

    // Render passes may contain only sample counts matching the pass sample count.
    // (MSRTSS will not be triggered in this case.)
    {
        auto textureView3 = CreateCompatibleColorTextureView(4);

        wgpu::DawnRenderPassSampleCount renderPassSampleCount;
        renderPassSampleCount.sampleCount = 4;
        utils::ComboRenderPassDescriptor renderPass({textureView2, textureView3});
        renderPass.nextInChain = &renderPassSampleCount;

        AssertBeginRenderPassSuccess(&renderPass);
    }
}

// When MSAARenderToSingleSampled is enabled in a render pass, there should be an error if a
// color attachment's format doesn't support resolve. Example, RGBA8Sint format.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, UnresolvableColorFormatError) {
    // Create a texture with sample count = 1.
    auto texture = CreateTexture(
        device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::RGBA8Sint, kSize, kSize,
        kArrayLayers, kLevelCount, /*sampleCount=*/1, wgpu::TextureUsage::RenderAttachment);

    auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(texture.CreateView());
    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("does not support resolve"));
}

// Depth stencil attachment's sample count must match the one specified in color attachment's
// implicitSampleCount.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest, DepthStencilSampleCountValid) {
    // Create a color texture with sample count = 1.
    auto colorTextureView = CreateCompatibleColorTextureView();

    // Create depth stencil texture with sample count = 4.
    auto depthStencilTexture = CreateTexture(
        device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::Depth24PlusStencil8, kSize, kSize,
        1, 1, /*sampleCount=*/kSampleCount, wgpu::TextureUsage::RenderAttachment);

    auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(
        colorTextureView, depthStencilTexture.CreateView());

    AssertBeginRenderPassSuccess(&renderPass);

    // Create depth stencil texture with sample count = 1.
    depthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::Depth24PlusStencil8,
                      kSize, kSize, 1, 1, /*sampleCount=*/1, wgpu::TextureUsage::RenderAttachment);

    renderPass = CreateMultisampledRenderToSingleSampledRenderPass(
        colorTextureView, depthStencilTexture.CreateView());

    AssertBeginRenderPassError(
        &renderPass, testing::HasSubstr("does not match the render pass explicit sample count"));
}

// Using depth stencil attachment with sample count not matching the implicit sample count will
// result in error.
TEST_F(MSAARenderToSingleSampledRenderPassDescriptorValidationTest,
       DepthStencilSampleCountNotMatchImplicitSampleCount) {
    // Create a color texture with sample count = 1.
    auto colorTextureView = CreateCompatibleColorTextureView();

    // Create depth stencil texture with sample count = 1. Which doesn't match implicitSampleCount=4
    // specified in mRenderToSingleSampledDesc.
    auto depthStencilTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::Depth24PlusStencil8,
                      kSize, kSize, 1, 1, /*sampleCount=*/1, wgpu::TextureUsage::RenderAttachment);

    auto renderPass = CreateMultisampledRenderToSingleSampledRenderPass(
        colorTextureView, depthStencilTexture.CreateView());

    AssertBeginRenderPassError(
        &renderPass, testing::HasSubstr("does not match the render pass explicit sample count"));
}

class DawnLoadResolveTextureValidationTest : public MultisampledRenderPassDescriptorValidationTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::DawnLoadResolveTexture};
    }

    // Create a view for a resolve texture that can be used with LoadOp::ExpandResolveTexture.
    wgpu::TextureView CreateCompatibleResolveTextureView() {
        wgpu::Texture colorTexture = CreateTexture(
            device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
            kLevelCount, /*sampleCount=*/1,
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding);

        return colorTexture.CreateView();
    }
};

// Test that using a valid resolve texture with LoadOp::ExpandResolveTexture doesn't raise
// any error.
TEST_F(DawnLoadResolveTextureValidationTest, ResolveTargetValid) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassSuccess(&renderPass);
}

// Test that LoadOp::ExpandResolveTexture can be used even if the MSAA attachment is transient.
TEST_F(DawnLoadResolveTextureValidationTest, CompatibleWithTransientMSAATexture) {
    auto multisampledColorTexture = CreateTexture(
        device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers, kLevelCount,
        /*sampleCount=*/kSampleCount,
        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment);
    auto multisampledColorTextureView = multisampledColorTexture.CreateView();

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
    AssertBeginRenderPassSuccess(&renderPass);
}

// When LoadOp::ExpandResolveTexture is used, a resolve texture view must be set.
TEST_F(DawnLoadResolveTextureValidationTest, ResolveTargetMustBeSet) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();

    // Error case: texture view is set but resolveTarget is not set.
    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("resolve target"));
}

// When LoadOp::ExpandResolveTexture is used, the attached texture view must be multisampled.
TEST_F(DawnLoadResolveTextureValidationTest, ResolveTargetInvalidSampleCount) {
    // Create a texture with sample count = 1.
    auto colorTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/1, wgpu::TextureUsage::RenderAttachment);

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = colorTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("sample count"));
}

// When LoadOp::ExpandResolveTexture is used, the resolve texture must be created with
// TextureBinding usage.
TEST_F(DawnLoadResolveTextureValidationTest, ResolveTargetInvalidUsage) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();

    // Create a texture with sample count = 1.
    auto resolveTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/1, wgpu::TextureUsage::RenderAttachment);

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTexture.CreateView();
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassError(&renderPass, testing::HasSubstr("usage"));
}

// When LoadOp::ExpandResolveTexture is enabled in a color attachment, there should be an error if a
// color attachment's format doesn't support resolve. Example, RGBA8Sint format.
TEST_F(DawnLoadResolveTextureValidationTest, UnresolvableColorFormatError) {
    auto multisampledTexture = CreateTexture(
        device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::RGBA8Sint, kSize, kSize,
        kArrayLayers, kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment);

    // Create a texture with sample count = 1.
    auto resolveTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::RGBA8Sint, kSize,
                      kSize, kArrayLayers, kLevelCount, /*sampleCount=*/1,
                      wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding);

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.cColorAttachments[0].view = multisampledTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTexture.CreateView();
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassError(&renderPass,
                               testing::HasSubstr("does not support being used as resolve target"));
}

// The LoadOp is NOT currently supported on depth/stencil attachment.
TEST_F(DawnLoadResolveTextureValidationTest, OnlyLoadingColorAttachmentIsSupported) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();
    auto resolveTarget = CreateCompatibleResolveTextureView();

    // Error case: Use ExpandResolveTexture on depth/stencil attachment.
    {
        // Create depth stencil texture with sample count = 4.
        auto depthStencilTexture = CreateTexture(
            device, wgpu::TextureDimension::e2D, wgpu::TextureFormat::Depth24PlusStencil8, kSize,
            kSize, 1, 1, /*sampleCount=*/kSampleCount, wgpu::TextureUsage::RenderAttachment);

        auto renderPass = utils::ComboRenderPassDescriptor({multisampledColorTextureView},
                                                           depthStencilTexture.CreateView());
        renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;

        renderPass.cDepthStencilAttachmentInfo.depthLoadOp =
            renderPass.cDepthStencilAttachmentInfo.stencilLoadOp =
                wgpu::LoadOp::ExpandResolveTexture;

        AssertBeginRenderPassError(&renderPass,
                                   testing::HasSubstr("not supported on depth/stencil attachment"));
    }
}

// Creating a render pass with ExpandResolveRect and no DawnPartialLoadResolveTexture feature
// enabled should result in error.
TEST_F(DawnLoadResolveTextureValidationTest, ExpandResolveRectWithoutFeatureEnabled) {
    auto multisampledColorTextureView = CreateMultisampledColorTextureView();
    auto resolveTarget = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledColorTextureView;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;

    AssertBeginRenderPassError(&renderPass);
}

class DawnPartialLoadResolveTextureValidationTest : public DawnLoadResolveTextureValidationTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        auto features = DawnLoadResolveTextureValidationTest::GetRequiredFeatures();
        features.push_back(wgpu::FeatureName::DawnPartialLoadResolveTexture);
        return features;
    }
};

// Test that using a valid ExpandResolveRect with LoadOp::ExpandResolveTexture doesn't raise
// any error.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ExpandResolveRectValid) {
    auto multisampledTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment);

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassSuccess(&renderPass);
}

// Test that using a valid ExpandResolveRect with LoadOp::ExpandResolveTexture, jointed with another
// attachment without LoadOp::ExpandResolveTexture doesn't raise any error.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ExpandResolveRectMixedLoadOpsValid) {
    auto multisampledTextureView1 =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment)
            .CreateView();
    auto multisampledTextureView2 =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment)
            .CreateView();

    // Create a resolve texture with sample count = 1.
    auto resolveTarget1 = CreateCompatibleResolveTextureView();
    auto resolveTarget2 = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    utils::ComboRenderPassDescriptor renderPass(
        {multisampledTextureView1, multisampledTextureView2});

    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget1;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    renderPass.cColorAttachments[1].resolveTarget = resolveTarget2;
    renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::Load;
    AssertBeginRenderPassSuccess(&renderPass);
}

// The area of ExpandResolveRect must be within the texture size.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ExpandResolveRectInvalidSize) {
    auto multisampledTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment);

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = kSize;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassSuccess(&renderPass);

    rect.width = kSize + 1;
    AssertBeginRenderPassError(&renderPass);

    rect.height = kSize + 1;
    rect.width = 1;
    AssertBeginRenderPassError(&renderPass);
}

// Test that using a valid ResolveRect with LoadOp::ExpandResolveTexture doesn't raise
// any error.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ResolveRectValid) {
    auto multisampledTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment);

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassSuccess(&renderPass);
}

// Test that using a valid ResolveRect with LoadOp::ExpandResolveTexture, jointed with another
// attachment without LoadOp::ExpandResolveTexture doesn't raise any error.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ResolveRectMixedLoadOpsValid) {
    auto multisampledTextureView1 =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment)
            .CreateView();
    auto multisampledTextureView2 =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment)
            .CreateView();

    // Create a resolve texture with sample count = 1.
    auto resolveTarget1 = CreateCompatibleResolveTextureView();
    auto resolveTarget2 = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = 1;

    utils::ComboRenderPassDescriptor renderPass(
        {multisampledTextureView1, multisampledTextureView2});

    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget1;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    renderPass.cColorAttachments[1].resolveTarget = resolveTarget2;
    renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::Load;
    AssertBeginRenderPassSuccess(&renderPass);
}

// The area of ResolveRect must be within the texture size.
TEST_F(DawnPartialLoadResolveTextureValidationTest, ResolveRectInvalidSizeAndOffset) {
    auto multisampledTexture =
        CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize, kArrayLayers,
                      kLevelCount, /*sampleCount=*/4, wgpu::TextureUsage::RenderAttachment);

    // Create a resolve texture with sample count = 1.
    auto resolveTarget = CreateCompatibleResolveTextureView();

    wgpu::RenderPassDescriptorResolveRect rect{};
    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = rect.height = kSize;

    auto renderPass = CreateMultisampledRenderPass();
    renderPass.nextInChain = &rect;
    renderPass.cColorAttachments[0].view = multisampledTexture.CreateView();
    renderPass.cColorAttachments[0].resolveTarget = resolveTarget;
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::ExpandResolveTexture;
    AssertBeginRenderPassSuccess(&renderPass);

    rect.colorOffsetX = rect.colorOffsetY = 5;
    AssertBeginRenderPassError(&renderPass);

    rect.colorOffsetX = rect.colorOffsetY = 0;
    rect.resolveOffsetX = rect.resolveOffsetY = 5;
    AssertBeginRenderPassError(&renderPass);

    rect.resolveOffsetX = rect.resolveOffsetY = 0;
    rect.width = kSize + 1;
    AssertBeginRenderPassError(&renderPass);

    rect.height = kSize + 1;
    rect.width = 1;
    AssertBeginRenderPassError(&renderPass);
}

class TransientAttachmentRenderPassDescriptorValidationTest
    : public RenderPassDescriptorValidationTest {
  protected:
    wgpu::Texture CreateTexture(wgpu::TextureUsage textureUsage, wgpu::TextureFormat format) {
        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.usage = textureUsage;
        textureDescriptor.format = format;
        textureDescriptor.size.width = 4;
        textureDescriptor.size.height = 4;
        return device.CreateTexture(&textureDescriptor);
    }
};

// Test color attachment load and store ops with transient attachments.
TEST_F(TransientAttachmentRenderPassDescriptorValidationTest, ColorAttachment) {
    wgpu::Texture transientTexture = CreateTexture(
        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment,
        wgpu::TextureFormat::RGBA8Unorm);

    utils::ComboRenderPassDescriptor renderPassDescriptor({transientTexture.CreateView()});

    // Control case.
    {
        renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPassDescriptor);
    }
    // Error: loadOp must be "clear".
    {
        renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Load;
        renderPassDescriptor.cColorAttachments[0].storeOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: storeOp must be "discard".
    {
        renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
}

// Test depth attachment load and store ops with transient attachments.
TEST_F(TransientAttachmentRenderPassDescriptorValidationTest, DepthAttachment) {
    wgpu::Texture texture =
        CreateTexture(wgpu::TextureUsage::RenderAttachment, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::Texture depthStencilTransientTexture = CreateTexture(
        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment,
        wgpu::TextureFormat::Depth24Plus);

    utils::ComboRenderPassDescriptor renderPassDescriptor(
        {texture.CreateView()}, depthStencilTransientTexture.CreateView());
    renderPassDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(wgpu::TextureFormat::Depth24Plus);

    // Control case.
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPassDescriptor);
    }
    // Error: depthLoadOp must be "clear".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: depthStoreOp must be "discard".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
}

// Test stencil attachment load and store ops with transient attachments.
TEST_F(TransientAttachmentRenderPassDescriptorValidationTest, StencilAttachment) {
    wgpu::Texture texture =
        CreateTexture(wgpu::TextureUsage::RenderAttachment, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::Texture depthStencilTransientTexture = CreateTexture(
        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment,
        wgpu::TextureFormat::Stencil8);

    utils::ComboRenderPassDescriptor renderPassDescriptor(
        {texture.CreateView()}, depthStencilTransientTexture.CreateView());
    renderPassDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(wgpu::TextureFormat::Stencil8);

    // Control case.
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPassDescriptor);
    }
    // Error: stencilLoadOp must be "clear".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: stencilStoreOp must be "discard".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
}

// Test depth stencil attachment load and store ops with transient attachments.
TEST_F(TransientAttachmentRenderPassDescriptorValidationTest, DepthStencilAttachment) {
    wgpu::Texture texture =
        CreateTexture(wgpu::TextureUsage::RenderAttachment, wgpu::TextureFormat::RGBA8Unorm);
    wgpu::Texture depthStencilTransientTexture = CreateTexture(
        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment,
        wgpu::TextureFormat::Depth24PlusStencil8);

    utils::ComboRenderPassDescriptor renderPassDescriptor(
        {texture.CreateView()}, depthStencilTransientTexture.CreateView());

    // Control case.
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Discard;
        AssertBeginRenderPassSuccess(&renderPassDescriptor);
    }
    // Error: depthLoadOp must be "clear".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: stencilLoadOp must be "clear".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: depthStoreOp must be "discard".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
    // Error: stencilStoreOp must be "discard".
    {
        renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Discard;
        renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
        AssertBeginRenderPassError(&renderPassDescriptor);
    }
}

class RenderPassRenderAreaValidationTests : public RenderPassDescriptorValidationTest {
  protected:
    static constexpr uint16_t kSize = 16;

    void SetUp() override {
        DAWN_SKIP_TEST_IF(UsesWire());
        RenderPassDescriptorValidationTest::SetUp();
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::RenderPassRenderArea};
    }
};

// Tests that chaining RenderPassRenderAreaRect is allowed.
TEST_F(RenderPassRenderAreaValidationTests, RenderAreaFull) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});

    wgpu::RenderPassRenderAreaRect renderArea;
    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    renderPass.nextInChain = &renderArea;

    AssertBeginRenderPassSuccess(&renderPass);
}

// Tests that chaining RenderPassRenderAreaRect smaller than full render pass is allowed.
TEST_F(RenderPassRenderAreaValidationTests, RenderAreaPartial) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});

    wgpu::RenderPassRenderAreaRect renderArea;
    renderArea.origin.x = 1;
    renderArea.origin.y = 1;
    renderArea.size.width = kSize - 1;
    renderArea.size.height = kSize - 1;
    renderPass.nextInChain = &renderArea;

    AssertBeginRenderPassSuccess(&renderPass);
}

// Tests that render area that isn't contained by the render pass size is rejected.
TEST_F(RenderPassRenderAreaValidationTests, RenderAreaNotContained) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});
    wgpu::RenderPassRenderAreaRect renderArea;
    renderPass.nextInChain = &renderArea;

    // Control case with valid render area.
    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    AssertBeginRenderPassSuccess(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize * 2;
    renderArea.size.height = kSize * 2;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize * 2;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize * 2;
    renderArea.size.height = kSize;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 1;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 1;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    AssertBeginRenderPassError(&renderPass);
}

// Tests that render area overflows uint32_t is rejected.
TEST_F(RenderPassRenderAreaValidationTests, RenderAreaNotContainedWithOverlow) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});
    wgpu::RenderPassRenderAreaRect renderArea;
    renderPass.nextInChain = &renderArea;

    // Control case with valid render area.
    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    AssertBeginRenderPassSuccess(&renderPass);

    renderArea.origin.x = std::numeric_limits<uint32_t>::max();
    renderArea.origin.y = std::numeric_limits<uint32_t>::max();
    renderArea.size.width = 2;
    renderArea.size.height = 2;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = std::numeric_limits<uint32_t>::max();
    renderArea.size.width = 2;
    renderArea.size.height = 2;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = std::numeric_limits<uint32_t>::max();
    renderArea.origin.y = 0;
    renderArea.size.width = 2;
    renderArea.size.height = 2;
    AssertBeginRenderPassError(&renderPass);
}

// Tests that an empty render area is rejected.
TEST_F(RenderPassRenderAreaValidationTests, RenderAreaIsEmpty) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});
    wgpu::RenderPassRenderAreaRect renderArea;
    renderPass.nextInChain = &renderArea;

    // Control case with valid render area.
    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = kSize;
    AssertBeginRenderPassSuccess(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = 0;
    renderArea.size.height = 0;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = kSize;
    renderArea.size.height = 0;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 0;
    renderArea.origin.y = 0;
    renderArea.size.width = 0;
    renderArea.size.height = kSize;
    AssertBeginRenderPassError(&renderPass);

    renderArea.origin.x = 1;
    renderArea.origin.y = 1;
    renderArea.size.width = 0;
    renderArea.size.height = 0;
    AssertBeginRenderPassError(&renderPass);
}

// Tests that setting a scissor rect outside the render area is rejected.
TEST_F(RenderPassRenderAreaValidationTests, ScissorRectOutsideRenderArea) {
    wgpu::TextureView color =
        Create2DAttachment(device, kSize, kSize, wgpu::TextureFormat::RGBA8Unorm);
    utils::ComboRenderPassDescriptor renderPass({color});

    wgpu::RenderPassRenderAreaRect renderArea;
    renderArea.origin.x = 4;
    renderArea.origin.y = 4;
    renderArea.size.width = kSize / 2;
    renderArea.size.height = kSize / 2;
    renderPass.nextInChain = &renderArea;

    {
        // Control case with valid scissor rect.
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);

        renderPassEncoder.SetScissorRect(renderArea.origin.x, renderArea.origin.y,
                                         renderArea.size.width, renderArea.size.height);
        renderPassEncoder.End();
        commandEncoder.Finish();
    }

    {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);

        renderPassEncoder.SetScissorRect(2, 2, 1, 1);
        renderPassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }

    {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);

        renderPassEncoder.SetScissorRect(14, 14, 1, 1);
        renderPassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }
}

}  // anonymous namespace
}  // namespace dawn
