// Copyright 2017 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 <array>
#include <bit>
#include <cstring>
#include <limits>
#include <tuple>
#include <type_traits>
#include <vector>

#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/WGPUHelpers.h"
#include "src/utils/compiler.h"

namespace dawn {
namespace {

constexpr size_t kRTSize = 16;

class DrawQuad {
  public:
    DrawQuad() {}
    DrawQuad(wgpu::Device device, const char* vsSource, const char* fsSource) : device(device) {
        vsModule = utils::CreateShaderModule(device, vsSource);
        fsModule = utils::CreateShaderModule(device, fsSource);

        pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
    }

    void Draw(wgpu::RenderPassEncoder* pass) {
        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.layout = pipelineLayout;
        descriptor.vertex.module = vsModule;
        descriptor.cFragment.module = fsModule;

        auto renderPipeline = device.CreateRenderPipeline(&descriptor);

        pass->SetPipeline(renderPipeline);
        pass->Draw(6, 1, 0, 0);
    }

  private:
    wgpu::Device device;
    wgpu::ShaderModule vsModule = {};
    wgpu::ShaderModule fsModule = {};
    wgpu::PipelineLayout pipelineLayout = {};
};

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

        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = kRTSize;
        descriptor.size.height = kRTSize;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = 1;
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        renderTarget = device.CreateTexture(&descriptor);

        renderTargetView = renderTarget.CreateView();

        std::fill(expectZero.begin(), expectZero.end(), utils::RGBA8::kZero);

        std::fill(expectGreen.begin(), expectGreen.end(), utils::RGBA8::kGreen);

        std::fill(expectBlue.begin(), expectBlue.end(), utils::RGBA8::kBlue);

        // draws a blue quad on the right half of the screen
        const char* vsSource = R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec2f( 0.0, -1.0),
                    vec2f( 1.0, -1.0),
                    vec2f( 0.0,  1.0),
                    vec2f( 0.0,  1.0),
                    vec2f( 1.0, -1.0),
                    vec2f( 1.0,  1.0));

                return vec4f(pos[VertexIndex], 0.0, 1.0);
            })";

        const char* fsSource = R"(
            @fragment fn main() -> @location(0) vec4f {
                return vec4f(0.0, 0.0, 1.0, 1.0);
            })";
        blueQuad = DrawQuad(device, vsSource, fsSource);
    }

    template <class T>
    void TestClearColor(wgpu::TextureFormat format,
                        const wgpu::Color& clearColor,
                        const std::array<T, 4>& expectedPixelValue) {
        constexpr wgpu::Extent3D kTextureSize = {1, 1, 1};

        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.dimension = wgpu::TextureDimension::e2D;
        textureDescriptor.size = kTextureSize;
        textureDescriptor.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        textureDescriptor.format = format;
        wgpu::Texture texture = device.CreateTexture(&textureDescriptor);

        utils::ComboRenderPassDescriptor renderPassDescriptor({texture.CreateView()});
        renderPassDescriptor.cColorAttachments[0].clearValue = clearColor;
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.End();

        const uint64_t bufferSize = sizeof(T) * expectedPixelValue.size();
        wgpu::BufferDescriptor bufferDescriptor;
        bufferDescriptor.size = bufferSize;
        bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);

        wgpu::TexelCopyTextureInfo texelCopyTextureInfo =
            utils::CreateTexelCopyTextureInfo(texture, 0, {0, 0, 0});
        wgpu::TexelCopyBufferInfo texelCopyBufferInfo =
            utils::CreateTexelCopyBufferInfo(buffer, 0, kTextureBytesPerRowAlignment);
        encoder.CopyTextureToBuffer(&texelCopyTextureInfo, &texelCopyBufferInfo, &kTextureSize);

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

        EXPECT_BUFFER_U8_RANGE_EQ(reinterpret_cast<const uint8_t*>(expectedPixelValue.data()),
                                  buffer, 0, bufferSize / sizeof(uint8_t));
    }

    wgpu::Texture renderTarget;
    wgpu::TextureView renderTargetView;

    std::array<utils::RGBA8, kRTSize * kRTSize> expectZero;
    std::array<utils::RGBA8, kRTSize * kRTSize> expectGreen;
    std::array<utils::RGBA8, kRTSize * kRTSize> expectBlue;

    DrawQuad blueQuad = {};
};

// Tests clearing, loading, and drawing into color attachments
TEST_P(RenderPassLoadOpTests, ColorClearThenLoadAndDraw) {
    // TODO(crbug.com/523272949): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    // Part 1: clear once, check to make sure it's cleared
    utils::ComboRenderPassDescriptor renderPassClearZero({renderTargetView});
    auto commandsClearZeroEncoder = device.CreateCommandEncoder();
    auto clearZeroPass = commandsClearZeroEncoder.BeginRenderPass(&renderPassClearZero);
    clearZeroPass.End();
    auto commandsClearZero = commandsClearZeroEncoder.Finish();

    utils::ComboRenderPassDescriptor renderPassClearGreen({renderTargetView});
    renderPassClearGreen.cColorAttachments[0].clearValue = {0.0f, 1.0f, 0.0f, 1.0f};
    auto commandsClearGreenEncoder = device.CreateCommandEncoder();
    auto clearGreenPass = commandsClearGreenEncoder.BeginRenderPass(&renderPassClearGreen);
    clearGreenPass.End();
    auto commandsClearGreen = commandsClearGreenEncoder.Finish();

    queue.Submit(1, &commandsClearZero);
    EXPECT_TEXTURE_EQ(expectZero.data(), renderTarget, {0, 0}, {kRTSize, kRTSize});

    queue.Submit(1, &commandsClearGreen);
    EXPECT_TEXTURE_EQ(expectGreen.data(), renderTarget, {0, 0}, {kRTSize, kRTSize});

    // Part 2: draw a blue quad into the right half of the render target, and check result
    utils::ComboRenderPassDescriptor renderPassLoad({renderTargetView});
    renderPassLoad.cColorAttachments[0].loadOp = wgpu::LoadOp::Load;
    wgpu::CommandBuffer commandsLoad;
    {
        auto encoder = device.CreateCommandEncoder();
        auto pass = encoder.BeginRenderPass(&renderPassLoad);
        blueQuad.Draw(&pass);
        pass.End();
        commandsLoad = encoder.Finish();
    }

    queue.Submit(1, &commandsLoad);
    // Left half should still be green
    EXPECT_TEXTURE_EQ(expectGreen.data(), renderTarget, {0, 0}, {kRTSize / 2, kRTSize});
    // Right half should now be blue
    EXPECT_TEXTURE_EQ(expectBlue.data(), renderTarget, {kRTSize / 2, 0}, {kRTSize / 2, kRTSize});
}

// Test clearing a color attachment with signed and unsigned integer formats.
TEST_P(RenderPassLoadOpTests, LoadOpClearOnIntegerFormats) {
    // RGBA8Uint
    {
        constexpr wgpu::Color kClearColor = {2.f, 3.3f, 254.8f, 255.0f};
        constexpr std::array<uint8_t, 4> kExpectedPixelValue = {2, 3, 254, 255};
        TestClearColor<uint8_t>(wgpu::TextureFormat::RGBA8Uint, kClearColor, kExpectedPixelValue);
    }

    // RGBA8Sint
    {
        constexpr wgpu::Color kClearColor = {2.f, -3.3f, 126.8f, -128.0f};
        constexpr std::array<int8_t, 4> kExpectedPixelValue = {2, -3, 126, -128};
        TestClearColor<int8_t>(wgpu::TextureFormat::RGBA8Sint, kClearColor, kExpectedPixelValue);
    }

    // RGBA16Uint
    {
        constexpr wgpu::Color kClearColor = {2.f, 3.3f, 512.7f, 65535.f};
        constexpr std::array<uint16_t, 4> kExpectedPixelValue = {2, 3, 512, 65535u};
        TestClearColor<uint16_t>(wgpu::TextureFormat::RGBA16Uint, kClearColor, kExpectedPixelValue);
    }

    // RGBA16Sint
    {
        constexpr wgpu::Color kClearColor = {2.f, -3.3f, 32767.8f, -32768.0f};
        constexpr std::array<int16_t, 4> kExpectedPixelValue = {2, -3, 32767, -32768};
        TestClearColor<int16_t>(wgpu::TextureFormat::RGBA16Sint, kClearColor, kExpectedPixelValue);
    }

    // RGBA32Uint
    {
        constexpr wgpu::Color kClearColor = {2.f, 3.3f, 65534.8f, 65537.f};
        constexpr std::array<uint32_t, 4> kExpectedPixelValue = {2, 3, 65534, 65537};
        TestClearColor<uint32_t>(wgpu::TextureFormat::RGBA32Uint, kClearColor, kExpectedPixelValue);
    }

    // RGBA32Sint
    {
        constexpr wgpu::Color kClearColor = {2.f, -3.3f, 65534.8f, -65537.f};
        constexpr std::array<int32_t, 4> kExpectedPixelValue = {2, -3, 65534, -65537};
        TestClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor, kExpectedPixelValue);
    }
}

// This test verifies that input double values are being rendered correctly when clearing.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsToLargeValues) {
    constexpr double kUint32MaxDouble = 4294967295.0;
    constexpr uint32_t kUint32Max = static_cast<uint32_t>(kUint32MaxDouble);
    // RGBA32Uint for UINT32_MAX
    {
        constexpr wgpu::Color kClearColor = {kUint32MaxDouble, kUint32MaxDouble, kUint32MaxDouble,
                                             kUint32MaxDouble};
        constexpr std::array<uint32_t, 4> kExpectedPixelValue = {kUint32Max, kUint32Max, kUint32Max,
                                                                 kUint32Max};
        TestClearColor<uint32_t>(wgpu::TextureFormat::RGBA32Uint, kClearColor, kExpectedPixelValue);
    }

    constexpr double kSint32MaxDouble = 2147483647.0;
    constexpr int32_t kSint32Max = static_cast<int32_t>(kSint32MaxDouble);

    constexpr double kSint32MinDouble = -2147483648.0;
    constexpr int32_t kSint32Min = static_cast<int32_t>(kSint32MinDouble);

    // RGBA32Sint for SINT32 upper bound.
    {
        constexpr wgpu::Color kClearColor = {kSint32MaxDouble, kSint32MaxDouble, kSint32MaxDouble,
                                             kSint32MaxDouble};
        constexpr std::array<int32_t, 4> kExpectedPixelValue = {kSint32Max, kSint32Max, kSint32Max,
                                                                kSint32Max};
        TestClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor, kExpectedPixelValue);
    }

    // RGBA32Sint for SINT32 lower bound.
    {
        constexpr wgpu::Color kClearColor = {kSint32MinDouble, kSint32MinDouble, kSint32MinDouble,
                                             kSint32MinDouble};
        constexpr std::array<int32_t, 4> kExpectedPixelValue = {kSint32Min, kSint32Min, kSint32Min,
                                                                kSint32Min};
        TestClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor, kExpectedPixelValue);
    }
}

// Test clearing a color attachment on Uint8 formats (R8Uint, RG8Uint, RGBA8Uint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Uint8) {
    constexpr uint16_t kUint8Max = std::numeric_limits<uint8_t>::max();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<uint8_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R8Uint, {-1, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R8Uint, {0, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R8Uint, {kUint8Max, 0, 0, 0}, {kUint8Max, 0, 0, 0}},
        {wgpu::TextureFormat::R8Uint, {kUint8Max + 1, 0, 0, 0}, {kUint8Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG8Uint, {0, kUint8Max, 0, 0}, {0, kUint8Max, 0, 0}},
        {wgpu::TextureFormat::RG8Uint, {-1, kUint8Max + 1, 0, 0}, {0, kUint8Max, 0, 0}},
        {wgpu::TextureFormat::RGBA8Uint,
         {-1, 0, kUint8Max, kUint8Max + 1},
         {0, 0, kUint8Max, kUint8Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<uint8_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on Sint8 formats (R8Sint, RG8Sint, RGBA8Sint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Sint8) {
    constexpr int16_t kSint8Max = std::numeric_limits<int8_t>::max();
    constexpr int16_t kSint8Min = std::numeric_limits<int8_t>::min();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<int8_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R8Sint, {kSint8Min - 1, 0, 0, 0}, {kSint8Min, 0, 0, 0}},
        {wgpu::TextureFormat::R8Sint, {kSint8Min, 0, 0, 0}, {kSint8Min, 0, 0, 0}},
        {wgpu::TextureFormat::R8Sint, {kSint8Max, 0, 0, 0}, {kSint8Max, 0, 0, 0}},
        {wgpu::TextureFormat::R8Sint, {kSint8Max + 1, 0, 0, 0}, {kSint8Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG8Sint, {kSint8Min, kSint8Max, 0, 0}, {kSint8Min, kSint8Max, 0, 0}},
        {wgpu::TextureFormat::RG8Sint,
         {kSint8Min - 1, kSint8Max + 1, 0, 0},
         {kSint8Min, kSint8Max, 0, 0}},
        {wgpu::TextureFormat::RGBA8Sint,
         {kSint8Min - 1, kSint8Min, kSint8Max, kSint8Max + 1},
         {kSint8Min, kSint8Min, kSint8Max, kSint8Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<int8_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on Uint16 formats (R16Uint, RG16Uint, RGBA16Uint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Uint16) {
    constexpr uint32_t kUint16Max = std::numeric_limits<uint16_t>::max();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<uint16_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R16Uint, {-1, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R16Uint, {0, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R16Uint, {kUint16Max, 0, 0, 0}, {kUint16Max, 0, 0, 0}},
        {wgpu::TextureFormat::R16Uint, {kUint16Max + 1, 0, 0, 0}, {kUint16Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG16Uint, {0, kUint16Max, 0, 0}, {0, kUint16Max, 0, 0}},
        {wgpu::TextureFormat::RG16Uint, {-1, kUint16Max + 1, 0, 0}, {0, kUint16Max, 0, 0}},
        {wgpu::TextureFormat::RGBA16Uint,
         {-1, 0, kUint16Max, kUint16Max + 1},
         {0, 0, kUint16Max, kUint16Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<uint16_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on Sint16 formats (R16Sint, RG16Sint, RGBA16Sint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Sint16) {
    constexpr int32_t kSint16Max = std::numeric_limits<int16_t>::max();
    constexpr int32_t kSint16Min = std::numeric_limits<int16_t>::min();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<int16_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R16Sint, {kSint16Min - 1, 0, 0, 0}, {kSint16Min, 0, 0, 0}},
        {wgpu::TextureFormat::R16Sint, {kSint16Min, 0, 0, 0}, {kSint16Min, 0, 0, 0}},
        {wgpu::TextureFormat::R16Sint, {kSint16Max, 0, 0, 0}, {kSint16Max, 0, 0, 0}},
        {wgpu::TextureFormat::R16Sint, {kSint16Max + 1, 0, 0, 0}, {kSint16Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG16Sint,
         {kSint16Min, kSint16Max, 0, 0},
         {kSint16Min, kSint16Max, 0, 0}},
        {wgpu::TextureFormat::RG16Sint,
         {kSint16Min - 1, kSint16Max + 1, 0, 0},
         {kSint16Min, kSint16Max, 0, 0}},
        {wgpu::TextureFormat::RGBA16Sint,
         {kSint16Min - 1, kSint16Min, kSint16Max, kSint16Max + 1},
         {kSint16Min, kSint16Min, kSint16Max, kSint16Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<int16_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on Uint32 formats (R32Uint, RG32Uint, RGBA32Uint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Uint32) {
    constexpr uint64_t kUint32Max = std::numeric_limits<uint32_t>::max();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<uint32_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R32Uint, {-1, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R32Uint, {0, 0, 0, 0}, {0, 0, 0, 0}},
        {wgpu::TextureFormat::R32Uint, {kUint32Max, 0, 0, 0}, {kUint32Max, 0, 0, 0}},
        {wgpu::TextureFormat::R32Uint, {kUint32Max + 1, 0, 0, 0}, {kUint32Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG32Uint, {0, kUint32Max, 0, 0}, {0, kUint32Max, 0, 0}},
        {wgpu::TextureFormat::RG32Uint, {-1, kUint32Max + 1, 0, 0}, {0, kUint32Max, 0, 0}},
        {wgpu::TextureFormat::RGBA32Uint,
         {-1, 0, kUint32Max, kUint32Max + 1},
         {0, 0, kUint32Max, kUint32Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<uint32_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on Sint32 formats (R32Sint, RG32Sint, RGBA32Sint) when the clear
// values are out of bound.
TEST_P(RenderPassLoadOpTests, LoadOpClearIntegerFormatsOutOfBound_Sint32) {
    constexpr int64_t kSint32Max = std::numeric_limits<int32_t>::max();
    constexpr int64_t kSint32Min = std::numeric_limits<int32_t>::min();

    using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<int32_t, 4>>;
    constexpr std::array<TestCase, 7> kTestCases = {{
        {wgpu::TextureFormat::R32Sint, {kSint32Min - 1, 0, 0, 0}, {kSint32Min, 0, 0, 0}},
        {wgpu::TextureFormat::R32Sint, {kSint32Min, 0, 0, 0}, {kSint32Min, 0, 0, 0}},
        {wgpu::TextureFormat::R32Sint, {kSint32Max, 0, 0, 0}, {kSint32Max, 0, 0, 0}},
        {wgpu::TextureFormat::R32Sint, {kSint32Max + 1, 0, 0, 0}, {kSint32Max, 0, 0, 0}},
        {wgpu::TextureFormat::RG32Sint,
         {kSint32Min, kSint32Max, 0, 0},
         {kSint32Min, kSint32Max, 0, 0}},
        {wgpu::TextureFormat::RG32Sint,
         {kSint32Min - 1, kSint32Max + 1, 0, 0},
         {kSint32Min, kSint32Max, 0, 0}},
        {wgpu::TextureFormat::RGBA32Sint,
         {kSint32Min - 1, kSint32Min, kSint32Max, kSint32Max + 1},
         {kSint32Min, kSint32Min, kSint32Max, kSint32Max}},
    }};

    for (const TestCase& testCase : kTestCases) {
        auto [format, clearColor, expectedPixelValue] = testCase;
        TestClearColor<int32_t>(format, clearColor, expectedPixelValue);
    }
}

// Test clearing a color attachment on normalized formats when the clear values are out of bound.
// Note that we don't test RGBA8Snorm because it doesn't support being used as render attachments in
// current WebGPU SPEC.
TEST_P(RenderPassLoadOpTests, LoadOpClearNormalizedFormatsOutOfBound) {
    // RGBA8Unorm
    {
        constexpr wgpu::Color kClearColor = {-0.1f, 0, 1, 1.1f};
        constexpr std::array<uint8_t, 4> kExpectedPixelValue = {0, 0, 255u, 255u};
        TestClearColor<uint8_t>(wgpu::TextureFormat::RGBA8Unorm, kClearColor, kExpectedPixelValue);
    }

    // RGB10A2Unorm - Test components RGB
    {
        constexpr wgpu::Color kClearColor = {-0.1f, 0, 1.1f, 1};
        constexpr std::array<uint8_t, 4> kExpectedPixelValue = {0, 0, 0xF0u, 0xFFu};
        TestClearColor<uint8_t>(wgpu::TextureFormat::RGB10A2Unorm, kClearColor,
                                kExpectedPixelValue);
    }

    // RGB10A2Unorm - Test component A < 0
    {
        constexpr wgpu::Color kClearColor = {0, 0, 0, -0.1f};
        constexpr std::array<uint8_t, 4> kExpectedPixelValue = {0, 0, 0, 0};
        TestClearColor<uint8_t>(wgpu::TextureFormat::RGB10A2Unorm, kClearColor,
                                kExpectedPixelValue);
    }

    // RGB10A2Unorm - Test component A > 1
    {
        constexpr wgpu::Color kClearColor = {0, 0, 0, 1.1f};
        constexpr std::array<uint8_t, 4> kExpectedPixelValue = {0, 0, 0, 0xC0u};
        TestClearColor<uint8_t>(wgpu::TextureFormat::RGB10A2Unorm, kClearColor,
                                kExpectedPixelValue);
    }
}

// Test clearing multiple color attachments with different big signed and unsigned integers can
// still work correctly.
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBig32BitIntegralValuesOnMultipleColorAttachments) {
    // TODO(383733873): ApplyClearBigIntegerColorValueWithDraw workaround doesn't work with multiple
    // outputs in compat mode.
    DAWN_TEST_UNSUPPORTED_IF(IsD3D11() && IsCompatibilityMode());

    constexpr int32_t kMaxInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
    constexpr int32_t kMinInt32RepresentableInFloat = -kMaxInt32RepresentableInFloat;

    constexpr uint32_t kMaxUInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
    std::array<float, 4> testColorForRGBA32Float = {
        kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
        kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3};
    std::array<uint32_t, 4> expectedDataForRGBA32Float;
    for (uint32_t i = 0; i < expectedDataForRGBA32Float.size(); ++i) {
        expectedDataForRGBA32Float[i] = std::bit_cast<uint32_t>(testColorForRGBA32Float[i]);
    }

    struct AttachmentCase {
        static AttachmentCase Int(wgpu::TextureFormat format,
                                  wgpu::Color clearValue,
                                  const std::array<int32_t, 4> expData) {
            AttachmentCase attachmentCase;
            static_assert(sizeof(int32_t) * expData.size() == sizeof(attachmentCase.mExpData));
            attachmentCase.mFormat = format;
            attachmentCase.mClearValue = clearValue;
            DAWN_UNSAFE_TODO(memcpy(attachmentCase.mExpData,
                                    reinterpret_cast<const uint8_t*>(expData.data()),
                                    sizeof(attachmentCase.mExpData)));
            return attachmentCase;
        }
        static AttachmentCase Uint(wgpu::TextureFormat format,
                                   wgpu::Color clearValue,
                                   const std::array<uint32_t, 4> expData) {
            AttachmentCase attachmentCase;
            static_assert(sizeof(uint32_t) * expData.size() == sizeof(attachmentCase.mExpData));
            attachmentCase.mFormat = format;
            attachmentCase.mClearValue = clearValue;
            DAWN_UNSAFE_TODO(memcpy(attachmentCase.mExpData,
                                    reinterpret_cast<const uint8_t*>(expData.data()),
                                    sizeof(attachmentCase.mExpData)));
            return attachmentCase;
        }

        wgpu::TextureFormat mFormat;
        wgpu::Color mClearValue;
        uint8_t mExpData[16];
    };
    using TestCase = std::vector<AttachmentCase>;
    // Test cases are split so that the attachments in each case do not exceed the default
    // maxColorAttachmentBytesPerSample.
    static std::vector<TestCase> kTestCases = {
        // 6 attachment case (Signed 1 and 2 components).
        {AttachmentCase::Int(wgpu::TextureFormat::R32Sint, {kMaxInt32RepresentableInFloat, 0, 0, 0},
                             {kMaxInt32RepresentableInFloat, 0, 0, 0}),
         AttachmentCase::Int(wgpu::TextureFormat::R32Sint,
                             {kMaxInt32RepresentableInFloat + 1, 0, 0, 0},
                             {kMaxInt32RepresentableInFloat + 1, 0, 0, 0}),
         AttachmentCase::Int(wgpu::TextureFormat::R32Sint, {kMinInt32RepresentableInFloat, 0, 0, 0},
                             {kMinInt32RepresentableInFloat, 0, 0, 0}),
         AttachmentCase::Int(wgpu::TextureFormat::R32Sint,
                             {kMinInt32RepresentableInFloat - 1, 0, 0, 0},
                             {kMinInt32RepresentableInFloat - 1, 0, 0, 0}),
         AttachmentCase::Int(
             wgpu::TextureFormat::RG32Sint,
             {kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0},
             {kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0}),
         AttachmentCase::Int(
             wgpu::TextureFormat::RG32Sint,
             {kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0},
             {kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0})},

        // 4 attachment case (Signed 1 and 2 components).
        {AttachmentCase::Int(wgpu::TextureFormat::R32Sint, {kMaxInt32RepresentableInFloat, 0, 0, 0},
                             {kMaxInt32RepresentableInFloat, 0, 0, 0}),
         AttachmentCase::Int(wgpu::TextureFormat::R32Sint,
                             {kMaxInt32RepresentableInFloat + 1, 0, 0, 0},
                             {kMaxInt32RepresentableInFloat + 1, 0, 0, 0}),
         AttachmentCase::Int(
             wgpu::TextureFormat::RG32Sint,
             {kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0},
             {kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0}),
         AttachmentCase::Int(
             wgpu::TextureFormat::RG32Sint,
             {kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0},
             {kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0})},

        // Signed 4 components.
        {AttachmentCase::Int(
             wgpu::TextureFormat::RGBA32Sint,
             {kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
              kMaxInt32RepresentableInFloat + 1, kMinInt32RepresentableInFloat - 1},
             {kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
              kMaxInt32RepresentableInFloat + 1, kMinInt32RepresentableInFloat - 1}),
         AttachmentCase::Int(
             wgpu::TextureFormat::RGBA32Sint,
             {kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
              kMaxInt32RepresentableInFloat - 1, kMinInt32RepresentableInFloat + 1},
             {kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
              kMaxInt32RepresentableInFloat - 1, kMinInt32RepresentableInFloat + 1})},

        // Unsigned 1 components.
        {AttachmentCase::Uint(wgpu::TextureFormat::R32Uint,
                              {kMaxUInt32RepresentableInFloat, 0, 0, 0},
                              {kMaxUInt32RepresentableInFloat, 0, 0, 0}),
         AttachmentCase::Uint(wgpu::TextureFormat::R32Uint,
                              {kMaxUInt32RepresentableInFloat + 1, 0, 0, 0},
                              {kMaxUInt32RepresentableInFloat + 1, 0, 0, 0})},

        // Unsigned 2 components.
        {AttachmentCase::Uint(
             wgpu::TextureFormat::RG32Uint,
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat, 0, 0},
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat, 0, 0}),
         AttachmentCase::Uint(
             wgpu::TextureFormat::RG32Uint,
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1, 0, 0},
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1, 0, 0})},

        // Unsigned 4 component expectations (with use of signed inputs).
        {AttachmentCase::Uint(
             wgpu::TextureFormat::RGBA32Uint,
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1,
              kMaxUInt32RepresentableInFloat - 1, kMaxUInt32RepresentableInFloat - 2},
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1,
              kMaxUInt32RepresentableInFloat - 1, kMaxUInt32RepresentableInFloat - 2}),
         AttachmentCase::Uint(
             wgpu::TextureFormat::RGBA32Sint,
             {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
              kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3},
             {static_cast<int32_t>(kMaxUInt32RepresentableInFloat),
              static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 1),
              static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 2),
              static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 3)})},

        // Unsigned 4 component expectations from float.
        {AttachmentCase::Uint(
            wgpu::TextureFormat::RGBA32Float,
            {kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
             kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3},
            expectedDataForRGBA32Float)}};

    for (const TestCase& testCase : kTestCases) {
        if (testCase.size() > GetSupportedLimits().maxColorAttachments) {
            continue;
        }
        std::vector<wgpu::Texture> textures;
        std::vector<wgpu::RenderPassColorAttachment> colorAttachmentsInfo;
        std::vector<wgpu::Buffer> outputBuffers;

        // Initialize the default values for the textures.
        wgpu::TextureDescriptor textureDescriptor = {};
        textureDescriptor.size = {1, 1, 1};
        textureDescriptor.usage =
            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        for (const AttachmentCase& attachmentCase : testCase) {
            textureDescriptor.format = attachmentCase.mFormat;
            textures.push_back(device.CreateTexture(&textureDescriptor));

            wgpu::RenderPassColorAttachment colorAttachmentInfo = {};
            colorAttachmentInfo.view = textures.back().CreateView();
            colorAttachmentInfo.loadOp = wgpu::LoadOp::Clear;
            colorAttachmentInfo.storeOp = wgpu::StoreOp::Store;
            colorAttachmentInfo.clearValue = attachmentCase.mClearValue;
            colorAttachmentsInfo.push_back(colorAttachmentInfo);

            // Create the output buffer to compare values against.
            wgpu::BufferDescriptor bufferDescriptor = {};
            bufferDescriptor.size = sizeof(attachmentCase.mExpData);
            bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
            outputBuffers.push_back(device.CreateBuffer(&bufferDescriptor));
        }

        wgpu::RenderPassDescriptor renderPassDescriptor = {};
        renderPassDescriptor.colorAttachmentCount = colorAttachmentsInfo.size();
        renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
        wgpu::RenderPassEncoder renderPass;
        renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.End();

        for (uint32_t i = 0; i < testCase.size(); ++i) {
            wgpu::TexelCopyTextureInfo texelCopyTextureInfo =
                utils::CreateTexelCopyTextureInfo(textures[i], 0, {0, 0, 0});
            wgpu::TexelCopyBufferInfo texelCopyBufferInfo =
                utils::CreateTexelCopyBufferInfo(outputBuffers[i], 0, kTextureBytesPerRowAlignment);
            encoder.CopyTextureToBuffer(&texelCopyTextureInfo, &texelCopyBufferInfo,
                                        &textureDescriptor.size);
        }

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

        for (uint32_t i = 0; i < testCase.size(); ++i) {
            EXPECT_BUFFER_U8_RANGE_EQ(testCase.at(i).mExpData, outputBuffers[i], 0,
                                      sizeof(testCase.at(i).mExpData));
        }
    }
}

// Test using LoadOp::Clear with different big unsigned integers as clearValues and LoadOp::Load on
// the other color attachments in one render pass encoder works correctly.
TEST_P(RenderPassLoadOpTests, MixedUseOfLoadOpLoadAndLoadOpClearWithBigIntegerValues) {
    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());

    // TODO(383733873): ApplyClearBigIntegerColorValueWithDraw workaround doesn't work with multiple
    // outputs in compat mode.
    DAWN_TEST_UNSUPPORTED_IF(IsD3D11() && IsCompatibilityMode());

    constexpr int32_t kMaxUInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;

    wgpu::TextureDescriptor textureDescriptor = {};
    textureDescriptor.size = {1, 1, 1};
    textureDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
    textureDescriptor.format = wgpu::TextureFormat::R32Uint;

    wgpu::Texture textureForLoad = device.CreateTexture(&textureDescriptor);
    wgpu::Texture textureForClear = device.CreateTexture(&textureDescriptor);

    constexpr uint32_t kExpectedLoadValue = 2u;
    // Initialize textureForLoad with pixel value 2u.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassForInit({textureForLoad.CreateView()});
        renderPassForInit.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPassForInit.cColorAttachments[0].clearValue = {kExpectedLoadValue, 0, 0, 0};
        wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPassForInit);
        renderPassEncoder.End();
        wgpu::CommandBuffer commandBuffer = encoder.Finish();
        queue.Submit(1, &commandBuffer);
    }

    // Then set the load operation to Load while we still set the clear color to a big integer value
    // that cannot be represented by float.
    constexpr uint32_t kExpectedClearValue = kMaxUInt32RepresentableInFloat + 1;
    wgpu::Buffer outputBuffer;
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPassForClear(
            {textureForLoad.CreateView(), textureForClear.CreateView()});
        renderPassForClear.cColorAttachments[0].loadOp = wgpu::LoadOp::Load;
        renderPassForClear.cColorAttachments[0].clearValue = {kExpectedClearValue, 0, 0, 0};
        renderPassForClear.cColorAttachments[1].loadOp = wgpu::LoadOp::Clear;
        renderPassForClear.cColorAttachments[1].clearValue = {kExpectedClearValue, 0, 0, 0};
        wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPassForClear);
        renderPassEncoder.End();

        wgpu::BufferDescriptor bufferDescriptor = {};
        bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        bufferDescriptor.size = 2 * sizeof(uint32_t);
        outputBuffer = device.CreateBuffer(&bufferDescriptor);

        wgpu::TexelCopyTextureInfo texelCopyTextureInfoForLoad =
            utils::CreateTexelCopyTextureInfo(textureForLoad, 0, {0, 0, 0});
        wgpu::TexelCopyBufferInfo texelCopyBufferInfoForLoad =
            utils::CreateTexelCopyBufferInfo(outputBuffer, 0, kTextureBytesPerRowAlignment);
        encoder.CopyTextureToBuffer(&texelCopyTextureInfoForLoad, &texelCopyBufferInfoForLoad,
                                    &textureDescriptor.size);

        wgpu::TexelCopyTextureInfo texelCopyTextureInfoForClear =
            utils::CreateTexelCopyTextureInfo(textureForClear, 0, {0, 0, 0});
        wgpu::TexelCopyBufferInfo texelCopyBufferInfoForClear = utils::CreateTexelCopyBufferInfo(
            outputBuffer, sizeof(uint32_t), kTextureBytesPerRowAlignment);
        encoder.CopyTextureToBuffer(&texelCopyTextureInfoForClear, &texelCopyBufferInfoForClear,
                                    &textureDescriptor.size);

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

    constexpr std::array<uint32_t, 2> kExpectedData = {kExpectedLoadValue, kExpectedClearValue};
    EXPECT_BUFFER_U32_RANGE_EQ(kExpectedData.data(), outputBuffer, 0, kExpectedData.size());
}

DAWN_INSTANTIATE_TEST(
    RenderPassLoadOpTests,
    D3D11Backend(),
    D3D11Backend({"clear_color_with_draw"}),
    D3D12Backend(),
    MetalBackend(),
    OpenGLBackend(),
    OpenGLESBackend(),
    VulkanBackend({"vulkan_use_dynamic_rendering"}, {}),
    VulkanBackend({"vulkan_use_create_render_pass_2"}, {"vulkan_use_dynamic_rendering"}),
    VulkanBackend({}, {"vulkan_use_create_render_pass_2", "vulkan_use_dynamic_rendering"}),
    WebGPUBackend());

}  // anonymous namespace
}  // namespace dawn
