/*
 * Copyright 2023 Rive
 */

#include "rive/renderer/vulkan/vulkan_context.hpp"

#include "rive/rive_types.hpp"
#include <vk_mem_alloc.h>

namespace rive::gpu
{
// Returns null if the driver can't give us an allocator, leaving it to the
// caller to decide whether that is recoverable.
static VmaAllocator make_vma_allocator(
    VkInstance instance,
    VkPhysicalDevice physicalDevice,
    VkDevice device,
    uint32_t apiVersion,
    PFN_vkGetInstanceProcAddr pfnvkGetInstanceProcAddr)
{
    VmaVulkanFunctions vmaVulkanFunctions = {
        .vkGetInstanceProcAddr = pfnvkGetInstanceProcAddr,
        .vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
            pfnvkGetInstanceProcAddr(instance, "vkGetDeviceProcAddr")),
        .vkGetPhysicalDeviceProperties =
            reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
                pfnvkGetInstanceProcAddr(instance,
                                         "vkGetPhysicalDeviceProperties")),
    };

    VmaAllocatorCreateInfo vmaCreateInfo = {
        // We are single-threaded.
        .flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT,
        .physicalDevice = physicalDevice,
        .device = device,
        .pVulkanFunctions = &vmaVulkanFunctions,
        .instance = instance,
        .vulkanApiVersion = apiVersion,
    };

    VmaAllocator vmaAllocator;
    if (!VK_SUCCEEDED(vmaCreateAllocator(&vmaCreateInfo, &vmaAllocator),
                      "the VMA allocator"))
    {
        return VK_NULL_HANDLE;
    }
    return vmaAllocator;
}

rcp<VulkanContext> VulkanContext::make(
    VkInstance instance,
    VkPhysicalDevice physicalDevice,
    VkDevice device,
    const VulkanFeatures& features,
    PFN_vkGetInstanceProcAddr pfnvkGetInstanceProcAddr,
    bool enableDebugNames)
{
    // Building the allocator first means a failure never constructs a context
    // at all.
    VmaAllocator vmaAllocator = make_vma_allocator(instance,
                                                   physicalDevice,
                                                   device,
                                                   features.apiVersion,
                                                   pfnvkGetInstanceProcAddr);
    if (vmaAllocator == VK_NULL_HANDLE)
    {
        return nullptr;
    }
    return rcp<VulkanContext>(new VulkanContext(instance,
                                                physicalDevice,
                                                device,
                                                features,
                                                pfnvkGetInstanceProcAddr,
                                                vmaAllocator,
                                                enableDebugNames));
}

VulkanContext::VulkanContext(VkInstance instance,
                             VkPhysicalDevice physicalDevice_,
                             VkDevice device_,
                             const VulkanFeatures& features_,
                             PFN_vkGetInstanceProcAddr pfnvkGetInstanceProcAddr,
                             VmaAllocator vmaAllocator,
                             bool enableDebugNames) :
    instance(instance),
    physicalDevice(physicalDevice_),
    device(device_),
#define LOAD_VULKAN_INSTANCE_COMMAND(CMD)                                      \
    CMD(reinterpret_cast<PFN_vk##CMD>(                                         \
        pfnvkGetInstanceProcAddr(instance, "vk" #CMD))),
    RIVE_VULKAN_INSTANCE_COMMANDS(LOAD_VULKAN_INSTANCE_COMMAND)
#undef LOAD_VULKAN_INSTANCE_COMMAND
        SetDebugUtilsObjectNameEXT(
            enableDebugNames
                ? reinterpret_cast<PFN_vkSetDebugUtilsObjectNameEXT>(
                      pfnvkGetInstanceProcAddr(instance,
                                               "vkSetDebugUtilsObjectNameEXT"))
                : nullptr),
#define LOAD_VULKAN_DEVICE_COMMAND(CMD)                                        \
    CMD(reinterpret_cast<PFN_vk##CMD>(GetDeviceProcAddr(device, "vk" #CMD))),
    RIVE_VULKAN_DEVICE_COMMANDS(LOAD_VULKAN_DEVICE_COMMAND)
#undef LOAD_VULKAN_DEVICE_COMMAND
        physicalDeviceProperties([this]() {
            VkPhysicalDeviceProperties props;
            GetPhysicalDeviceProperties(physicalDevice, &props);
            return props;
        }()),
    features([this, mutableFeatures = features_]() mutable {
        if (physicalDeviceProperties.vendorID == vkutil::vendors::Qualcomm ||
            physicalDeviceProperties.vendorID == vkutil::vendors::Imagination)
        {
            // We have observed rendering issues on both Adreno and PowerVR when
            // using VK_EXT_color_write_enable.
            mutableFeatures.colorWriteEnable = false;
        }
        return mutableFeatures;
    }()),
    m_vmaAllocator(vmaAllocator != VK_NULL_HANDLE
                       ? vmaAllocator
                       : make_vma_allocator(instance,
                                            physicalDevice_,
                                            device_,
                                            features_.apiVersion,
                                            pfnvkGetInstanceProcAddr))
{
    // A constructor has nowhere to report this; make() is the path that can
    // recover. make_vma_allocator() already printed why.
    if (m_vmaAllocator == VK_NULL_HANDLE)
    {
        abort();
    }

    // Check that we weren't told the device was more capable than it is
    assert(physicalDeviceProperties.apiVersion >= features.apiVersion &&
           "Supplied API version should not be newer than the physical device");

    // VK spec says between D24_S8 and D32_S8, one of them must be supported
    m_supportsD24S8 = isFormatSupportedWithFeatureFlags(
        VK_FORMAT_D24_UNORM_S8_UINT,
        VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);

    // This assert should never fire unless some hardware is breaking the VK
    // spec by reporting that it does not support one of these formats.
    assert((m_supportsD24S8 ||
            isFormatSupportedWithFeatureFlags(
                VK_FORMAT_D32_SFLOAT_S8_UINT,
                VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
           "No suitable depth format supported!");
}

VulkanContext::~VulkanContext() { vmaDestroyAllocator(m_vmaAllocator); }

bool VulkanContext::isFormatSupportedWithFeatureFlags(
    VkFormat format,
    VkFormatFeatureFlagBits featureFlags)
{
    // Can flesch this out, but currently just checks if format's optimal tiling
    // features include the provided bits.
    VkFormatProperties properties;
    GetPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
    return properties.optimalTilingFeatures & featureFlags;
}

rcp<vkutil::Buffer> VulkanContext::makeBuffer(const VkBufferCreateInfo& info,
                                              vkutil::Mappability mappability)
{
    return rcp(new vkutil::Buffer(ref_rcp(this), info, mappability));
}

rcp<vkutil::Image> VulkanContext::makeImage(const VkImageCreateInfo& info,
                                            const char* name)
{
    return rcp(new vkutil::Image(ref_rcp(this), info, name));
}

rcp<vkutil::Image> VulkanContext::makeExternalImage(
    VkImage existingImage,
    const VkImageCreateInfo& info,
    const char* name)
{
    return rcp(new vkutil::Image(ref_rcp(this), existingImage, info, name));
}

rcp<vkutil::Framebuffer> VulkanContext::makeFramebuffer(
    const VkFramebufferCreateInfo& info)
{
    return rcp(new vkutil::Framebuffer(ref_rcp(this), info));
}

static VkImageViewType image_view_type_for_image_type(VkImageType type)
{
    switch (type)
    {
        case VK_IMAGE_TYPE_2D:
            return VK_IMAGE_VIEW_TYPE_2D;
        default:
            fprintf(
                stderr,
                "vkutil::image_view_type_for_image_type: VkImageType %u is not "
                "supported\n",
                type);
    }
    RIVE_UNREACHABLE();
}

static VkImageAspectFlags image_aspect_flags_for_format(VkFormat format)
{
    switch (format)
    {
        case VK_FORMAT_D24_UNORM_S8_UINT:
        case VK_FORMAT_D32_SFLOAT_S8_UINT:
            return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
        default:
            return VK_IMAGE_ASPECT_COLOR_BIT;
    }
    RIVE_UNREACHABLE();
}

rcp<vkutil::ImageView> VulkanContext::makeImageView(rcp<vkutil::Image> image,
                                                    const char* name)
{
    const VkImageCreateInfo& texInfo = image->info();

    return makeImageView(
        image,
        {
            .viewType = image_view_type_for_image_type(texInfo.imageType),
            .format = texInfo.format,
            .subresourceRange =
                {
                    .aspectMask = image_aspect_flags_for_format(texInfo.format),
                    .levelCount = texInfo.mipLevels,
                    .layerCount = 1,
                },
        },
        name);
}

rcp<vkutil::ImageView> VulkanContext::makeImageView(
    rcp<vkutil::Image> image,
    const VkImageViewCreateInfo& info,
    const char* name)
{
    assert(image);
    return rcp(
        new vkutil::ImageView(ref_rcp(this), std::move(image), info, name));
}

rcp<vkutil::ImageView> VulkanContext::makeExternalImageView(
    const VkImageViewCreateInfo& info,
    const char* name)
{
    return rcp<vkutil::ImageView>(
        new vkutil::ImageView(ref_rcp(this), nullptr, info, name));
}

rcp<vkutil::Texture2D> VulkanContext::makeTexture2D(
    const VkImageCreateInfo& info,
    const char* name)
{
    return rcp<vkutil::Texture2D>(
        new vkutil::Texture2D(ref_rcp(this), info, name));
}

rcp<vkutil::Texture2D> VulkanContext::makeTexture2D(
    rcp<vkutil::Image> existingImage,
    const char* name)
{
    return rcp<vkutil::Texture2D>(
        new vkutil::Texture2D(ref_rcp(this), std::move(existingImage), name));
}

void VulkanContext::updateImageDescriptorSets(
    VkDescriptorSet vkDescriptorSet,
    VkWriteDescriptorSet writeSet,
    std::initializer_list<VkDescriptorImageInfo> imageInfos)
{
    writeSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
    writeSet.dstSet = vkDescriptorSet;
    writeSet.descriptorCount =
        math::lossless_numeric_cast<uint32_t>(imageInfos.size());
    writeSet.pImageInfo = imageInfos.begin();
    UpdateDescriptorSets(device, 1, &writeSet, 0, nullptr);
}

void VulkanContext::updateBufferDescriptorSets(
    VkDescriptorSet vkDescriptorSet,
    VkWriteDescriptorSet writeSet,
    std::initializer_list<VkDescriptorBufferInfo> bufferInfos)
{
    writeSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
    writeSet.dstSet = vkDescriptorSet;
    writeSet.descriptorCount =
        math::lossless_numeric_cast<uint32_t>(bufferInfos.size());
    writeSet.pBufferInfo = bufferInfos.begin();
    UpdateDescriptorSets(device, 1, &writeSet, 0, nullptr);
}

void VulkanContext::memoryBarrier(VkCommandBuffer commandBuffer,
                                  VkPipelineStageFlags srcStageMask,
                                  VkPipelineStageFlags dstStageMask,
                                  VkDependencyFlags dependencyFlags,
                                  VkMemoryBarrier memoryBarrier)
{
    memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
    CmdPipelineBarrier(commandBuffer,
                       srcStageMask,
                       dstStageMask,
                       dependencyFlags,
                       1,
                       &memoryBarrier,
                       0,
                       nullptr,
                       0,
                       nullptr);
}

void VulkanContext::imageMemoryBarriers(
    VkCommandBuffer commandBuffer,
    VkPipelineStageFlags srcStageMask,
    VkPipelineStageFlags dstStageMask,
    VkDependencyFlags dependencyFlags,
    uint32_t count,
    VkImageMemoryBarrier* imageMemoryBarriers)
{
    for (uint32_t i = 0; i < count; ++i)
    {
        auto& imageMemoryBarrier = imageMemoryBarriers[i];
        imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
        if (imageMemoryBarrier.subresourceRange.aspectMask == 0)
        {
            imageMemoryBarrier.subresourceRange.aspectMask =
                VK_IMAGE_ASPECT_COLOR_BIT;
        }
        if (imageMemoryBarrier.subresourceRange.levelCount == 0)
        {
            imageMemoryBarrier.subresourceRange.levelCount =
                VK_REMAINING_MIP_LEVELS;
        }
        if (imageMemoryBarrier.subresourceRange.layerCount == 0)
        {
            imageMemoryBarrier.subresourceRange.layerCount =
                VK_REMAINING_ARRAY_LAYERS;
        }
    }
    CmdPipelineBarrier(commandBuffer,
                       srcStageMask,
                       dstStageMask,
                       dependencyFlags,
                       0,
                       nullptr,
                       0,
                       nullptr,
                       count,
                       imageMemoryBarriers);
}

const vkutil::ImageAccess& VulkanContext::simpleImageMemoryBarrier(
    VkCommandBuffer commandBuffer,
    const vkutil::ImageAccess& srcAccess,
    const vkutil::ImageAccess& dstAccess,
    VkImage image,
    vkutil::ImageAccessAction imageAccessAction,
    VkDependencyFlags dependencyFlags)
{
    assert(image != VK_NULL_HANDLE);
    if (srcAccess != dstAccess)
    {
        imageMemoryBarrier(
            commandBuffer,
            srcAccess.pipelineStages,
            dstAccess.pipelineStages,
            dependencyFlags,
            {
                .srcAccessMask = srcAccess.accessMask,
                .dstAccessMask = dstAccess.accessMask,
                .oldLayout = imageAccessAction ==
                                     vkutil::ImageAccessAction::preserveContents
                                 ? srcAccess.layout
                                 : VK_IMAGE_LAYOUT_UNDEFINED,
                .newLayout = dstAccess.layout,
                .image = image,
            });
    }
    return dstAccess;
}

void VulkanContext::bufferMemoryBarrier(
    VkCommandBuffer commandBuffer,
    VkPipelineStageFlags srcStageMask,
    VkPipelineStageFlags dstStageMask,
    VkDependencyFlags dependencyFlags,
    VkBufferMemoryBarrier bufferMemoryBarrier)
{
    bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
    if (bufferMemoryBarrier.size == 0)
    {
        bufferMemoryBarrier.size = VK_WHOLE_SIZE;
    }
    CmdPipelineBarrier(commandBuffer,
                       srcStageMask,
                       dstStageMask,
                       dependencyFlags,
                       0,
                       nullptr,
                       1,
                       &bufferMemoryBarrier,
                       0,
                       nullptr);
}

void VulkanContext::clearColorImage(VkCommandBuffer commandBuffer,
                                    ColorInt clearColor,
                                    VkImage image,
                                    VkImageLayout imageLayout)
{
    const VkClearColorValue colorClearValue = {
        vkutil::color_clear_rgba32f(clearColor)};

    const VkImageSubresourceRange colorClearRange = {
        .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
        .levelCount = 1,
        .layerCount = 1,
    };

    CmdClearColorImage(commandBuffer,
                       image,
                       imageLayout,
                       &colorClearValue,
                       1,
                       &colorClearRange);
}

void VulkanContext::blitSubRect(VkCommandBuffer commandBuffer,
                                VkImage srcImage,
                                VkImageLayout srcImageLayout,
                                VkImage dstImage,
                                VkImageLayout dstImageLayout,
                                const IAABB& blitBounds)
{
    if (blitBounds.empty())
    {
        return;
    }

    VkImageBlit imageBlit = {
        .srcSubresource =
            {
                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                .layerCount = 1,
            },
        .dstSubresource =
            {
                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                .layerCount = 1,
            },
    };

    imageBlit.srcOffsets[0] = {blitBounds.left, blitBounds.top, 0};
    imageBlit.srcOffsets[1] = {blitBounds.right, blitBounds.bottom, 1};

    imageBlit.dstOffsets[0] = {blitBounds.left, blitBounds.top, 0};
    imageBlit.dstOffsets[1] = {blitBounds.right, blitBounds.bottom, 1};

    CmdBlitImage(commandBuffer,
                 srcImage,
                 srcImageLayout,
                 dstImage,
                 dstImageLayout,
                 1,
                 &imageBlit,
                 VK_FILTER_NEAREST);
}

void VulkanContext::setDebugNameIfEnabled(uint64_t handle,
                                          VkObjectType objectType,
                                          const char* name)
{
    // A null handle means creation failed; naming it would be invalid usage.
    if (SetDebugUtilsObjectNameEXT != nullptr && name != nullptr && handle != 0)
    {
        VkDebugUtilsObjectNameInfoEXT nameInfo = {
            .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
            .objectType = objectType,
            .objectHandle = handle,
            .pObjectName = name,
        };

        SetDebugUtilsObjectNameEXT(device, &nameInfo);
    }
}

} // namespace rive::gpu
