// Copyright 2019 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/UtilsVulkan.h"

#include "src/dawn/native/EnumMaskIterator.h"
#include "src/dawn/native/Format.h"
#include "src/dawn/native/Pipeline.h"
#include "src/dawn/native/ShaderModule.h"
#include "src/dawn/native/vulkan/DeviceVk.h"
#include "src/dawn/native/vulkan/Forward.h"
#include "src/dawn/native/vulkan/PhysicalDeviceVk.h"
#include "src/dawn/native/vulkan/TextureVk.h"
#include "src/dawn/native/vulkan/VulkanError.h"
#include "src/dawn/native/vulkan/VulkanFunctions.h"
#include "src/utils/assert.h"
#include "src/utils/compiler.h"
#include "src/utils/numeric.h"

namespace dawn::native::vulkan {

constexpr char kDeviceDebugPrefix[] = "DawnDbg=";
constexpr char kDeviceDebugSeparator[] = ";";

#define VK_OBJECT_TYPE_GETTER(object, objectType)         \
    template <>                                           \
    VkObjectType GetVkObjectType<object>(object handle) { \
        return objectType;                                \
    }

VK_OBJECT_TYPE_GETTER(VkBuffer, VK_OBJECT_TYPE_BUFFER)
VK_OBJECT_TYPE_GETTER(VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
VK_OBJECT_TYPE_GETTER(VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET)
VK_OBJECT_TYPE_GETTER(VkPipeline, VK_OBJECT_TYPE_PIPELINE)
VK_OBJECT_TYPE_GETTER(VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT)
VK_OBJECT_TYPE_GETTER(VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL)
VK_OBJECT_TYPE_GETTER(VkSampler, VK_OBJECT_TYPE_SAMPLER)
VK_OBJECT_TYPE_GETTER(VkShaderModule, VK_OBJECT_TYPE_SHADER_MODULE)
VK_OBJECT_TYPE_GETTER(VkImage, VK_OBJECT_TYPE_IMAGE)
VK_OBJECT_TYPE_GETTER(VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW)
VK_OBJECT_TYPE_GETTER(VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW)

#undef VK_OBJECT_TYPE_GETTER

uint32_t ToPushConstantBytes(const ImmediateMask& immediates) {
    return static_cast<uint32_t>(immediates.count()) * kImmediateElementByteSize;
}

uint32_t AttachmentCount(const ColorAttachmentMask& mask) {
    return static_cast<uint32_t>(mask.count());
}

VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op) {
    switch (op) {
        case wgpu::CompareFunction::Never:
            return VK_COMPARE_OP_NEVER;
        case wgpu::CompareFunction::Less:
            return VK_COMPARE_OP_LESS;
        case wgpu::CompareFunction::LessEqual:
            return VK_COMPARE_OP_LESS_OR_EQUAL;
        case wgpu::CompareFunction::Greater:
            return VK_COMPARE_OP_GREATER;
        case wgpu::CompareFunction::GreaterEqual:
            return VK_COMPARE_OP_GREATER_OR_EQUAL;
        case wgpu::CompareFunction::Equal:
            return VK_COMPARE_OP_EQUAL;
        case wgpu::CompareFunction::NotEqual:
            return VK_COMPARE_OP_NOT_EQUAL;
        case wgpu::CompareFunction::Always:
            return VK_COMPARE_OP_ALWAYS;

        case wgpu::CompareFunction::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkFilter ToVulkanSamplerFilter(wgpu::FilterMode filter) {
    switch (filter) {
        case wgpu::FilterMode::Linear:
            return VK_FILTER_LINEAR;
        case wgpu::FilterMode::Nearest:
            return VK_FILTER_NEAREST;
        case wgpu::FilterMode::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

// Convert Dawn texture aspects to  Vulkan texture aspect flags
VkImageAspectFlags VulkanAspectMask(const Aspect& aspects) {
    VkImageAspectFlags flags = 0;
    for (Aspect aspect : IterateEnumMask(aspects)) {
        switch (aspect) {
            case Aspect::Color:
                flags |= VK_IMAGE_ASPECT_COLOR_BIT;
                break;
            case Aspect::Depth:
                flags |= VK_IMAGE_ASPECT_DEPTH_BIT;
                break;
            case Aspect::Stencil:
                flags |= VK_IMAGE_ASPECT_STENCIL_BIT;
                break;

            case Aspect::CombinedDepthStencil:
                flags |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
                break;

            case Aspect::Plane0:
                flags |= VK_IMAGE_ASPECT_PLANE_0_BIT;
                break;
            case Aspect::Plane1:
                flags |= VK_IMAGE_ASPECT_PLANE_1_BIT;
                break;
            case Aspect::Plane2:
                flags |= VK_IMAGE_ASPECT_PLANE_2_BIT;
                break;

            case Aspect::None:
                DAWN_UNREACHABLE();
        }
    }
    return flags;
}

VkShaderStageFlags VulkanShaderStages(wgpu::ShaderStage stages) {
    VkShaderStageFlags flags = 0;

    if (stages & wgpu::ShaderStage::Vertex) {
        flags |= VK_SHADER_STAGE_VERTEX_BIT;
    }
    if (stages & wgpu::ShaderStage::Fragment) {
        flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
    }
    if (stages & wgpu::ShaderStage::Compute) {
        flags |= VK_SHADER_STAGE_COMPUTE_BIT;
    }

    return flags;
}

VkShaderStageFlagBits VulkanShaderStage(SingleShaderStage stage) {
    return static_cast<VkShaderStageFlagBits>(VulkanShaderStages(StageBit(stage)));
}

VkAttachmentLoadOp VulkanAttachmentLoadOp(wgpu::LoadOp op) {
    switch (op) {
        case wgpu::LoadOp::Load:
            return VK_ATTACHMENT_LOAD_OP_LOAD;
        case wgpu::LoadOp::Clear:
            return VK_ATTACHMENT_LOAD_OP_CLEAR;
        case wgpu::LoadOp::ExpandResolveTexture:
            return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
        case wgpu::LoadOp::Undefined:
            DAWN_UNREACHABLE();
            return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    }
    DAWN_UNREACHABLE();
}

VkAttachmentStoreOp VulkanAttachmentStoreOp(wgpu::StoreOp op) {
    // TODO(crbug.com/dawn/485): return STORE_OP_STORE_NONE_QCOM if the device has required
    // extension.
    switch (op) {
        case wgpu::StoreOp::Store:
            return VK_ATTACHMENT_STORE_OP_STORE;
        case wgpu::StoreOp::Discard:
            return VK_ATTACHMENT_STORE_OP_DONT_CARE;
        case wgpu::StoreOp::Undefined:
            DAWN_UNREACHABLE();
            return VK_ATTACHMENT_STORE_OP_DONT_CARE;
    }
    DAWN_UNREACHABLE();
}

// Vulkan SPEC requires the source/destination region specified by each element of
// pRegions must be a region that is contained within srcImage/dstImage. Here the size of
// the image refers to the virtual size, while Dawn validates texture copy extent with the
// physical size, so we need to re-calculate the texture copy extent to ensure it should fit
// in the virtual size of the subresource.
TexelExtent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy,
                                       const TexelExtent3D& copySize) {
    TexelExtent3D validTextureCopyExtent = copySize;
    const TextureBase* texture = textureCopy.texture.Get();
    TexelExtent3D virtualSizeAtLevel =
        texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel, textureCopy.aspect);
    DAWN_ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
    DAWN_ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
    if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
        DAWN_ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
    }
    if (copySize.height > virtualSizeAtLevel.height - textureCopy.origin.y) {
        DAWN_ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
    }

    return validTextureCopyExtent;
}

VkBufferImageCopy ComputeBufferImageCopyRegion(const TexelCopyBufferLayout& dataLayout,
                                               const TextureCopy& textureCopy,
                                               const BlockExtent3D& copySize) {
    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);

    BufferCopy bufferCopy;
    bufferCopy.offset = dataLayout.offset;
    bufferCopy.rowsPerImage = BlockCount{dataLayout.rowsPerImage};
    bufferCopy.blocksPerRow = blockInfo.BytesToBlocks(dataLayout.bytesPerRow);

    return ComputeBufferImageCopyRegion(bufferCopy, textureCopy, copySize);
}

VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
                                               const TextureCopy& textureCopy,
                                               const BlockExtent3D& copySize) {
    VkBufferImageCopy region;

    region.bufferOffset = bufferCopy.offset;
    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);
    TexelExtent3D copySizeTexels = blockInfo.ToTexel(copySize);

    // In Vulkan the row length is in texels while it is in blocks for Dawn
    region.bufferRowLength =
        dchecked_cast<uint32_t>(blockInfo.ToTexelWidth(bufferCopy.blocksPerRow));
    region.bufferImageHeight =
        dchecked_cast<uint32_t>(blockInfo.ToTexelHeight(bufferCopy.rowsPerImage));

    region.imageSubresource.aspectMask = VulkanAspectMask(textureCopy.aspect);
    region.imageSubresource.mipLevel = textureCopy.mipLevel;

    switch (textureCopy.texture->GetDimension()) {
        case wgpu::TextureDimension::Undefined:
            DAWN_UNREACHABLE();
        case wgpu::TextureDimension::e1D:
            DAWN_ASSERT(textureCopy.origin.z == TexelCount{0u} &&
                        copySizeTexels.depthOrArrayLayers == TexelCount{1u});
            region.imageOffset.x = dchecked_cast<int32_t>(textureCopy.origin.x);
            region.imageOffset.y = 0;
            region.imageOffset.z = 0;
            region.imageSubresource.baseArrayLayer = 0;
            region.imageSubresource.layerCount = 1;

            DAWN_ASSERT(!textureCopy.texture->GetFormat().isCompressed);
            region.imageExtent.width = dchecked_cast<uint32_t>(copySizeTexels.width);
            region.imageExtent.height = 1;
            region.imageExtent.depth = 1;
            break;

        case wgpu::TextureDimension::e2D: {
            region.imageOffset.x = dchecked_cast<int32_t>(textureCopy.origin.x);
            region.imageOffset.y = dchecked_cast<int32_t>(textureCopy.origin.y);
            region.imageOffset.z = 0;
            region.imageSubresource.baseArrayLayer = dchecked_cast<uint32_t>(textureCopy.origin.z);
            region.imageSubresource.layerCount =
                dchecked_cast<uint32_t>(copySizeTexels.depthOrArrayLayers);

            TexelExtent3D imageExtent =
                ComputeTextureCopyExtent(textureCopy, copySizeTexels.ToExtent3D());
            region.imageExtent.width = dchecked_cast<uint32_t>(imageExtent.width);
            region.imageExtent.height = dchecked_cast<uint32_t>(imageExtent.height);
            region.imageExtent.depth = 1;
            break;
        }

        case wgpu::TextureDimension::e3D: {
            region.imageOffset.x = dchecked_cast<int32_t>(textureCopy.origin.x);
            region.imageOffset.y = dchecked_cast<int32_t>(textureCopy.origin.y);
            region.imageOffset.z = dchecked_cast<int32_t>(textureCopy.origin.z);
            region.imageSubresource.baseArrayLayer = 0;
            region.imageSubresource.layerCount = 1;

            TexelExtent3D imageExtent =
                ComputeTextureCopyExtent(textureCopy, copySizeTexels.ToExtent3D());
            region.imageExtent.width = dchecked_cast<uint32_t>(imageExtent.width);
            region.imageExtent.height = dchecked_cast<uint32_t>(imageExtent.height);
            region.imageExtent.depth = dchecked_cast<uint32_t>(copySizeTexels.depthOrArrayLayers);
            break;
        }
    }

    return region;
}

void SetDebugNameInternal(Device* device,
                          VkObjectType objectType,
                          uint64_t objectHandle,
                          const char* prefix,
                          std::string_view label) {
    if (!device->IsToggleEnabled(Toggle::UseUserDefinedLabelsInBackend)) {
        return;
    }

    if (!objectHandle || !device->GetVkDevice()) {
        return;
    }

    if (device->GetGlobalInfo().HasExt(InstanceExt::DebugUtils)) {
        VkDebugUtilsObjectNameInfoEXT objectNameInfo;
        objectNameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
        objectNameInfo.pNext = nullptr;
        objectNameInfo.objectType = objectType;
        objectNameInfo.objectHandle = objectHandle;

        std::ostringstream objectNameStream;
        // Prefix with the device's message ID so that if this label appears in a validation
        // message it can be parsed out and the message can be associated with the right device.
        objectNameStream << device->GetDebugPrefix() << kDeviceDebugSeparator << prefix;
        if (!label.empty()) {
            objectNameStream << "_" << label;
        }

        std::string objectName = objectNameStream.str();
        objectNameInfo.pObjectName = objectName.c_str();
        device->fn.SetDebugUtilsObjectNameEXT(device->GetVkDevice(), &objectNameInfo);
    }
}

std::string GetNextDeviceDebugPrefix() {
    static uint64_t nextDeviceDebugId = 1;
    std::ostringstream objectName;
    objectName << kDeviceDebugPrefix << nextDeviceDebugId++;
    return objectName.str();
}

std::string GetDeviceDebugPrefixFromDebugName(const char* cDebugName) {
    if (cDebugName == nullptr) {
        return {};
    }

    std::string_view debugName = cDebugName;

    if (debugName.starts_with(kDeviceDebugPrefix)) {
        return {};
    }

    size_t separatorIndex = debugName.find(kDeviceDebugSeparator);
    if (separatorIndex == std::string_view::npos) {
        return {};
    }

    return std::string(debugName.substr(0u, separatorIndex));
}

std::string FormatAPIVersion(uint32_t version) {
    std::ostringstream versionString;
    versionString << VK_API_VERSION_MAJOR(version) << "." << VK_API_VERSION_MINOR(version) << "."
                  << VK_API_VERSION_PATCH(version);
    return versionString.str();
}

std::vector<VkDrmFormatModifierPropertiesEXT> GetFormatModifierProps(
    const VulkanFunctions& fn,
    VkPhysicalDevice vkPhysicalDevice,
    VkFormat format) {
    VkFormatProperties2 formatProps = {};
    formatProps.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
    PNextChainBuilder formatPropsChain(&formatProps);

    // Obtain the list of Linux DRM format modifiers compatible with a VkFormat
    VkDrmFormatModifierPropertiesListEXT formatModifierPropsList = {};
    formatModifierPropsList.drmFormatModifierCount = 0;
    formatModifierPropsList.pDrmFormatModifierProperties = nullptr;
    formatPropsChain.Add(&formatModifierPropsList,
                         VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT);

    fn.GetPhysicalDeviceFormatProperties2(vkPhysicalDevice, format, &formatProps);

    const uint32_t modifierCount = formatModifierPropsList.drmFormatModifierCount;

    std::vector<VkDrmFormatModifierPropertiesEXT> formatModifierPropsVector;
    formatModifierPropsVector.resize(modifierCount);
    formatModifierPropsList.pDrmFormatModifierProperties = formatModifierPropsVector.data();

    fn.GetPhysicalDeviceFormatProperties2(vkPhysicalDevice, format, &formatProps);
    return formatModifierPropsVector;
}

ResultOrError<VkDrmFormatModifierPropertiesEXT> GetFormatModifierProps(
    const VulkanFunctions& fn,
    VkPhysicalDevice vkPhysicalDevice,
    VkFormat format,
    uint64_t modifier) {
    std::vector<VkDrmFormatModifierPropertiesEXT> formatModifierPropsVector =
        GetFormatModifierProps(fn, vkPhysicalDevice, format);

    // Find the modifier props that match the modifier, and return them.
    for (const auto& props : formatModifierPropsVector) {
        if (props.drmFormatModifier == modifier) {
            return VkDrmFormatModifierPropertiesEXT{props};
        }
    }
    return DAWN_VALIDATION_ERROR("DRM format modifier %u not supported.", modifier);
}

ResultOrError<VkSamplerYcbcrConversion> CreateSamplerYCbCrConversion(
    const Device* device,
    const YCbCrVkDescriptor& yCbCrDescriptor) {
    uint64_t externalFormat = yCbCrDescriptor.externalFormat;
    VkFormat vulkanFormat = static_cast<VkFormat>(yCbCrDescriptor.vkFormat);
    DAWN_ASSERT(externalFormat != 0 || vulkanFormat != VK_FORMAT_UNDEFINED);

    VkComponentMapping vulkanComponent;
    vulkanComponent.r = static_cast<VkComponentSwizzle>(yCbCrDescriptor.vkComponentSwizzleRed);
    vulkanComponent.g = static_cast<VkComponentSwizzle>(yCbCrDescriptor.vkComponentSwizzleGreen);
    vulkanComponent.b = static_cast<VkComponentSwizzle>(yCbCrDescriptor.vkComponentSwizzleBlue);
    vulkanComponent.a = static_cast<VkComponentSwizzle>(yCbCrDescriptor.vkComponentSwizzleAlpha);

    VkSamplerYcbcrConversionCreateInfo vulkanYCbCrCreateInfo;
    vulkanYCbCrCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
    vulkanYCbCrCreateInfo.pNext = nullptr;
    vulkanYCbCrCreateInfo.format = vulkanFormat;
    vulkanYCbCrCreateInfo.ycbcrModel =
        static_cast<VkSamplerYcbcrModelConversion>(yCbCrDescriptor.vkYCbCrModel);
    vulkanYCbCrCreateInfo.ycbcrRange =
        static_cast<VkSamplerYcbcrRange>(yCbCrDescriptor.vkYCbCrRange);
    vulkanYCbCrCreateInfo.components = vulkanComponent;
    vulkanYCbCrCreateInfo.xChromaOffset =
        static_cast<VkChromaLocation>(yCbCrDescriptor.vkXChromaOffset);
    vulkanYCbCrCreateInfo.yChromaOffset =
        static_cast<VkChromaLocation>(yCbCrDescriptor.vkYChromaOffset);
    vulkanYCbCrCreateInfo.chromaFilter = ToVulkanSamplerFilter(yCbCrDescriptor.vkChromaFilter);
    vulkanYCbCrCreateInfo.forceExplicitReconstruction =
        static_cast<VkBool32>(yCbCrDescriptor.forceExplicitReconstruction);

    // VUID-VkSamplerYcbcrConversionCreateInfo-chromaFilter-01657
    // Adjust linear filter to nearest if the format doesn't support linear. This is to support
    // samplers created with YCrCb conversion info directly, which can't easily validate against the
    // driver information at creation time.
    if (vulkanFormat != VK_FORMAT_UNDEFINED &&
        vulkanYCbCrCreateInfo.chromaFilter == VK_FILTER_LINEAR) {
        VkPhysicalDevice vkPhysicalDevice =
            ToBackend(device->GetPhysicalDevice())->GetVkPhysicalDevice();
        VkFormatProperties formatProperties;
        device->fn.GetPhysicalDeviceFormatProperties(vkPhysicalDevice, vulkanFormat,
                                                     &formatProperties);
        bool supportsLinear = IsSubset(
            VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
            formatProperties.optimalTilingFeatures | formatProperties.linearTilingFeatures);
        if (!supportsLinear) {
            vulkanYCbCrCreateInfo.chromaFilter = VK_FILTER_NEAREST;
        }
    }

#if DAWN_PLATFORM_IS(ANDROID)
    VkExternalFormatANDROID vulkanExternalFormat;
    // Chain VkExternalFormatANDROID only if needed.
    if (externalFormat != 0) {
        vulkanExternalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
        vulkanExternalFormat.pNext = nullptr;
        vulkanExternalFormat.externalFormat = externalFormat;

        vulkanYCbCrCreateInfo.pNext = &vulkanExternalFormat;
    }
#endif  // DAWN_PLATFORM_IS(ANDROID)

    VkSamplerYcbcrConversion samplerYCbCrConversion = VK_NULL_HANDLE;
    DAWN_TRY(CheckVkSuccess(
        device->fn.CreateSamplerYcbcrConversion(device->GetVkDevice(), &vulkanYCbCrCreateInfo,
                                                nullptr, &*samplerYCbCrConversion),
        "CreateSamplerYcbcrConversion"));

    return samplerYCbCrConversion;
}

}  // namespace dawn::native::vulkan
