// Copyright 2020 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/VulkanExtensions.h"

#include "common/Assert.h"
#include "common/vulkan_platform.h"

#include <array>
#include <limits>

namespace dawn_native { namespace vulkan {

    static constexpr uint32_t VulkanVersion_1_1 = VK_MAKE_VERSION(1, 1, 0);
    static constexpr uint32_t VulkanVersion_1_2 = VK_MAKE_VERSION(1, 2, 0);
    static constexpr uint32_t NeverPromoted = std::numeric_limits<uint32_t>::max();

    // A static array for InstanceExtInfo that can be indexed with InstanceExts.
    // GetInstanceExtInfo checks that "index" matches the index used to access this array so an
    // assert will fire if it isn't in the correct order.
    static constexpr size_t kInstanceExtCount = static_cast<size_t>(InstanceExt::EnumCount);
    static constexpr std::array<InstanceExtInfo, kInstanceExtCount> sInstanceExtInfos{{
        //
        {InstanceExt::GetPhysicalDeviceProperties2, "VK_KHR_get_physical_device_properties2",
         VulkanVersion_1_1},
        {InstanceExt::ExternalMemoryCapabilities, "VK_KHR_external_memory_capabilities",
         VulkanVersion_1_1},
        {InstanceExt::ExternalSemaphoreCapabilities, "VK_KHR_external_semaphore_capabilities",
         VulkanVersion_1_1},

        {InstanceExt::Surface, "VK_KHR_surface", NeverPromoted},
        {InstanceExt::FuchsiaImagePipeSurface, "VK_FUCHSIA_imagepipe_surface", NeverPromoted},
        {InstanceExt::MetalSurface, "VK_EXT_metal_surface", NeverPromoted},
        {InstanceExt::WaylandSurface, "VK_KHR_wayland_surface", NeverPromoted},
        {InstanceExt::Win32Surface, "VK_KHR_win32_surface", NeverPromoted},
        {InstanceExt::XcbSurface, "VK_KHR_xcb_surface", NeverPromoted},
        {InstanceExt::XlibSurface, "VK_KHR_xlib_surface", NeverPromoted},

        {InstanceExt::DebugUtils, "VK_EXT_debug_utils", NeverPromoted},
        //
    }};

    const InstanceExtInfo& GetInstanceExtInfo(InstanceExt ext) {
        uint32_t index = static_cast<uint32_t>(ext);
        ASSERT(index < sInstanceExtInfos.size());
        ASSERT(sInstanceExtInfos[index].index == ext);
        return sInstanceExtInfos[index];
    }

    std::unordered_map<std::string, InstanceExt> CreateInstanceExtNameMap() {
        std::unordered_map<std::string, InstanceExt> result;
        for (const InstanceExtInfo& info : sInstanceExtInfos) {
            result[info.name] = info.index;
        }
        return result;
    }

    InstanceExtSet EnsureDependencies(const InstanceExtSet& advertisedExts) {
        // We need to check that all transitive dependencies of extensions are advertised.
        // To do that in a single pass and no data structures, the extensions are topologically
        // sorted in the definition of InstanceExt.
        // To ensure the order is correct, we mark visited extensions in `visitedSet` and each
        // dependency check will first assert all its dependents have been visited.
        InstanceExtSet visitedSet;
        InstanceExtSet trimmedSet;

        auto HasDep = [&](InstanceExt ext) -> bool {
            ASSERT(visitedSet[ext]);
            return trimmedSet[ext];
        };

        for (uint32_t i = 0; i < sInstanceExtInfos.size(); i++) {
            InstanceExt ext = static_cast<InstanceExt>(i);

            bool hasDependencies = false;
            switch (ext) {
                case InstanceExt::GetPhysicalDeviceProperties2:
                case InstanceExt::Surface:
                case InstanceExt::DebugUtils:
                    hasDependencies = true;
                    break;

                case InstanceExt::ExternalMemoryCapabilities:
                case InstanceExt::ExternalSemaphoreCapabilities:
                    hasDependencies = HasDep(InstanceExt::GetPhysicalDeviceProperties2);
                    break;

                case InstanceExt::FuchsiaImagePipeSurface:
                case InstanceExt::MetalSurface:
                case InstanceExt::WaylandSurface:
                case InstanceExt::Win32Surface:
                case InstanceExt::XcbSurface:
                case InstanceExt::XlibSurface:
                    hasDependencies = HasDep(InstanceExt::Surface);
                    break;

                case InstanceExt::EnumCount:
                    UNREACHABLE();
            }

            trimmedSet.set(ext, hasDependencies && advertisedExts[ext]);
            visitedSet.set(ext, true);
        }

        return trimmedSet;
    }

    void MarkPromotedExtensions(InstanceExtSet* extensions, uint32_t version) {
        for (const InstanceExtInfo& info : sInstanceExtInfos) {
            if (info.versionPromoted <= version) {
                extensions->set(info.index, true);
            }
        }
    }

    static constexpr size_t kDeviceExtCount = static_cast<size_t>(DeviceExt::EnumCount);
    static constexpr std::array<DeviceExtInfo, kDeviceExtCount> sDeviceExtInfos{{
        //
        {DeviceExt::BindMemory2, "VK_KHR_bind_memory2", VulkanVersion_1_1},
        {DeviceExt::Maintenance1, "VK_KHR_maintenance1", VulkanVersion_1_1},
        {DeviceExt::StorageBufferStorageClass, "VK_KHR_storage_buffer_storage_class",
         VulkanVersion_1_1},
        {DeviceExt::GetPhysicalDeviceProperties2, "VK_KHR_get_physical_device_properties2",
         VulkanVersion_1_1},
        {DeviceExt::GetMemoryRequirements2, "VK_KHR_get_memory_requirements2", VulkanVersion_1_1},
        {DeviceExt::ExternalMemoryCapabilities, "VK_KHR_external_memory_capabilities",
         VulkanVersion_1_1},
        {DeviceExt::ExternalSemaphoreCapabilities, "VK_KHR_external_semaphore_capabilities",
         VulkanVersion_1_1},
        {DeviceExt::ExternalMemory, "VK_KHR_external_memory", VulkanVersion_1_1},
        {DeviceExt::ExternalSemaphore, "VK_KHR_external_semaphore", VulkanVersion_1_1},
        {DeviceExt::_16BitStorage, "VK_KHR_16bit_storage", VulkanVersion_1_1},
        {DeviceExt::SamplerYCbCrConversion, "VK_KHR_sampler_ycbcr_conversion", VulkanVersion_1_1},

        {DeviceExt::DriverProperties, "VK_KHR_driver_properties", VulkanVersion_1_2},
        {DeviceExt::ImageFormatList, "VK_KHR_image_format_list", VulkanVersion_1_2},
        {DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8", VulkanVersion_1_2},

        {DeviceExt::ExternalMemoryFD, "VK_KHR_external_memory_fd", NeverPromoted},
        {DeviceExt::ExternalMemoryDmaBuf, "VK_EXT_external_memory_dma_buf", NeverPromoted},
        {DeviceExt::ExternalMemoryZirconHandle, "VK_FUCHSIA_external_memory", NeverPromoted},
        {DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd", NeverPromoted},
        {DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore", NeverPromoted},

        {DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier", NeverPromoted},
        {DeviceExt::Swapchain, "VK_KHR_swapchain", NeverPromoted},
        {DeviceExt::SubgroupSizeControl, "VK_EXT_subgroup_size_control", NeverPromoted},
        //
    }};

    const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext) {
        uint32_t index = static_cast<uint32_t>(ext);
        ASSERT(index < sDeviceExtInfos.size());
        ASSERT(sDeviceExtInfos[index].index == ext);
        return sDeviceExtInfos[index];
    }

    std::unordered_map<std::string, DeviceExt> CreateDeviceExtNameMap() {
        std::unordered_map<std::string, DeviceExt> result;
        for (const DeviceExtInfo& info : sDeviceExtInfos) {
            result[info.name] = info.index;
        }
        return result;
    }

    DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
                                    const InstanceExtSet& instanceExts,
                                    uint32_t icdVersion) {
        // This is very similar to EnsureDependencies for instanceExtSet. See comment there for
        // an explanation of what happens.
        DeviceExtSet visitedSet;
        DeviceExtSet trimmedSet;

        auto HasDep = [&](DeviceExt ext) -> bool {
            ASSERT(visitedSet[ext]);
            return trimmedSet[ext];
        };

        for (uint32_t i = 0; i < sDeviceExtInfos.size(); i++) {
            DeviceExt ext = static_cast<DeviceExt>(i);

            bool hasDependencies = false;
            switch (ext) {
                // Happy extensions don't need anybody else!
                case DeviceExt::BindMemory2:
                case DeviceExt::GetMemoryRequirements2:
                case DeviceExt::Maintenance1:
                case DeviceExt::ImageFormatList:
                case DeviceExt::StorageBufferStorageClass:
                    hasDependencies = true;
                    break;

                // Physical device extensions technically don't require the instance to support
                // them but VulkanFunctions only loads the function pointers if the instance
                // advertises the extension. So if we didn't have this check, we'd risk a calling
                // a nullptr.
                case DeviceExt::GetPhysicalDeviceProperties2:
                    hasDependencies = instanceExts[InstanceExt::GetPhysicalDeviceProperties2];
                    break;
                case DeviceExt::ExternalMemoryCapabilities:
                    hasDependencies = instanceExts[InstanceExt::ExternalMemoryCapabilities] &&
                                      HasDep(DeviceExt::GetPhysicalDeviceProperties2);
                    break;
                case DeviceExt::ExternalSemaphoreCapabilities:
                    hasDependencies = instanceExts[InstanceExt::ExternalSemaphoreCapabilities] &&
                                      HasDep(DeviceExt::GetPhysicalDeviceProperties2);
                    break;

                case DeviceExt::ImageDrmFormatModifier:
                    hasDependencies = HasDep(DeviceExt::BindMemory2) &&
                                      HasDep(DeviceExt::GetPhysicalDeviceProperties2) &&
                                      HasDep(DeviceExt::ImageFormatList) &&
                                      HasDep(DeviceExt::SamplerYCbCrConversion);
                    break;

                case DeviceExt::Swapchain:
                    hasDependencies = instanceExts[InstanceExt::Surface];
                    break;

                case DeviceExt::SamplerYCbCrConversion:
                    hasDependencies = HasDep(DeviceExt::Maintenance1) &&
                                      HasDep(DeviceExt::BindMemory2) &&
                                      HasDep(DeviceExt::GetMemoryRequirements2) &&
                                      HasDep(DeviceExt::GetPhysicalDeviceProperties2);
                    break;

                case DeviceExt::DriverProperties:
                case DeviceExt::ShaderFloat16Int8:
                    hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2);
                    break;

                case DeviceExt::ExternalMemory:
                    hasDependencies = HasDep(DeviceExt::ExternalMemoryCapabilities);
                    break;

                case DeviceExt::ExternalSemaphore:
                    hasDependencies = HasDep(DeviceExt::ExternalSemaphoreCapabilities);
                    break;

                case DeviceExt::ExternalMemoryFD:
                case DeviceExt::ExternalMemoryZirconHandle:
                    hasDependencies = HasDep(DeviceExt::ExternalMemory);
                    break;

                case DeviceExt::ExternalMemoryDmaBuf:
                    hasDependencies = HasDep(DeviceExt::ExternalMemoryFD);
                    break;

                case DeviceExt::ExternalSemaphoreFD:
                case DeviceExt::ExternalSemaphoreZirconHandle:
                    hasDependencies = HasDep(DeviceExt::ExternalSemaphore);
                    break;

                case DeviceExt::_16BitStorage:
                    hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2) &&
                                      HasDep(DeviceExt::StorageBufferStorageClass);
                    break;

                case DeviceExt::SubgroupSizeControl:
                    // Using the extension requires DeviceExt::GetPhysicalDeviceProperties2, but we
                    // don't need to check for it as it also requires Vulkan 1.1 in which
                    // VK_KHR_get_physical_device_properties2 was promoted.
                    hasDependencies = icdVersion >= VulkanVersion_1_1;
                    break;

                case DeviceExt::EnumCount:
                    UNREACHABLE();
            }

            trimmedSet.set(ext, hasDependencies && advertisedExts[ext]);
            visitedSet.set(ext, true);
        }

        return trimmedSet;
    }

    void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version) {
        for (const DeviceExtInfo& info : sDeviceExtInfos) {
            if (info.versionPromoted <= version) {
                extensions->set(info.index, true);
            }
        }
    }

}}  // namespace dawn_native::vulkan
