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

#include "src/dawn/native/vulkan/FramebufferFetchHelper.h"

#include <utility>

#include "src/dawn/native/Error.h"
#include "src/dawn/native/vulkan/DeviceVk.h"
#include "src/dawn/native/vulkan/ShaderModuleVk.h"
#include "src/dawn/native/vulkan/TextureVk.h"
#include "src/dawn/native/vulkan/UtilsVulkan.h"
#include "src/dawn/native/vulkan/VulkanError.h"
#include "src/utils/log.h"
#include "vulkan/vulkan_core.h"

namespace dawn::native::vulkan {
namespace {

ResultOrError<VkDescriptorSetLayout> MakeFramebufferFetchLayout(Device* device,
                                                                uint32_t attachmentCount) {
    std::array<VkDescriptorSetLayoutBinding, kMaxColorAttachments> bindings;
    for (uint32_t i = 0; i < attachmentCount; ++i) {
        bindings[i].binding = i;
        bindings[i].descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
        bindings[i].descriptorCount = 1;
        bindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
        bindings[i].pImmutableSamplers = nullptr;
    }

    VkDescriptorSetLayoutCreateInfo createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.bindingCount = attachmentCount;
    createInfo.pBindings = bindings.data();

    VkDescriptorSetLayout layout = VK_NULL_HANDLE;
    DAWN_TRY(CheckVkSuccess(
        device->fn.CreateDescriptorSetLayout(device->GetVkDevice(), &createInfo, nullptr, &*layout),
        "CreateDescriptorSetLayout"));
    return layout;
}

}  // namespace

FramebufferFetchHelper::FramebufferFetchHelper(Device* device) : mDevice(device) {
    DAWN_ASSERT(mDevice);
}

FramebufferFetchHelper::~FramebufferFetchHelper() {
    for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
        auto& holder = mHolders[i];
        if (holder.layout != VK_NULL_HANDLE) {
            mDevice->fn.DestroyDescriptorSetLayout(mDevice->GetVkDevice(), holder.layout, nullptr);
            holder.layout = VK_NULL_HANDLE;
        }
        holder.allocator = nullptr;
    }
}

ResultOrError<VkDescriptorSetLayout> FramebufferFetchHelper::GetLayout(uint32_t attachmentCount) {
    DAWN_CHECK(attachmentCount > 0 && attachmentCount <= kMaxColorAttachments);
    auto& holder = mHolders[attachmentCount - 1];

    if (holder.layout == VK_NULL_HANDLE) {
        DAWN_TRY_ASSIGN(holder.layout, MakeFramebufferFetchLayout(mDevice, attachmentCount));

        absl::flat_hash_map<VkDescriptorType, uint32_t> descriptorCountPerType;
        descriptorCountPerType[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT] = attachmentCount;
        holder.allocator =
            DescriptorSetAllocator::Create(mDevice, std::move(descriptorCountPerType));
    }

    return holder.layout;
}

ResultOrError<VkDescriptorSet> FramebufferFetchHelper::GetDescriptorsForRenderPass(
    const BeginRenderPassCmd* cmd) {
    uint32_t attachmentCount = AttachmentCount(cmd->attachmentState->GetColorAttachmentsMask());
    DAWN_CHECK(attachmentCount > 0);
    auto& holder = mHolders[attachmentCount - 1];

    // The descriptor set allocator is created along with the layout the first time a pipeline that
    // uses framebuffer fetch with N color attachments is created.
    DAWN_CHECK(holder.allocator);

    // Needed to work around some quirks introduced by vulkan_platform.h which causes some platforms
    // to hit compiler errors if Vulkan struct members are assigned to VK_NULL_HANDLE directly.
    static const VkSampler nullSampler = VK_NULL_HANDLE;

    DescriptorSetAllocation allocation;
    DAWN_TRY_ASSIGN(allocation, holder.allocator->Allocate(holder.layout));
    VkDescriptorSet set = allocation.set;

    std::array<VkWriteDescriptorSet, kMaxColorAttachments> writes;
    std::array<VkDescriptorImageInfo, kMaxColorAttachments> imageInfos;
    uint32_t writeCount = 0;

    for (auto i : cmd->attachmentState->GetColorAttachmentsMask()) {
        auto& attachmentInfo = cmd->colorAttachments[i];
        TextureView* textureView = ToBackend(attachmentInfo.view.Get());

        VkImageView imageView;
        if (textureView->GetDimension() == wgpu::TextureViewDimension::e3D) {
            DAWN_TRY_ASSIGN(imageView,
                            textureView->GetOrCreate2DViewOn3D(attachmentInfo.depthSlice));
        } else {
            imageView = textureView->GetHandle();
        }
        DAWN_ASSERT(imageView != VK_NULL_HANDLE);

        auto& imageInfo = imageInfos[writeCount];
        imageInfo.sampler = nullSampler;
        imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
        imageInfo.imageView = imageView;

        auto& write = writes[writeCount];
        write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
        write.pNext = nullptr;
        write.dstSet = set;
        write.dstBinding = static_cast<uint32_t>(i);
        write.dstArrayElement = 0;
        write.descriptorCount = 1;
        write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
        write.pImageInfo = &imageInfo;
        write.pBufferInfo = nullptr;
        write.pTexelBufferView = nullptr;

        writeCount++;
    }
    DAWN_ASSERT(writeCount == attachmentCount);

    mDevice->fn.UpdateDescriptorSets(mDevice->GetVkDevice(), attachmentCount, writes.data(), 0,
                                     nullptr);

    // This will delete the VkDescriptorSet after the pending command serial has completed.
    holder.allocator->Deallocate(&allocation);

    return set;
}

}  // namespace dawn::native::vulkan
