// 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 "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 {

    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 SetDebugName(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
