// Copyright 2025 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 <string>
#include <vector>

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

namespace dawn {
namespace {

class TextureFormatsTier1Test : public DawnTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        std::vector<wgpu::FeatureName> requiredFeatures = {};
        if (SupportsFeatures({wgpu::FeatureName::TextureFormatsTier1})) {
            requiredFeatures.push_back(wgpu::FeatureName::TextureFormatsTier1);
        }
        return requiredFeatures;
    }

    const char* GetFullScreenQuadVS() {
        return R"(
                @vertex
                fn vs_main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4<f32> {
                    var positions = array<vec2<f32>, 3>(
                        vec2<f32>(-1.0, -1.0),
                        vec2<f32>( 3.0, -1.0),
                        vec2<f32>( -1.0, 3.0));
                    return vec4<f32>(positions[VertexIndex], 0.0, 1.0);
                }
            )";
    }

    std::string GenerateFragmentShader(const std::vector<float>& srcColorFloats) {
        std::ostringstream fsCodeStream;
        fsCodeStream << R"(
    @fragment
    fn fs_main() -> @location(0) vec4<f32> {
        return vec4<f32>()";

        for (size_t i = 0; i < 4; ++i) {
            if (i < srcColorFloats.size()) {
                fsCodeStream << srcColorFloats[i];
            } else {
                fsCodeStream << (i == 3 ? "1.0" : "0.0");
            }
            if (i < 3) {
                fsCodeStream << ", ";
            }
        }

        fsCodeStream << ");\n"
                     << "}\n";

        return fsCodeStream.str();
    }

    // Function to run a basic render pass drawing a full-screen quad.
    // Returns the finished command buffer for submission.
    wgpu::CommandBuffer RunDrawPass(wgpu::TextureView renderTargetView,
                                    wgpu::TextureFormat renderTargetFormat,
                                    const std::vector<float>& drawColorFloats,
                                    wgpu::MultisampleState multisampleState = {}) {
        std::string fsCode = GenerateFragmentShader(drawColorFloats);
        wgpu::ShaderModule shaderModule =
            utils::CreateShaderModule(device, (GetFullScreenQuadVS() + fsCode).c_str());

        utils::ComboRenderPipelineDescriptor pipelineDesc;
        pipelineDesc.vertex.module = shaderModule;
        pipelineDesc.cFragment.module = shaderModule;
        pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        pipelineDesc.cFragment.targetCount = 1;
        pipelineDesc.cTargets[0].format = renderTargetFormat;
        pipelineDesc.multisample = multisampleState;  // Apply provided multisample state
        pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::All;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDesc);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass;
        renderPass.cColorAttachments[0].view = renderTargetView;
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        renderPass.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
        renderPass.colorAttachmentCount = 1;

        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
        pass.SetPipeline(pipeline);
        pass.Draw(3);
        pass.End();
        return encoder.Finish();
    }

    // Function to run a render pass with blending.
    wgpu::CommandBuffer RunBlendPass(wgpu::TextureView renderTargetView,
                                     wgpu::TextureFormat renderTargetFormat,
                                     const std::vector<float>& srcColorFloats,
                                     const std::vector<float>& clearColorFloats) {
        std::string fsCode = GenerateFragmentShader(srcColorFloats);
        wgpu::ShaderModule shaderModule =
            utils::CreateShaderModule(device, (GetFullScreenQuadVS() + fsCode).c_str());

        utils::ComboRenderPipelineDescriptor pipelineDesc;
        pipelineDesc.vertex.module = shaderModule;
        pipelineDesc.cFragment.module = shaderModule;
        pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        pipelineDesc.cFragment.targetCount = 1;
        pipelineDesc.cTargets[0].format = renderTargetFormat;
        pipelineDesc.cTargets[0].blend = &pipelineDesc.cBlends[0];

        // Standard alpha blending: SrcAlpha * Src + (1 - SrcAlpha) * Dst
        pipelineDesc.cBlends[0].color.srcFactor = wgpu::BlendFactor::SrcAlpha;
        pipelineDesc.cBlends[0].color.dstFactor = wgpu::BlendFactor::OneMinusSrcAlpha;
        pipelineDesc.cBlends[0].color.operation = wgpu::BlendOperation::Add;
        pipelineDesc.cBlends[0].alpha.srcFactor = wgpu::BlendFactor::One;
        pipelineDesc.cBlends[0].alpha.dstFactor = wgpu::BlendFactor::Zero;
        pipelineDesc.cBlends[0].alpha.operation = wgpu::BlendOperation::Add;
        pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::All;

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDesc);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass;
        renderPass.cColorAttachments[0].view = renderTargetView;
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        renderPass.cColorAttachments[0].clearValue = {clearColorFloats[0], clearColorFloats[1],
                                                      clearColorFloats[2], clearColorFloats[3]};
        renderPass.colorAttachmentCount = 1;

        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
        pass.SetPipeline(pipeline);
        pass.Draw(3);
        pass.End();
        return encoder.Finish();
    }

    // Helper function for calculating expectations and checking pixels.
    void CalculateAndCheckPixels(wgpu::Texture texture,
                                 wgpu::TextureFormat format,
                                 const std::vector<float>& originData) {
        uint32_t componentCount = utils::GetTextureComponentCount(format);

        // Define vectors for expected bounds for each possible format type.
        std::vector<int8_t> expectedLowerBoundSnorm8;
        std::vector<int8_t> expectedUpperBoundSnorm8;
        std::vector<int16_t> expectedLowerBoundSnorm16;
        std::vector<int16_t> expectedUpperBoundSnorm16;
        std::vector<uint16_t> expectedLowerBoundUnorm16;
        std::vector<uint16_t> expectedUpperBoundUnorm16;

        for (uint32_t i = 0; i < componentCount; ++i) {
            float floatComponent = originData[i];
            // FLOAT -> SNORM/UNORM is permitted tolerance of 0.6f ULP. See
            // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#3.2.3.4%20FLOAT%20-%3E%20SNORM
            float tolerance = 0.6f;

            switch (format) {
                case wgpu::TextureFormat::R8Snorm:
                case wgpu::TextureFormat::RG8Snorm:
                case wgpu::TextureFormat::RGBA8Snorm: {
                    float scaledComponent = floatComponent * 127.0f;
                    int8_t lowerExpectation =
                        utils::ConvertFloatToSnorm8(scaledComponent - tolerance);
                    int8_t upperExpectation =
                        utils::ConvertFloatToSnorm8(scaledComponent + tolerance);
                    expectedLowerBoundSnorm8.push_back(lowerExpectation);
                    expectedUpperBoundSnorm8.push_back(upperExpectation);
                    break;
                }
                case wgpu::TextureFormat::R16Snorm:
                case wgpu::TextureFormat::RG16Snorm:
                case wgpu::TextureFormat::RGBA16Snorm: {
                    float scaledComponent = floatComponent * 32767.0f;
                    int16_t lowerExpectation =
                        utils::ConvertFloatToSnorm16(scaledComponent - tolerance);
                    int16_t upperExpectation =
                        utils::ConvertFloatToSnorm16(scaledComponent + tolerance);
                    expectedLowerBoundSnorm16.push_back(lowerExpectation);
                    expectedUpperBoundSnorm16.push_back(upperExpectation);
                    break;
                }
                case wgpu::TextureFormat::R16Unorm:
                case wgpu::TextureFormat::RG16Unorm:
                case wgpu::TextureFormat::RGBA16Unorm: {
                    float clampedComponent = floatComponent * 65535.0f;
                    uint16_t lowerExpectation =
                        utils::ConvertFloatToUnorm16(clampedComponent - tolerance);
                    uint16_t upperExpectation =
                        utils::ConvertFloatToUnorm16(clampedComponent + tolerance);
                    expectedLowerBoundUnorm16.push_back(lowerExpectation);
                    expectedUpperBoundUnorm16.push_back(upperExpectation);
                    break;
                }
                default:
                    DAWN_UNREACHABLE();
            }
        }

        // Perform the texture pixel validation based on the determined format type.
        // It asserts that the pixel at {0,0} with size {1,1} falls within the calculated bounds.
        switch (format) {
            case wgpu::TextureFormat::R8Snorm:
            case wgpu::TextureFormat::RG8Snorm:
            case wgpu::TextureFormat::RGBA8Snorm:
                EXPECT_TEXTURE_NORM_BETWEEN(expectedLowerBoundSnorm8, expectedUpperBoundSnorm8,
                                            texture, {0, 0}, {1, 1}, format);
                break;
            case wgpu::TextureFormat::R16Snorm:
            case wgpu::TextureFormat::RG16Snorm:
            case wgpu::TextureFormat::RGBA16Snorm:
                EXPECT_TEXTURE_NORM_BETWEEN(expectedLowerBoundSnorm16, expectedUpperBoundSnorm16,
                                            texture, {0, 0}, {1, 1}, format);
                break;
            case wgpu::TextureFormat::R16Unorm:
            case wgpu::TextureFormat::RG16Unorm:
            case wgpu::TextureFormat::RGBA16Unorm:
                EXPECT_TEXTURE_NORM_BETWEEN(expectedLowerBoundUnorm16, expectedUpperBoundUnorm16,
                                            texture, {0, 0}, {1, 1}, format);
                break;
            default:
                DAWN_UNREACHABLE();
        }
    }
};

class RenderAttachmentFormatsTest : public TextureFormatsTier1Test {
  protected:
    void RunRenderTest(wgpu::TextureFormat format, const std::vector<float>& originData) {
        DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureFormatsTier1));

        wgpu::Extent3D textureSize = {16, 16, 1};
        wgpu::TextureDescriptor textureDesc;
        textureDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        textureDesc.dimension = wgpu::TextureDimension::e2D;
        textureDesc.size = textureSize;
        textureDesc.format = format;

        wgpu::Texture texture = device.CreateTexture(&textureDesc);

        wgpu::CommandBuffer drawCommands = RunDrawPass(texture.CreateView(), format, originData);
        queue.Submit(1, &drawCommands);
        CalculateAndCheckPixels(texture, format, originData);
    }
};

// Test that r8snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, R8SnormRenderAttachment) {
    std::vector<float> originData = {-0.5f};  // R
    RunRenderTest(wgpu::TextureFormat::R8Snorm, originData);
}

// Test that rg8snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RG8SnormRenderAttachment) {
    std::vector<float> originData = {-0.5f, 0.25f};  // RG
    RunRenderTest(wgpu::TextureFormat::RG8Snorm, originData);
}

// Test that rgba8snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RGBA8SnormRenderAttachment) {
    std::vector<float> originData = {-0.5f, 0.25f, -1.0f, 1.0f};  // RGBA
    RunRenderTest(wgpu::TextureFormat::RGBA8Snorm, originData);
}

// Test that r16unorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, R16UnormRenderAttachment) {
    std::vector<float> originData = {0.375f};
    RunRenderTest(wgpu::TextureFormat::R16Unorm, originData);
}

// Test that r16snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, R16SnormRenderAttachment) {
    std::vector<float> originData = {-0.375f};
    RunRenderTest(wgpu::TextureFormat::R16Snorm, originData);
}

// Test that rg16unorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RG16UnormRenderAttachment) {
    std::vector<float> originData = {0.375f, 0.75f};
    RunRenderTest(wgpu::TextureFormat::RG16Unorm, originData);
}

// Test that rg16snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RG16SnormRenderAttachment) {
    std::vector<float> originData = {-0.375f, 0.625f};
    RunRenderTest(wgpu::TextureFormat::RG16Snorm, originData);
}

// Test that rgba16unorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RGBA16UnormRenderAttachment) {
    std::vector<float> originData = {0.375f, 0.75f, 0.125f, 0.875f};
    RunRenderTest(wgpu::TextureFormat::RGBA16Unorm, originData);
}

// Test that rgba16snorm format is valid as renderable texture if
// 'texture-formats-tier1' is enabled.
TEST_P(RenderAttachmentFormatsTest, RGBA16SnormRenderAttachment) {
    std::vector<float> originData = {-0.375f, 0.625f, -0.875f, 0.5f};
    RunRenderTest(wgpu::TextureFormat::RGBA16Snorm, originData);
}

DAWN_INSTANTIATE_TEST(RenderAttachmentFormatsTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

class BlendableFormatsTest : public TextureFormatsTier1Test {
  protected:
    void RunBlendTest(wgpu::TextureFormat format,
                      const std::vector<float>& srcColorFloats,
                      const std::vector<float>& clearColorFloats) {
        DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureFormatsTier1));

        wgpu::Extent3D textureSize = {16, 16, 1};
        wgpu::TextureDescriptor textureDesc;
        textureDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        textureDesc.dimension = wgpu::TextureDimension::e2D;
        textureDesc.size = textureSize;
        textureDesc.format = format;
        wgpu::Texture renderTarget = device.CreateTexture(&textureDesc);
        wgpu::TextureView renderTargetView = renderTarget.CreateView();

        wgpu::CommandBuffer blendCommands =
            RunBlendPass(renderTargetView, format, srcColorFloats, clearColorFloats);
        queue.Submit(1, &blendCommands);

        std::vector<float> expectedBlendedFloats(4);
        float srcR = (srcColorFloats.size() > 0) ? srcColorFloats[0] : 0.0f;
        float srcG = (srcColorFloats.size() > 1) ? srcColorFloats[1] : 0.0f;
        float srcB = (srcColorFloats.size() > 2) ? srcColorFloats[2] : 0.0f;
        float srcA = (srcColorFloats.size() > 3) ? srcColorFloats[3] : 1.0f;

        float dstR = clearColorFloats[0];
        float dstG = clearColorFloats[1];
        float dstB = clearColorFloats[2];

        expectedBlendedFloats[0] = srcR * srcA + dstR * (1.0f - srcA);
        expectedBlendedFloats[1] = srcG * srcA + dstG * (1.0f - srcA);
        expectedBlendedFloats[2] = srcB * srcA + dstB * (1.0f - srcA);
        expectedBlendedFloats[3] = srcA;
        CalculateAndCheckPixels(renderTarget, format, expectedBlendedFloats);
    }
};

// Test that r8snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, R8SnormBlendable) {
    std::vector<float> srcColor = {1.0f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::R8Snorm, srcColor, clearColor);
}

// Test that rg8snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RG8SnormBlendable) {
    std::vector<float> srcColor = {1.0f, -0.5f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RG8Snorm, srcColor, clearColor);
}

// Test that rgba8snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RGBA8SnormBlendable) {
    std::vector<float> srcColor = {1.0f, -0.5f, 0.0f, 0.5f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RGBA8Snorm, srcColor, clearColor);
}

// Test that r16unorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, R16UnormBlendable) {
    std::vector<float> srcColor = {1.0f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::R16Unorm, srcColor, clearColor);
}

// Test that r16snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, R16SnormBlendable) {
    std::vector<float> srcColor = {1.0f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::R16Snorm, srcColor, clearColor);
}

// Test that rg16unorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RG16UnormBlendable) {
    std::vector<float> srcColor = {1.0f, 0.0f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RG16Unorm, srcColor, clearColor);
}

// Test that rg16snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RG16SnormBlendable) {
    std::vector<float> srcColor = {1.0f, -0.5f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RG16Snorm, srcColor, clearColor);
}

// Test that rgba16unorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RGBA16UnormBlendable) {
    std::vector<float> srcColor = {1.0f, 0.0f, 0.0f, 0.5f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RGBA16Unorm, srcColor, clearColor);
}

// Test that rgba16snorm format is blendable when 'texture-formats-tier1' is enabled.
TEST_P(BlendableFormatsTest, RGBA16SnormBlendable) {
    std::vector<float> srcColor = {1.0f, -0.5f, 0.0f, 0.5f};
    std::vector<float> clearColor = {0.0f, 0.0f, 1.0f, 1.0f};
    RunBlendTest(wgpu::TextureFormat::RGBA16Snorm, srcColor, clearColor);
}

DAWN_INSTANTIATE_TEST(BlendableFormatsTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

class MultisampleResolveFormatsTest : public TextureFormatsTier1Test {
  protected:
    static constexpr uint32_t kSize = 16;
    static constexpr uint32_t kMultisampleCount = 4;
    static constexpr uint32_t kSingleSampleCount = 1;

    void RunMultisampleResolveFormatsTest(wgpu::TextureFormat format,
                                          const std::vector<float>& expectedDrawColorFloats) {
        DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureFormatsTier1));

        std::string fsCode = GenerateFragmentShader(expectedDrawColorFloats);
        wgpu::ShaderModule shaderModule =
            utils::CreateShaderModule(device, (GetFullScreenQuadVS() + fsCode).c_str());
        utils::ComboRenderPipelineDescriptor pipelineDesc;
        pipelineDesc.vertex.module = shaderModule;
        pipelineDesc.cFragment.module = shaderModule;
        pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        pipelineDesc.cFragment.targetCount = 1;
        pipelineDesc.cTargets[0].format = format;
        pipelineDesc.multisample.count = kMultisampleCount;
        pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::All;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDesc);

        wgpu::TextureDescriptor multisampleColorDesc;
        multisampleColorDesc.usage = wgpu::TextureUsage::RenderAttachment;
        multisampleColorDesc.dimension = wgpu::TextureDimension::e2D;
        multisampleColorDesc.size = {kSize, kSize, 1};
        multisampleColorDesc.format = format;
        multisampleColorDesc.sampleCount = kMultisampleCount;

        wgpu::Texture multisampleColorTexture = device.CreateTexture(&multisampleColorDesc);
        wgpu::TextureView multisampleColorView = multisampleColorTexture.CreateView();

        wgpu::TextureDescriptor resolveTargetDesc;
        resolveTargetDesc.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        resolveTargetDesc.dimension = wgpu::TextureDimension::e2D;
        resolveTargetDesc.size = {kSize, kSize, 1};
        resolveTargetDesc.format = format;
        resolveTargetDesc.sampleCount = kSingleSampleCount;

        wgpu::Texture resolveTargetTexture = device.CreateTexture(&resolveTargetDesc);
        wgpu::TextureView resolveTargetView = resolveTargetTexture.CreateView();

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass;
        renderPass.cColorAttachments[0].view = multisampleColorView;
        renderPass.cColorAttachments[0].resolveTarget = resolveTargetView;
        renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        renderPass.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
        renderPass.colorAttachmentCount = 1;

        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        pass.SetPipeline(pipeline);
        pass.Draw(3);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        CalculateAndCheckPixels(resolveTargetTexture, format, expectedDrawColorFloats);
    }
};

// Test that r8snorm format has multisample and resolve capability
// if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleResolveFormatsTest, R8SnormMultisampleResolve) {
    // TODO(crbug.com/468047551): Fails on Win11/NVIDIA GTX 1660.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsNvidia() && IsD3D12() && IsBackendValidationEnabled());

    std::vector<float> expectedDrawColor = {1.0f};
    RunMultisampleResolveFormatsTest(wgpu::TextureFormat::R8Snorm, expectedDrawColor);
}

// Test that rg8snorm format has multisample and resolve capability
// if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleResolveFormatsTest, RG8SnormMultisampleResolve) {
    // TODO(crbug.com/468047551): Fails on Win11/NVIDIA GTX 1660.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsNvidia() && IsD3D12() && IsBackendValidationEnabled());

    std::vector<float> expectedDrawColor = {1.0f, -0.5f};
    RunMultisampleResolveFormatsTest(wgpu::TextureFormat::RG8Snorm, expectedDrawColor);
}

// Test that rgba8snorm format has multisample and resolve capability
// if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleResolveFormatsTest, RGBA8SnormMultisampleResolve) {
    // TODO(crbug.com/468047551): Fails on Win11/NVIDIA GTX 1660.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsNvidia() && IsD3D12() && IsBackendValidationEnabled());

    std::vector<float> expectedDrawColor = {1.0f, -0.5f, -1.0f, 0.5f};
    RunMultisampleResolveFormatsTest(wgpu::TextureFormat::RGBA8Snorm, expectedDrawColor);
}

DAWN_INSTANTIATE_TEST(MultisampleResolveFormatsTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

class MultisampleFormatsTest : public TextureFormatsTier1Test {
  protected:
    static constexpr uint32_t kSize = 16;
    static constexpr uint32_t kMultisampleCount = 4;

    void SetUp() override {
        TextureFormatsTier1Test::SetUp();
        DAWN_SUPPRESS_TEST_IF(!IsCompatibilityMode());

        // TODO(crbug.com/473899151): [Capture] multisampled.
        DAWN_SUPPRESS_TEST_IF(IsCaptureReplayCheckingEnabled());
    }

    // Fragment shader for the second pass: reading multisample texture and writing verification
    // color. This shader outputs red if all samples match the expected color, else green.
    std::string GetMultisampleValidationFS(wgpu::TextureFormat format) {
        std::ostringstream fsCodeStream;
        std::string componentType = "f32";
        std::string textureType = "texture_multisampled_2d<f32>";

        fsCodeStream << R"(
                @group(0) @binding(0) var myMultisampleTexture: )"
                     << textureType << R"(;
                @group(0) @binding(1) var<uniform> expectedColorUniform: vec4<f32>;

                @fragment
                fn fs_main(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f32> {
                    let texelCoord = vec2<i32>(fragCoord.xy);
                    let numSamples = textureNumSamples(myMultisampleTexture);

                    var allSamplesMatch = true;
                    // Epsilon for floating point comparison of normalized values
                    // A small epsilon like 1/65535 or 1/32767 is appropriate for 16-bit formats.
                    // We will use a slightly larger one to account for potential precision differences.
                    let epsilon = 0.005;

                    for (var i: u32 = 0; i < numSamples; i = i + 1) {
                        let sampleColor = textureLoad(myMultisampleTexture, texelCoord, i);
                        if (abs(sampleColor.r - expectedColorUniform.r) > epsilon ||
                            abs(sampleColor.g - expectedColorUniform.g) > epsilon ||
                            abs(sampleColor.b - expectedColorUniform.b) > epsilon ||
                            abs(sampleColor.a - expectedColorUniform.a) > epsilon) {
                            allSamplesMatch = false;
                            break;
                        }
                    }

                    if (allSamplesMatch) {
                        return vec4<f32>(1.0, 0.0, 0.0, 1.0); // Output Red if all samples match
                    } else {
                        return vec4<f32>(0.0, 1.0, 0.0, 1.0); // Output Green if mismatch
                    }
                }
            )";
        return fsCodeStream.str();
    }

    // This function tests multisampled texture functionality in WebGPU. It renders
    // a color to a multisampled texture, then samples it and validates the color
    // to ensure correct multisampling and format handling.
    void RunMultisampleFormatsTest(wgpu::TextureFormat format,
                                   std::vector<float> expectedDrawColorFloats) {
        DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureFormatsTier1));

        // Create a multisampled texture that will be drawn to.
        wgpu::TextureDescriptor multisampleColorDesc;
        multisampleColorDesc.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
        multisampleColorDesc.dimension = wgpu::TextureDimension::e2D;
        multisampleColorDesc.size = {kSize, kSize, 1};
        multisampleColorDesc.format = format;
        multisampleColorDesc.sampleCount = kMultisampleCount;

        wgpu::Texture multisampleColorTexture = device.CreateTexture(&multisampleColorDesc);
        wgpu::TextureView multisampleColorView = multisampleColorTexture.CreateView({});

        // This pass draws a full-screen quad with the expected color to the multisampled texture.
        wgpu::CommandBuffer drawCommands =
            RunDrawPass(multisampleColorView, format, expectedDrawColorFloats,
                        {/* nextInChain */ nullptr, kMultisampleCount});
        queue.Submit(1, &drawCommands);

        // Create a single-sampled texture to render the validation result to.
        // This will be checked by EXPECT_PIXEL_RGBA8_EQ.
        wgpu::TextureDescriptor validationTextureDesc;
        validationTextureDesc.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        validationTextureDesc.dimension = wgpu::TextureDimension::e2D;
        validationTextureDesc.size = {kSize, kSize, 1};
        validationTextureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
        validationTextureDesc.sampleCount = 1;

        wgpu::Texture validationTexture = device.CreateTexture(&validationTextureDesc);
        wgpu::TextureView validationTextureView = validationTexture.CreateView({});

        std::string validationFsCode = GetMultisampleValidationFS(format);
        wgpu::ShaderModule validationShaderModule =
            utils::CreateShaderModule(device, (GetFullScreenQuadVS() + validationFsCode).c_str());

        // Pad the expectedDrawColorFloats to ensure it's vec4 for the uniform buffer.
        while (expectedDrawColorFloats.size() < 3) {
            expectedDrawColorFloats.push_back(0.0f);
        }
        if (expectedDrawColorFloats.size() < 4) {
            expectedDrawColorFloats.push_back(1.0f);
        }

        // Create uniform buffer to pass expected color to the validation shader.
        wgpu::BufferDescriptor uniformBufferDesc;
        uniformBufferDesc.size = 16;
        uniformBufferDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer expectedColorBuffer = device.CreateBuffer(&uniformBufferDesc);
        queue.WriteBuffer(expectedColorBuffer, 0, expectedDrawColorFloats.data(), 16);

        wgpu::BindGroupLayout validationBindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat,
                      wgpu::TextureViewDimension::e2D, true},
                     {1, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});

        wgpu::BindGroup validationBindGroup =
            utils::MakeBindGroup(device, validationBindGroupLayout,
                                 {{0, multisampleColorView}, {1, expectedColorBuffer}});

        // Pipeline for the second pass, which samples the multisampled texture.
        utils::ComboRenderPipelineDescriptor validationPipelineDesc;
        validationPipelineDesc.vertex.module = validationShaderModule;
        validationPipelineDesc.cFragment.module = validationShaderModule;
        validationPipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        validationPipelineDesc.cFragment.targetCount = 1;
        validationPipelineDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
        validationPipelineDesc.multisample.count = 1;
        validationPipelineDesc.layout =
            utils::MakePipelineLayout(device, {validationBindGroupLayout});
        validationPipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::All;

        wgpu::RenderPipeline validationPipeline =
            device.CreateRenderPipeline(&validationPipelineDesc);

        // This pass draws to the validationTexture, sampling the content from
        // multisampleColorTexture.
        wgpu::CommandEncoder encoder2 = device.CreateCommandEncoder();
        utils::ComboRenderPassDescriptor renderPass2;
        renderPass2.cColorAttachments[0].view = validationTextureView;
        renderPass2.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPass2.cColorAttachments[0].storeOp = wgpu::StoreOp::Store;
        renderPass2.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
        renderPass2.colorAttachmentCount = 1;

        wgpu::RenderPassEncoder pass2 = encoder2.BeginRenderPass(&renderPass2);
        pass2.SetPipeline(validationPipeline);
        pass2.SetBindGroup(0, validationBindGroup);
        pass2.Draw(3);
        pass2.End();

        wgpu::CommandBuffer commands2 = encoder2.Finish();
        queue.Submit(1, &commands2);

        // We expect red, confirming the multisampled texture was correctly drawn to and sampled.
        EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kRed, validationTexture, 0, 0);
    }
};

// Test that r16unorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, R16UnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::R16Unorm, {0.5f});
}

// Test that r16snorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, R16SnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::R16Snorm, {0.25f});
}

// Test that rg16unorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, RG16UnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::RG16Unorm, {0.25f, 0.75f});
}

// Test that rg16snorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, RG16SnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::RG16Snorm, {-0.5f, 0.5f});
}

// Test that rgba16unorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, RGBA16UnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::RGBA16Unorm, {0.1f, 0.4f, 0.7f, 1.0f});
}

// Test that rgba16snorm format has multisample capability if 'texture-formats-tier1' is enabled.
TEST_P(MultisampleFormatsTest, RGBA16SnormMultisample) {
    RunMultisampleFormatsTest(wgpu::TextureFormat::RGBA16Snorm, {-0.8f, -0.2f, 0.3f, 0.9f});
}

DAWN_INSTANTIATE_TEST(MultisampleFormatsTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

}  // anonymous namespace
}  // namespace dawn
