// 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 "src/dawn/native/BlitBufferToTexture.h"

#include <sstream>
#include <string>
#include <string_view>
#include <utility>

#include "src/dawn/common/Strings.h"
#include "src/dawn/native/BindGroup.h"
#include "src/dawn/native/CommandBuffer.h"
#include "src/dawn/native/CommandEncoder.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/InternalPipelineStore.h"
#include "src/dawn/native/Queue.h"
#include "src/dawn/native/RenderPassEncoder.h"
#include "src/dawn/native/RenderPipeline.h"
#include "src/dawn/native/utils/NativeHelpers.h"
#include "src/utils/assert.h"

namespace dawn::native {

namespace {

constexpr std::string_view kShaderCommonSrc = DAWN_MULTILINE(
    @vertex fn vert_fullscreen_quad(
    @builtin(vertex_index) vertex_index : 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[vertex_index], 0.0, 1.0);
    }

    struct Params {
    srcOffset : u32,
    bytesPerRow : u32,
    dstOrigin : vec2u
    };

    @group(0) @binding(0) var<storage, read> src_buf : array<u32>;
    @group(0) @binding(1) var<uniform> params : Params;

    fn loadU8AsU32(byteOffset: u32) -> u32 {
        let uintOffset = byteOffset >> 2;
        let uintModOffset = byteOffset & 3;
        let bitShift = uintModOffset * 8;
        return (src_buf[uintOffset] >> bitShift) & 0xff;
    }

    fn loadU16AsU32(byteOffset: u32) -> u32 {
        let firstHalf = loadU8AsU32(byteOffset);
        let secondHalf = loadU8AsU32(byteOffset + 1);
        return firstHalf | (secondHalf << 8);
    }

    // byteOffset is expected to be aligned to 4.
    fn loadU32(byteOffset: u32) -> u32 {
        let uintOffset = byteOffset >> 2;
        return src_buf[uintOffset];
    }

    // byteOffset is expected to be aligned to 4.
    fn loadTwoU32s(byteOffset: u32) -> vec2u {
        return vec2u(loadU32(byteOffset), loadU32(byteOffset + 4));
    }

    @fragment fn blit_buffer_to_texture(
        @builtin(position) screen_position : vec4f
    ) -> @location(0) vec4f {
        let iposition = vec2u(screen_position.xy) - params.dstOrigin;

        let srcOffset = params.srcOffset + iposition.x * kPixelSize + iposition.y * params.bytesPerRow;

        return unpackData(srcOffset);
    }
);

constexpr std::string_view kUnpackR8Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return unpack4x8unorm(loadU8AsU32(byteOffset));
    }
);

constexpr std::string_view kUnpackRG8Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return unpack4x8unorm(loadU16AsU32(byteOffset));
    }
);

constexpr std::string_view kUnpackRGBA8Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return unpack4x8unorm(loadU32(byteOffset));
    }
);

constexpr std::string_view kUnpackBGRA8Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return unpack4x8unorm(loadU32(byteOffset)).bgra;
    }
);

constexpr std::string_view kUnpackRGB10A2Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        let data = loadU32(byteOffset);
        let r = f32((data & 0x3ff)) / 1023.0;
        let g = f32(((data >> 10) & 0x3ff)) / 1023.0;
        let b = f32(((data >> 20) & 0x3ff)) / 1023.0;
        let a = f32(((data >> 30) & 0x3)) / 3.0;
        return vec4f(r, g, b, a);
    }
);

constexpr std::string_view kUnpackR16Float = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return vec4f(unpack2x16float(loadU16AsU32(byteOffset)), 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackR16Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return vec4f(f32(loadU16AsU32(byteOffset)) / f32(0xffff), 0.0, 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackRG16Float = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return vec4f(unpack2x16float(loadU32(byteOffset)), 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackRG16Unorm = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        let word = loadU32(byteOffset);
        let x = f32(word & 0xffff);
        let y = f32(word >> 16);
        return vec4f(vec2f(x, y) / f32(0xffff), 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackRGBA16Float = DAWN_MULTILINE(
fn unpackData(byteOffset: u32) -> vec4f {
    let data = loadTwoU32s(byteOffset);
    return vec4f(unpack2x16float(data.x), unpack2x16float(data.y));
}
);

constexpr std::string_view kUnpackRGBA16Unorm = DAWN_MULTILINE(
fn unpackData(byteOffset: u32) -> vec4f {
    let words = loadTwoU32s(byteOffset);
    let x = f32(words[0] & 0xffff);
    let y = f32(words[0] >> 16);
    let z = f32(words[1] & 0xffff);
    let w = f32(words[1] >> 16);
    return vec4f(x, y, z, w) / f32(0xffff);
}
);

constexpr std::string_view kUnpackR32Float = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        //
        return vec4f(bitcast<f32>(loadU32(byteOffset)), 0.0, 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackRG32Float = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        let color = bitcast<vec2f>(loadTwoU32s(byteOffset));
        return vec4f(color, 0.0, 1.0);
    }
);

constexpr std::string_view kUnpackRGBA32Float = DAWN_MULTILINE(
    fn unpackData(byteOffset: u32) -> vec4f {
        return vec4f(bitcast<vec2f>(loadTwoU32s(byteOffset)),
                    bitcast<vec2f>(loadTwoU32s(byteOffset + 8)));
    }
);

std::string GenerateShaderSource(wgpu::TextureFormat format) {
    int pixelSize = 0;
    std::ostringstream ss;
    switch (format) {
        case wgpu::TextureFormat::R8Unorm:
            pixelSize = 1;
            ss << kUnpackR8Unorm;
            break;
        case wgpu::TextureFormat::RG8Unorm:
            pixelSize = 2;
            ss << kUnpackRG8Unorm;
            break;
        case wgpu::TextureFormat::RGBA8Unorm:
            pixelSize = 4;
            ss << kUnpackRGBA8Unorm;
            break;
        case wgpu::TextureFormat::BGRA8Unorm:
            pixelSize = 4;
            ss << kUnpackBGRA8Unorm;
            break;
        case wgpu::TextureFormat::RGB10A2Unorm:
            pixelSize = 4;
            ss << kUnpackRGB10A2Unorm;
            break;
        case wgpu::TextureFormat::R16Float:
            pixelSize = 2;
            ss << kUnpackR16Float;
            break;
        case wgpu::TextureFormat::R16Unorm:
            pixelSize = 2;
            ss << kUnpackR16Unorm;
            break;
        case wgpu::TextureFormat::RG16Float:
            pixelSize = 4;
            ss << kUnpackRG16Float;
            break;
        case wgpu::TextureFormat::RG16Unorm:
            pixelSize = 4;
            ss << kUnpackRG16Unorm;
            break;
        case wgpu::TextureFormat::RGBA16Float:
            pixelSize = 8;
            ss << kUnpackRGBA16Float;
            break;
        case wgpu::TextureFormat::RGBA16Unorm:
            pixelSize = 8;
            ss << kUnpackRGBA16Unorm;
            break;
        case wgpu::TextureFormat::R32Float:
            pixelSize = 4;
            ss << kUnpackR32Float;
            break;
        case wgpu::TextureFormat::RG32Float:
            pixelSize = 8;
            ss << kUnpackRG32Float;
            break;
        case wgpu::TextureFormat::RGBA32Float:
            pixelSize = 16;
            ss << kUnpackRGBA32Float;
            break;
        default:
            DAWN_UNREACHABLE();
    }

    ss << "const kPixelSize = " << pixelSize << ";";
    ss << kShaderCommonSrc;

    return ss.str();
}

ResultOrError<Ref<RenderPipelineBase>> GetOrCreatePipeline(DeviceBase* device,
                                                           wgpu::TextureFormat format) {
    InternalPipelineStore* store = device->GetInternalPipelineStore();
    {
        auto it = store->blitBufferToTexturePipelines.find(format);
        if (it != store->blitBufferToTexturePipelines.end()) {
            return it->second;
        }
    }

    // vertex shader's source.
    ShaderSourceWGSL wgslDesc = {};
    ShaderModuleDescriptor shaderModuleDesc = {};
    shaderModuleDesc.nextInChain = &wgslDesc;

    // shader's source will depend on format key.
    std::string shaderCode = GenerateShaderSource(format);
    wgslDesc.code = shaderCode.c_str();
    Ref<ShaderModuleBase> shaderModule;
    DAWN_TRY_ASSIGN(shaderModule, device->CreateShaderModule(&shaderModuleDesc));

    FragmentState fragmentState = {};
    fragmentState.module = shaderModule.Get();
    fragmentState.entryPoint = "blit_buffer_to_texture";

    // Color target states.
    ColorTargetState colorTarget = {};
    colorTarget.format = format;
    colorTarget.writeMask = wgpu::ColorWriteMask::All;

    fragmentState.targets = SpanFromRef<ColorAttachmentIndex>(colorTarget);

    RenderPipelineDescriptor renderPipelineDesc = {};
    renderPipelineDesc.label = "blit_buffer_to_texture";
    renderPipelineDesc.vertex.module = shaderModule.Get();
    renderPipelineDesc.vertex.entryPoint = "vert_fullscreen_quad";
    renderPipelineDesc.fragment = &fragmentState;

    // Bind group layout.
    Ref<BindGroupLayoutBase> bindGroupLayout;
    DAWN_TRY_ASSIGN(bindGroupLayout,
                    utils::MakeBindGroupLayout(
                        device,
                        {
                            {0, wgpu::ShaderStage::Fragment, kInternalReadOnlyStorageBufferBinding},
                            {1, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform},
                        },
                        /* allowInternalBinding */ true));

    Ref<PipelineLayoutBase> pipelineLayout;
    DAWN_TRY_ASSIGN(pipelineLayout, utils::MakeBasicPipelineLayout(device, bindGroupLayout));
    renderPipelineDesc.layout = pipelineLayout.Get();

    Ref<RenderPipelineBase> pipeline;
    DAWN_TRY_ASSIGN(pipeline, device->CreateRenderPipeline(&renderPipelineDesc));

    store->blitBufferToTexturePipelines.emplace(format, pipeline);
    return pipeline;
}

}  // anonymous namespace

bool IsFormatSupportedByBufferToTextureBlit(wgpu::TextureFormat format) {
    // TODO(348653642): Eventually we should support all non-compressed formats. For now, just list
    // a subset of them that we support.
    switch (format) {
        case wgpu::TextureFormat::R8Unorm:
        case wgpu::TextureFormat::RG8Unorm:
        case wgpu::TextureFormat::RGBA8Unorm:
        case wgpu::TextureFormat::BGRA8Unorm:
        case wgpu::TextureFormat::RGB10A2Unorm:
        case wgpu::TextureFormat::R16Float:
        case wgpu::TextureFormat::R16Unorm:
        case wgpu::TextureFormat::RG16Float:
        case wgpu::TextureFormat::RG16Unorm:
        case wgpu::TextureFormat::RGBA16Float:
        case wgpu::TextureFormat::RGBA16Unorm:
        case wgpu::TextureFormat::R32Float:
        case wgpu::TextureFormat::RG32Float:
        case wgpu::TextureFormat::RGBA32Float:
            return true;
        default:
            return false;
    }
}

bool IsBufferToTextureBlitSupported(BufferBase* buffer,
                                    const TextureCopy& dst,
                                    const TexelExtent3D& copyExtent) {
    if (!(buffer->GetInternalUsage() &
          (kReadOnlyStorageBuffer | kInternalStorageBuffer | wgpu::BufferUsage::Storage))) {
        return false;
    }

    if (!IsFormatSupportedByBufferToTextureBlit(dst.texture->GetFormat().format)) {
        return false;
    }

    if (dst.texture->GetDimension() == wgpu::TextureDimension::e1D) {
        // 1D texture cannot be rendered to so skip it.
        return false;
    }

    if (dst.aspect != Aspect::Color) {
        // Don't support multiplanar copies yet.
        return false;
    }

    // Must have non-zero copy size.
    return copyExtent.width * copyExtent.height * copyExtent.depthOrArrayLayers > TexelCount{0u};
}

MaybeError BlitBufferToTexture(DeviceBase* device,
                               CommandEncoder* commandEncoder,
                               BufferBase* buffer,
                               const TexelCopyBufferLayout& src,
                               const TextureCopy& dst,
                               const TexelExtent3D& copyExtent) {
    DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());

    // This function assumes bytesPerRow is multiples of 4. Normally it's required that
    // bytesPerRow is aligned to 256. However some backends might enable
    // DawnTexelCopyBufferRowAlignment feature to relax the alignment. Currently only D3D11 backend
    // enables this feature, and the relaxed alignment there is 4.
    DAWN_CHECK((src.bytesPerRow % 4) == 0);

    DAWN_ASSERT(buffer->GetInternalUsage() &
                (kReadOnlyStorageBuffer | kInternalStorageBuffer | wgpu::BufferUsage::Storage));

    DAWN_CHECK(!copyExtent.IsEmpty());

    // Allow internal usages since we need to use the destination
    // as a render attachment.
    auto scope = commandEncoder->MakeInternalUsageScope();

    Ref<RenderPipelineBase> pipeline;
    DAWN_TRY_ASSIGN(pipeline, GetOrCreatePipeline(device, dst.texture->GetFormat().format));

    Ref<BindGroupLayoutBase> bgl;
    DAWN_TRY_ASSIGN(bgl, pipeline->GetBindGroupLayout(0));

    const auto ssboAlignment = device->GetLimits().v1.minStorageBufferOffsetAlignment;
    DAWN_ASSERT(IsPowerOfTwo(ssboAlignment));

    wgpu::TextureViewDimension viewDimension;
    uint32_t baseDepth = 0;
    uint32_t baseArray = 0;
    uint32_t depthStep = 0;
    uint32_t arrayStep = 0;
    switch (dst.texture->GetDimension()) {
        case wgpu::TextureDimension::e1D:
            DAWN_UNREACHABLE();
            break;
        case wgpu::TextureDimension::e3D:
            viewDimension = wgpu::TextureViewDimension::e3D;
            baseDepth = dchecked_cast<uint32_t>(dst.origin.z);
            depthStep = 1;
            break;
        default:
            viewDimension = wgpu::TextureViewDimension::e2D;
            baseArray = dchecked_cast<uint32_t>(dst.origin.z);
            arrayStep = 1;
            break;
    }

    for (TexelCount z{0u}; z < copyExtent.depthOrArrayLayers; ++z) {
        Ref<TextureViewBase> dstView;
        {
            TextureViewDescriptor viewDesc = {};
            viewDesc.dimension = viewDimension;
            viewDesc.baseArrayLayer = baseArray + arrayStep * dchecked_cast<uint32_t>(z);
            viewDesc.arrayLayerCount = 1;
            viewDesc.baseMipLevel = dst.mipLevel;
            viewDesc.mipLevelCount = 1;
            DAWN_TRY_ASSIGN(dstView, dst.texture->CreateView(&viewDesc));
        }

        const uint64_t srcOffset = src.offset + static_cast<uint64_t>(dchecked_cast<uint32_t>(z)) *
                                                    src.rowsPerImage * src.bytesPerRow;
        const uint64_t srcBufferBindingOffset = AlignDown(srcOffset, ssboAlignment);
        const uint32_t shaderReadOffset = static_cast<uint32_t>(srcOffset & (ssboAlignment - 1));
        Ref<BufferBase> paramsBuffer;
        {
            DAWN_TRY_ASSIGN(paramsBuffer,
                            device->GetOrCreateTemporaryUniformBuffer(sizeof(uint32_t) * 4));

            std::array<uint32_t, 4> params{};
            params[0] = shaderReadOffset;
            params[1] = src.bytesPerRow;
            params[2] = dchecked_cast<uint32_t>(dst.origin.x);
            params[3] = dchecked_cast<uint32_t>(dst.origin.y);
            commandEncoder->APIWriteBuffer(paramsBuffer.Get(), 0,
                                           SpanAsBytes(Span<const uint32_t>(params)));
        }

        Ref<BindGroupBase> bindGroup;
        DAWN_TRY_ASSIGN(bindGroup, utils::MakeBindGroup(device, bgl,
                                                        {
                                                            {0, buffer, srcBufferBindingOffset},
                                                            {1, paramsBuffer},
                                                        },
                                                        UsageValidationMode::Internal));

        RenderPassColorAttachment colorAttachment;
        colorAttachment.view = dstView.Get();
        if (depthStep) {
            colorAttachment.depthSlice = baseDepth + depthStep * dchecked_cast<uint32_t>(z);
        }
        colorAttachment.loadOp = wgpu::LoadOp::Load;
        colorAttachment.storeOp = wgpu::StoreOp::Store;

        RenderPassDescriptor rpDesc = {};
        rpDesc.colorAttachments = SpanFromRef<ColorAttachmentIndex>(colorAttachment);

        Ref<RenderPassEncoder> pass = commandEncoder->BeginRenderPass(&rpDesc);
        // Bind the resources.
        pass->APISetBindGroup(0, bindGroup.Get());
        pass->APISetViewport(static_cast<float>(dchecked_cast<uint32_t>(dst.origin.x)),
                             static_cast<float>(dchecked_cast<uint32_t>(dst.origin.y)),
                             static_cast<float>(dchecked_cast<uint32_t>(copyExtent.width)),
                             static_cast<float>(dchecked_cast<uint32_t>(copyExtent.height)), 0.f,
                             1.f);

        // Draw to perform the blit.
        pass->APISetPipeline(pipeline.Get());
        pass->APIDraw(3, 1, 0, 0);

        pass->End();
    }
    return {};
}

}  // namespace dawn::native
