// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/vulkan/UtilsVulkan.h"

#include "dawn/common/Assert.h"
#include "dawn/native/EnumMaskIterator.h"
#include "dawn/native/Format.h"
#include "dawn/native/Pipeline.h"
#include "dawn/native/ShaderModule.h"
#include "dawn/native/vulkan/DeviceVk.h"
#include "dawn/native/vulkan/Forward.h"
#include "dawn/native/vulkan/TextureVk.h"
#include "dawn/native/vulkan/VulkanError.h"

namespace dawn::native::vulkan {

#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)

#undef VK_OBJECT_TYPE_GETTER

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;
    }
    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::None:
                UNREACHABLE();
        }
    }
    return flags;
}

// 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.
Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy, const Extent3D& copySize) {
    Extent3D validTextureCopyExtent = copySize;
    const TextureBase* texture = textureCopy.texture.Get();
    Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
    ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
    ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
    if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
        ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
    }
    if (copySize.height > virtualSizeAtLevel.height - textureCopy.origin.y) {
        ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
    }

    return validTextureCopyExtent;
}

VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
                                               const TextureCopy& textureCopy,
                                               const Extent3D& copySize) {
    TextureDataLayout passDataLayout;
    passDataLayout.offset = bufferCopy.offset;
    passDataLayout.rowsPerImage = bufferCopy.rowsPerImage;
    passDataLayout.bytesPerRow = bufferCopy.bytesPerRow;
    return ComputeBufferImageCopyRegion(passDataLayout, textureCopy, copySize);
}

VkBufferImageCopy ComputeBufferImageCopyRegion(const TextureDataLayout& dataLayout,
                                               const TextureCopy& textureCopy,
                                               const Extent3D& copySize) {
    const Texture* texture = ToBackend(textureCopy.texture.Get());

    VkBufferImageCopy region;

    region.bufferOffset = dataLayout.offset;
    // In Vulkan the row length is in texels while it is in bytes for Dawn
    const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(textureCopy.aspect).block;
    ASSERT(dataLayout.bytesPerRow % blockInfo.byteSize == 0);
    region.bufferRowLength = dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width;
    region.bufferImageHeight = dataLayout.rowsPerImage * blockInfo.height;

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

    switch (textureCopy.texture->GetDimension()) {
        case wgpu::TextureDimension::e1D:
            ASSERT(textureCopy.origin.z == 0 && copySize.depthOrArrayLayers == 1);
            region.imageOffset.x = textureCopy.origin.x;
            region.imageOffset.y = 0;
            region.imageOffset.z = 0;
            region.imageSubresource.baseArrayLayer = 0;
            region.imageSubresource.layerCount = 1;

            ASSERT(!textureCopy.texture->GetFormat().isCompressed);
            region.imageExtent.width = copySize.width;
            region.imageExtent.height = 1;
            region.imageExtent.depth = 1;
            break;

        case wgpu::TextureDimension::e2D: {
            region.imageOffset.x = textureCopy.origin.x;
            region.imageOffset.y = textureCopy.origin.y;
            region.imageOffset.z = 0;
            region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
            region.imageSubresource.layerCount = copySize.depthOrArrayLayers;

            Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
            region.imageExtent.width = imageExtent.width;
            region.imageExtent.height = imageExtent.height;
            region.imageExtent.depth = 1;
            break;
        }

        case wgpu::TextureDimension::e3D: {
            region.imageOffset.x = textureCopy.origin.x;
            region.imageOffset.y = textureCopy.origin.y;
            region.imageOffset.z = textureCopy.origin.z;
            region.imageSubresource.baseArrayLayer = 0;
            region.imageSubresource.layerCount = 1;

            ASSERT(!textureCopy.texture->GetFormat().isCompressed);
            region.imageExtent.width = copySize.width;
            region.imageExtent.height = copySize.height;
            region.imageExtent.depth = copySize.depthOrArrayLayers;
            break;
        }
    }

    return region;
}

void SetDebugNameInternal(Device* device,
                          VkObjectType objectType,
                          uint64_t objectHandle,
                          const char* prefix,
                          std::string label) {
    if (!objectHandle) {
        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;

        if (label.empty() || !device->IsToggleEnabled(Toggle::UseUserDefinedLabelsInBackend)) {
            objectNameInfo.pObjectName = prefix;
            device->fn.SetDebugUtilsObjectNameEXT(device->GetVkDevice(), &objectNameInfo);
            return;
        }

        std::string objectName = prefix;
        objectName += "_";
        objectName += label;
        objectNameInfo.pObjectName = objectName.c_str();
        device->fn.SetDebugUtilsObjectNameEXT(device->GetVkDevice(), &objectNameInfo);
    }
}

VkSpecializationInfo* GetVkSpecializationInfo(
    const ProgrammableStage& programmableStage,
    VkSpecializationInfo* specializationInfo,
    std::vector<OverridableConstantScalar>* specializationDataEntries,
    std::vector<VkSpecializationMapEntry>* specializationMapEntries) {
    ASSERT(specializationInfo);
    ASSERT(specializationDataEntries);
    ASSERT(specializationMapEntries);

    if (programmableStage.constants.size() == 0) {
        return nullptr;
    }

    const EntryPointMetadata& entryPointMetaData =
        programmableStage.module->GetEntryPoint(programmableStage.entryPoint);

    for (const auto& pipelineConstant : programmableStage.constants) {
        const std::string& identifier = pipelineConstant.first;
        double value = pipelineConstant.second;

        // This is already validated so `identifier` must exist
        const auto& moduleConstant = entryPointMetaData.overridableConstants.at(identifier);

        specializationMapEntries->push_back(
            VkSpecializationMapEntry{moduleConstant.id,
                                     static_cast<uint32_t>(specializationDataEntries->size() *
                                                           sizeof(OverridableConstantScalar)),
                                     sizeof(OverridableConstantScalar)});

        OverridableConstantScalar entry{};
        switch (moduleConstant.type) {
            case EntryPointMetadata::OverridableConstant::Type::Boolean:
                entry.b = static_cast<int32_t>(value);
                break;
            case EntryPointMetadata::OverridableConstant::Type::Float32:
                entry.f32 = static_cast<float>(value);
                break;
            case EntryPointMetadata::OverridableConstant::Type::Int32:
                entry.i32 = static_cast<int32_t>(value);
                break;
            case EntryPointMetadata::OverridableConstant::Type::Uint32:
                entry.u32 = static_cast<uint32_t>(value);
                break;
            default:
                UNREACHABLE();
        }
        specializationDataEntries->push_back(entry);
    }

    specializationInfo->mapEntryCount = static_cast<uint32_t>(specializationMapEntries->size());
    specializationInfo->pMapEntries = specializationMapEntries->data();
    specializationInfo->dataSize =
        specializationDataEntries->size() * sizeof(OverridableConstantScalar);
    specializationInfo->pData = specializationDataEntries->data();

    return specializationInfo;
}

}  // namespace dawn::native::vulkan
