// Copyright 2023 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 "dawn/native/BlitDepthToDepth.h"

#include <utility>
#include <vector>

#include "dawn/common/Assert.h"
#include "dawn/common/Strings.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/BlockInfo.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/Device.h"
#include "dawn/native/InternalPipelineStore.h"
#include "dawn/native/RenderPassEncoder.h"
#include "dawn/native/RenderPipeline.h"

namespace dawn::native {

namespace {

constexpr char kBlitToDepthShaders[] = 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);
    }

    @group(0) @binding(0) var src_tex : texture_depth_2d;

    // Load the depth value and return it as the frag_depth.
    @fragment fn blit_to_depth(@builtin(position) position : vec4f) -> @builtin(frag_depth) f32 {
        return textureLoad(src_tex, vec2u(position.xy), 0);
    }
);

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

    ShaderSourceWGSL wgslDesc = {};
    ShaderModuleDescriptor shaderModuleDesc = {};
    shaderModuleDesc.nextInChain = &wgslDesc;
    wgslDesc.code = kBlitToDepthShaders;

    Ref<ShaderModuleBase> shaderModule;
    DAWN_TRY_ASSIGN(shaderModule, device->CreateShaderModule(&shaderModuleDesc));

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

    DepthStencilState dsState = {};
    dsState.format = format;
    dsState.depthWriteEnabled = wgpu::OptionalBool::True;
    dsState.depthCompare = wgpu::CompareFunction::Always;

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

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

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

}  // namespace

MaybeError BlitDepthToDepth(DeviceBase* device,
                            CommandEncoder* commandEncoder,
                            const TextureCopy& src,
                            const TextureCopy& dst,
                            const TexelExtent3D& copyExtent) {
    DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());
    // DAWN_ASSERT that the texture have depth and are not multisampled.
    DAWN_CHECK(src.texture->GetFormat().HasDepth());
    DAWN_CHECK(dst.texture->GetFormat().HasDepth());
    DAWN_CHECK(src.texture->GetSampleCount() == 1u);
    DAWN_CHECK(dst.texture->GetSampleCount() == 1u);
    DAWN_CHECK(!copyExtent.IsEmpty());

    // Note: because depth texture subresources must be copied in full, this blit
    // does not need to handle copy subrects.

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

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

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

    // TODO(crbug.com/dawn/838)
    // Metal Intel drivers incorrectly create texture views starting at a  nonzero array layer. They
    // also don't textureLoad in the shader at a non-zero array index correctly. Workaround this
    // issue by copying the non-zero array slices to a single-layer texture. That texture will be be
    // sampled as the source instead.
    ityp::vector<TexelCount, Ref<TextureViewBase>> srcViews;
    srcViews.reserve(copyExtent.depthOrArrayLayers);
    for (TexelCount z = TexelCount{0}; z < copyExtent.depthOrArrayLayers; ++z) {
        TexelCount layer = src.origin.z + z;
        Ref<TextureViewBase> srcView;
        if (layer == TexelCount{0}) {
            // The zero'th slice. We can use the original texture.
            TextureViewDescriptor viewDesc = {};
            viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
            viewDesc.dimension = wgpu::TextureViewDimension::e2D;
            viewDesc.baseMipLevel = src.mipLevel;
            viewDesc.mipLevelCount = 1u;
            DAWN_TRY_ASSIGN(srcView, src.texture->CreateView(&viewDesc));
        } else {
            // Create a single-layer intermediate texture to use as the texture source.
            TextureDescriptor intermediateTexDesc = {};
            intermediateTexDesc.format = src.texture->GetFormat().format;
            intermediateTexDesc.usage =
                wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst;
            intermediateTexDesc.size = {static_cast<uint32_t>(copyExtent.width),
                                        static_cast<uint32_t>(copyExtent.height)};

            Ref<TextureBase> intermediateTexture;
            DAWN_TRY_ASSIGN(intermediateTexture, device->CreateTexture(&intermediateTexDesc));

            // Copy from the original texture source into the intermediate.
            {
                TexelCopyTextureInfo intermediateSrc;
                intermediateSrc.texture = src.texture.Get();
                intermediateSrc.mipLevel = src.mipLevel;
                intermediateSrc.origin = {0, 0, static_cast<uint32_t>(layer)};
                intermediateSrc.aspect = wgpu::TextureAspect::All;

                TexelCopyTextureInfo intermediateDst;
                intermediateDst.texture = intermediateTexture.Get();
                intermediateDst.mipLevel = 0u;
                intermediateDst.origin = {0, 0, 0};
                intermediateDst.aspect = wgpu::TextureAspect::All;

                // Note: This does not recurse infinitely because the workaround to
                // blit depth is not needed if the destination level and layer is 0,
                // and the copy depth is 1.
                commandEncoder->APICopyTextureToTexture(&intermediateSrc, &intermediateDst,
                                                        &intermediateTexDesc.size);
            }

            // Create a texture view pointing to the intermediate texture.
            TextureViewDescriptor viewDesc = {};
            viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
            DAWN_TRY_ASSIGN(srcView, intermediateTexture->CreateView(&viewDesc));
        }
        srcViews.push_back(std::move(srcView));
    }

    // For each copied layer, blit from the source into the destination.
    for (TexelCount z = TexelCount{0}; z < copyExtent.depthOrArrayLayers; ++z) {
        Ref<BindGroupBase> bindGroup;
        {
            BindGroupEntry bgEntry = {};
            bgEntry.binding = 0;
            bgEntry.textureView = srcViews[z].Get();

            BindGroupDescriptor bgDesc = {};
            bgDesc.layout = bgl.Get();
            bgDesc.entryCount = 1;
            bgDesc.entries = &bgEntry;
            DAWN_TRY_ASSIGN(bindGroup,
                            device->CreateBindGroup(&bgDesc, UsageValidationMode::Internal));
        }

        Ref<TextureViewBase> dstView;
        {
            TextureViewDescriptor viewDesc = {};
            viewDesc.dimension = wgpu::TextureViewDimension::e2D;
            viewDesc.baseArrayLayer = static_cast<uint32_t>(dst.origin.z + z);
            viewDesc.arrayLayerCount = 1;
            viewDesc.baseMipLevel = dst.mipLevel;
            viewDesc.mipLevelCount = 1;
            DAWN_TRY_ASSIGN(dstView, dst.texture->CreateView(&viewDesc));
        }

        RenderPassDepthStencilAttachment dsAttachment = {};
        dsAttachment.view = dstView.Get();
        dsAttachment.depthClearValue = 0.0;
        dsAttachment.depthLoadOp = wgpu::LoadOp::Load;
        dsAttachment.depthStoreOp = wgpu::StoreOp::Store;
        if (dst.texture->GetFormat().HasStencil()) {
            dsAttachment.stencilLoadOp = wgpu::LoadOp::Load;
            dsAttachment.stencilStoreOp = wgpu::StoreOp::Store;
        }

        RenderPassDescriptor rpDesc = {};
        rpDesc.depthStencilAttachment = &dsAttachment;

        // Draw to perform the blit.
        Ref<RenderPassEncoder> pass = commandEncoder->BeginRenderPass(&rpDesc);
        pass->APISetBindGroup(0, bindGroup.Get());
        pass->APISetPipeline(pipeline.Get());
        pass->APIDraw(3, 1, 0, 0);
        pass->End();
    }

    return {};
}

}  // namespace dawn::native
