// Copyright 2026 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

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

#include "src/dawn/tests/perf_tests/DawnPerfTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

constexpr unsigned int kNumIterations = 20;

enum class LoadStoreOp {
    ClearAndDiscard,  // LoadOp=Clear + StoreOp=Discard (MSAA attachments only)
    ClearAndStore,    // LoadOp=Clear + StoreOp=Store
    LoadAndStore,     // LoadOp=Load  + StoreOp=Store
};

std::ostream& operator<<(std::ostream& o, LoadStoreOp op) {
    switch (op) {
        case LoadStoreOp::ClearAndDiscard:
            return o << "ClearAndDiscard";
        case LoadStoreOp::ClearAndStore:
            return o << "ClearAndStore";
        case LoadStoreOp::LoadAndStore:
            return o << "LoadAndStore";
    }
}

DAWN_TEST_PARAM_STRUCT(LoadStoreOpParams, LoadStoreOp);

// Perf test comparing load+store configurations on MSAA attachments:
//   - LoadOp=Clear + StoreOp=Discard
//   - LoadOp=Clear + StoreOp=Store
//   - LoadOp=Load  + StoreOp=Store
// Each step renders multiple passes across several large (4096x4096) MSAA + resolve texture pairs
// to measure how the choice of load/store ops affects GPU throughput in a realistic multi-pass
// scenario. We use multiple textures (kNumTextures) to avoid the driver potentially caching results
// and effectively skipping work when the same operation is performed repeatedly.
class LoadStoreOpPerfTest : public DawnPerfTestWithParams<LoadStoreOpParams> {
  public:
    LoadStoreOpPerfTest() : DawnPerfTestWithParams<LoadStoreOpParams>(kNumIterations, 1) {}
    ~LoadStoreOpPerfTest() override = default;

  private:
    void SetUpPerfTest() override;
    void Step() override;

    wgpu::Texture CreateTexture(wgpu::TextureFormat format, uint32_t sampleCount) {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = kWidth;
        descriptor.size.height = kHeight;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = sampleCount;
        descriptor.format = format;
        descriptor.mipLevelCount = 1;

        descriptor.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;

        return device.CreateTexture(&descriptor);
    }

    static constexpr uint32_t kWidth = 4096;
    static constexpr uint32_t kHeight = 4096;
    static constexpr uint32_t kNumTextures = 5;

    std::array<wgpu::Texture, kNumTextures> msaaTexture;
    std::array<wgpu::TextureView, kNumTextures> msaaTextureView;
    std::array<wgpu::Texture, kNumTextures> resolveTexture;
    std::array<wgpu::TextureView, kNumTextures> resolveTextureView;

    std::array<wgpu::Texture, kNumTextures> srcTexture1;
    std::array<wgpu::Texture, kNumTextures> srcTexture2;
    std::array<wgpu::TextureView, kNumTextures> srcTextureView1;
    std::array<wgpu::TextureView, kNumTextures> srcTextureView2;

    wgpu::RenderPipeline msaaPipeline;
    wgpu::RenderPipeline singleSampledPipeline;
    std::array<wgpu::BindGroup, kNumTextures> blitBindGroup1;
    std::array<wgpu::BindGroup, kNumTextures> blitBindGroup2;
};

void LoadStoreOpPerfTest::SetUpPerfTest() {
    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float},
                });

    wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, {bgl});

    const char* vs = R"(
        @vertex
        fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
            const pos = array(
                vec2f(-1.0, -1.0),
                vec2f( 3.0, -1.0),
                vec2f(-1.0,  3.0));
            return vec4f(pos[VertexIndex], 0.0, 1.0);
        })";
    constexpr char fs[] = R"(
        @group(0) @binding(0) var colorMap: texture_2d<f32>;
        @fragment
        fn main(@builtin(position) fragPosition : vec4<f32>) -> @location(0) vec4<f32> {
            let coords = vec2<i32>(i32(fragPosition.x), i32(fragPosition.y));
            return textureLoad(colorMap, coords, 0);
        })";
    utils::ComboRenderPipelineDescriptor pipelineDescriptor;

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

    pipelineDescriptor.cFragment.targetCount = 1;
    pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::All;
    pipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;

    pipelineDescriptor.layout = pipelineLayout;

    pipelineDescriptor.multisample.mask = 0xFFFFFFFF;
    pipelineDescriptor.multisample.count = 4;
    msaaPipeline = device.CreateRenderPipeline(&pipelineDescriptor);

    pipelineDescriptor.multisample.count = 1;
    singleSampledPipeline = device.CreateRenderPipeline(&pipelineDescriptor);

    for (uint32_t i = 0; i < kNumTextures; ++i) {
        msaaTexture[i] = CreateTexture(wgpu::TextureFormat::RGBA8Unorm, 4);
        resolveTexture[i] = CreateTexture(wgpu::TextureFormat::RGBA8Unorm, 1);
        srcTexture1[i] = CreateTexture(wgpu::TextureFormat::RGBA8Unorm, 1);
        srcTexture2[i] = CreateTexture(wgpu::TextureFormat::RGBA8Unorm, 1);

        msaaTextureView[i] = msaaTexture[i].CreateView();
        resolveTextureView[i] = resolveTexture[i].CreateView();
        srcTextureView1[i] = srcTexture1[i].CreateView();
        srcTextureView2[i] = srcTexture2[i].CreateView();

        blitBindGroup1[i] = utils::MakeBindGroup(device, bgl, {{0, srcTextureView1[i]}});
        blitBindGroup2[i] = utils::MakeBindGroup(device, bgl, {{0, srcTextureView2[i]}});

        // Clear the textures
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        float colorScale = std::max(0.1f, i / float(kNumTextures));
        {
            utils::ComboRenderPassDescriptor renderPass({msaaTextureView[i]});
            renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
            renderPass.cColorAttachments[0].clearValue = {0.0f, colorScale, 0.0f, 0.0f};

            wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
            renderPassEncoder.End();
        }
        {
            utils::ComboRenderPassDescriptor renderPass({srcTextureView1[i]});
            renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
            renderPass.cColorAttachments[0].clearValue = {colorScale, 0.0f, colorScale, 0.0f};

            wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
            renderPassEncoder.End();
        }
        {
            utils::ComboRenderPassDescriptor renderPass({srcTextureView2[i]});
            renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
            renderPass.cColorAttachments[0].clearValue = {0.0f, colorScale, colorScale, 0.0f};

            wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
            renderPassEncoder.End();
        }
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    }
}

void LoadStoreOpPerfTest::Step() {
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

    if (SupportsTimestampQuery()) {
        RecordBeginTimestamp(encoder);
    }

    for (unsigned int iteration = 0; iteration < kNumIterations; ++iteration) {
        for (uint32_t i = 0; i < kNumTextures; ++i) {
            const bool isClear = GetParam().mLoadStoreOp != LoadStoreOp::LoadAndStore;
            const bool isDiscard = GetParam().mLoadStoreOp == LoadStoreOp::ClearAndDiscard;

            // We perform two passes to mimic typical Skia multi-pass use cases where a resolve
            // texture is used both as a resolve target in an MSAA pass and directly as a
            // render attachment in a single-sampled pass. This structure also prevents the
            // driver from merging multiple identical render passes into one.

            // 1st pass: blit the src texture 1 to the MSAA texture.
            {
                utils::ComboRenderPassDescriptor renderPass({msaaTextureView[i]});
                renderPass.cColorAttachments[0].resolveTarget = resolveTextureView[i];
                renderPass.cColorAttachments[0].loadOp =
                    isClear ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load;
                renderPass.cColorAttachments[0].storeOp =
                    isDiscard ? wgpu::StoreOp::Discard : wgpu::StoreOp::Store;
                renderPass.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};

                wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
                renderPassEncoder.SetBindGroup(0, blitBindGroup1[i]);
                renderPassEncoder.SetPipeline(msaaPipeline);
                renderPassEncoder.Draw(3);
                renderPassEncoder.End();
            }
            // 2nd pass: blit the src texture 2 to the resolve texture.
            // This is a non-MSAA attachment so we always use StoreOp=Store — discarding it
            // would throw away the resolve output that subsequent passes depend on.
            {
                utils::ComboRenderPassDescriptor renderPass({resolveTextureView[i]});
                renderPass.cColorAttachments[0].loadOp =
                    isClear ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load;
                renderPass.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};

                wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
                renderPassEncoder.SetBindGroup(0, blitBindGroup2[i]);
                renderPassEncoder.SetPipeline(singleSampledPipeline);
                renderPassEncoder.Draw(3);
                renderPassEncoder.End();
            }
        }
    }

    if (SupportsTimestampQuery()) {
        RecordEndTimestampAndResolveQuerySet(encoder);
    }

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

    if (SupportsTimestampQuery()) {
        ComputeGPUElapsedTime();
    }
}

TEST_P(LoadStoreOpPerfTest, Run) {
    RunTest();
}

DAWN_INSTANTIATE_TEST_P(LoadStoreOpPerfTest,
                        {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
                         VulkanBackend()},
                        {LoadStoreOp::ClearAndDiscard, LoadStoreOp::ClearAndStore,
                         LoadStoreOp::LoadAndStore});

using StoreOp = wgpu::StoreOp;
DAWN_TEST_PARAM_STRUCT(StoreOpParams, StoreOp);

// Measures the cost of rendering with a depth attachment using loadOp=Clear and configurable
// storeOp (Discard vs Store).
class StoreOpDepthPerfTest : public DawnPerfTestWithParams<StoreOpParams> {
  public:
    StoreOpDepthPerfTest() : DawnPerfTestWithParams(kNumIterations, 1) {}
    ~StoreOpDepthPerfTest() override = default;

  private:
    void SetUpPerfTest() override;
    void Step() override;

    wgpu::Texture CreateColorTexture() {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = kWidth;
        descriptor.size.height = kHeight;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = 1;
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;
        return device.CreateTexture(&descriptor);
    }

    wgpu::Texture CreateDepthTexture() {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = kWidth;
        descriptor.size.height = kHeight;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = 1;
        descriptor.format = wgpu::TextureFormat::Depth24Plus;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;
        return device.CreateTexture(&descriptor);
    }

    static constexpr uint32_t kWidth = 4096;
    static constexpr uint32_t kHeight = 4096;
    static constexpr uint32_t kNumTextures = 5;

    std::array<wgpu::Texture, kNumTextures> colorTexture;
    std::array<wgpu::TextureView, kNumTextures> colorTextureView;
    std::array<wgpu::Texture, kNumTextures> depthTexture;
    std::array<wgpu::TextureView, kNumTextures> depthTextureView;

    wgpu::RenderPipeline pipeline;
};

void StoreOpDepthPerfTest::SetUpPerfTest() {
    const char* vs = R"(
        @vertex
        fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
            const pos = array(
                vec2f(-1.0, -1.0),
                vec2f( 3.0, -1.0),
                vec2f(-1.0,  3.0));
            return vec4f(pos[VertexIndex], 0.0, 1.0);
        })";
    const char* fs = R"(
        @fragment
        fn main() -> @location(0) vec4f {
            return vec4f(0.0, 1.0, 0.0, 1.0);
        })";

    utils::ComboRenderPipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, vs);
    pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, fs);
    pipelineDescriptor.cFragment.targetCount = 1;
    pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::All;
    pipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pipelineDescriptor.EnableDepthStencil(wgpu::TextureFormat::Depth24Plus);
    pipelineDescriptor.cDepthStencil.depthWriteEnabled = wgpu::OptionalBool::True;
    pipelineDescriptor.cDepthStencil.depthCompare = wgpu::CompareFunction::Less;
    pipeline = device.CreateRenderPipeline(&pipelineDescriptor);

    for (uint32_t i = 0; i < kNumTextures; ++i) {
        colorTexture[i] = CreateColorTexture();
        depthTexture[i] = CreateDepthTexture();
        colorTextureView[i] = colorTexture[i].CreateView();
        depthTextureView[i] = depthTexture[i].CreateView();
    }
}

void StoreOpDepthPerfTest::Step() {
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

    if (SupportsTimestampQuery()) {
        RecordBeginTimestamp(encoder);
    }

    for (unsigned int iteration = 0; iteration < kNumIterations; ++iteration) {
        for (uint32_t i = 0; i < kNumTextures; ++i) {
            utils::ComboRenderPassDescriptor renderPass({colorTextureView[i]}, depthTextureView[i]);
            renderPass.UnsetDepthStencilLoadStoreOpsForFormat(wgpu::TextureFormat::Depth24Plus);

            // Color attachment
            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};

            // Depth attachment: loadOp=Clear, storeOp=configurable
            renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
            renderPass.cDepthStencilAttachmentInfo.depthStoreOp = GetParam().mStoreOp;
            renderPass.cDepthStencilAttachmentInfo.depthClearValue = 1.0f;

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

    if (SupportsTimestampQuery()) {
        RecordEndTimestampAndResolveQuerySet(encoder);
    }

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

    if (SupportsTimestampQuery()) {
        ComputeGPUElapsedTime();
    }
}

TEST_P(StoreOpDepthPerfTest, Run) {
    RunTest();
}

DAWN_INSTANTIATE_TEST_P(StoreOpDepthPerfTest,
                        {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
                         VulkanBackend()},
                        {wgpu::StoreOp::Discard, wgpu::StoreOp::Store});

}  // anonymous namespace
}  // namespace dawn
