// 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 "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/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 SetUp() override {
        TextureFormatsTier1Test::SetUp();
        // TODO(crbug.com/523211957): Produces incorrect result on Pixel 10.
        DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());
    }

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

        // TODO(crbug.com/518759194): Produces incorrect result on Pixel 10.
        DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

        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:
    void SetUp() override {
        TextureFormatsTier1Test::SetUp();
        // TODO(crbug.com/522869944): Produces incorrect result on Pixel 10.
        DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());
    }

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

    // TODO(crbug.com/468047551): Fails on Win11/AMD RX 5500 XT.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsAMD() && 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());

    // TODO(crbug.com/468047551): Fails on Win11/AMD RX 5500 XT.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsAMD() && 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());

    // TODO(crbug.com/468047551): Fails on Win11/AMD RX 5500 XT.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsAMD() && 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
