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

#include <array>
#include <limits>

#include "src/dawn/common/vulkan_platform.h"
#include "src/utils/assert.h"

namespace dawn::native::vulkan {

// 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{{
    // Not promoted to core in any version
    {InstanceExt::Surface, "VK_KHR_surface"},
    {InstanceExt::FuchsiaImagePipeSurface, "VK_FUCHSIA_imagepipe_surface"},
    {InstanceExt::MetalSurface, "VK_EXT_metal_surface"},
    {InstanceExt::WaylandSurface, "VK_KHR_wayland_surface"},
    {InstanceExt::Win32Surface, "VK_KHR_win32_surface"},
    {InstanceExt::XcbSurface, "VK_KHR_xcb_surface"},
    {InstanceExt::XlibSurface, "VK_KHR_xlib_surface"},
    {InstanceExt::AndroidSurface, "VK_KHR_android_surface"},

    {InstanceExt::DebugUtils, "VK_EXT_debug_utils"},
    {InstanceExt::ValidationFeatures, "VK_EXT_validation_features"},
    //
}};

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

absl::flat_hash_map<std::string, InstanceExt> CreateInstanceExtNameMap() {
    absl::flat_hash_map<std::string, InstanceExt> result;
    for (const InstanceExtInfo& info : sInstanceExtInfos) {
        result.emplace(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 {
        DAWN_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::Surface:
            case InstanceExt::DebugUtils:
            case InstanceExt::ValidationFeatures:
                hasDependencies = true;
                break;

            case InstanceExt::AndroidSurface:
            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:
                DAWN_UNREACHABLE();
        }

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

    return trimmedSet;
}

static constexpr size_t kDeviceExtCount = static_cast<size_t>(DeviceExt::EnumCount);
static constexpr std::array<DeviceExtInfo, kDeviceExtCount> sDeviceExtInfos{{
    // Promoted in 1.2
    {DeviceExt::DriverProperties, "VK_KHR_driver_properties"},
    {DeviceExt::ImageFormatList, "VK_KHR_image_format_list"},
    {DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8"},
    {DeviceExt::ShaderSubgroupExtendedTypes, "VK_KHR_shader_subgroup_extended_types"},
    {DeviceExt::ShaderBufferInt64Atomics, "VK_KHR_shader_atomic_int64"},
    {DeviceExt::DrawIndirectCount, "VK_KHR_draw_indirect_count"},
    {DeviceExt::VulkanMemoryModel, "VK_KHR_vulkan_memory_model"},
    {DeviceExt::ShaderFloatControls, "VK_KHR_shader_float_controls"},
    {DeviceExt::Spirv14, "VK_KHR_spirv_1_4"},
    {DeviceExt::DescriptorIndexing, "VK_EXT_descriptor_indexing"},
    {DeviceExt::CreateRenderPass2, "VK_KHR_create_renderpass2"},
    {DeviceExt::DepthStencilResolve, "VK_KHR_depth_stencil_resolve"},

    // Promoted in 1.3
    {DeviceExt::ShaderIntegerDotProduct, "VK_KHR_shader_integer_dot_product"},
    {DeviceExt::ZeroInitializeWorkgroupMemory, "VK_KHR_zero_initialize_workgroup_memory"},
    {DeviceExt::DemoteToHelperInvocation, "VK_EXT_shader_demote_to_helper_invocation"},
    {DeviceExt::Maintenance4, "VK_KHR_maintenance4"},
    {DeviceExt::SubgroupSizeControl, "VK_EXT_subgroup_size_control"},
    {DeviceExt::DynamicRendering, "VK_KHR_dynamic_rendering"},
    {DeviceExt::ExtendedDynamicState, "VK_EXT_extended_dynamic_state"},

    // Promoted in 1.4
    {DeviceExt::PipelineRobustness, "VK_EXT_pipeline_robustness"},
    {DeviceExt::Maintenance5, "VK_KHR_maintenance5"},
    {DeviceExt::LoadStoreOpNone, "VK_KHR_load_store_op_none"},

    // Not promoted to core in any version
    {DeviceExt::Maintenance9, "VK_KHR_maintenance9"},
    {DeviceExt::DepthClipEnable, "VK_EXT_depth_clip_enable"},
    {DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier"},
    {DeviceExt::Swapchain, "VK_KHR_swapchain"},
    {DeviceExt::SwapchainMutableFormat, "VK_KHR_swapchain_mutable_format"},
    {DeviceExt::QueueFamilyForeign, "VK_EXT_queue_family_foreign"},
    {DeviceExt::Robustness2, "VK_EXT_robustness2"},
    {DeviceExt::DisplayTiming, "VK_GOOGLE_display_timing"},
    {DeviceExt::CooperativeMatrix, "VK_KHR_cooperative_matrix"},
    {DeviceExt::MultisampledRenderToSingleSampled, "VK_EXT_multisampled_render_to_single_sampled"},
    {DeviceExt::PhysicalDeviceDrm, "VK_EXT_physical_device_drm"},
    {DeviceExt::RasterizationOrderAttachmentAccess, "VK_EXT_rasterization_order_attachment_access"},
    {DeviceExt::MaximalReconvergence, "VK_KHR_shader_maximal_reconvergence"},
    {DeviceExt::SubgroupUniformControlFlow, "VK_KHR_shader_subgroup_uniform_control_flow"},
    {DeviceExt::LoadStoreOpNoneEXT, "VK_EXT_load_store_op_none"},
    {DeviceExt::RenderPassStoreOpsQCOM, "VK_QCOM_render_pass_store_ops"},

    {DeviceExt::ExternalMemoryAndroidHardwareBuffer,
     "VK_ANDROID_external_memory_android_hardware_buffer"},
    {DeviceExt::ExternalMemoryFD, "VK_KHR_external_memory_fd"},
    {DeviceExt::ExternalMemoryDmaBuf, "VK_EXT_external_memory_dma_buf"},
    {DeviceExt::ExternalMemoryZirconHandle, "VK_FUCHSIA_external_memory"},
    {DeviceExt::ExternalMemoryHost, "VK_EXT_external_memory_host"},
    {DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd"},
    {DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore"},
    //
}};

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

absl::flat_hash_map<std::string, DeviceExt> CreateDeviceExtNameMap() {
    absl::flat_hash_map<std::string, DeviceExt> result;
    for (const DeviceExtInfo& info : sDeviceExtInfos) {
        result.emplace(info.name, info.index);
    }
    return result;
}

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

    // Dawn requires at least Vulkan 1.1
    DAWN_ASSERT(version >= VK_API_VERSION_1_1);

    auto HasDep = [&](DeviceExt ext) -> bool {
        DAWN_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::ImageFormatList:
            case DeviceExt::DrawIndirectCount:
            case DeviceExt::LoadStoreOpNone:
            case DeviceExt::LoadStoreOpNoneEXT:
            case DeviceExt::RenderPassStoreOpsQCOM:
            // Extensions which only depend on Vulkan 1.1
            case DeviceExt::DriverProperties:
            case DeviceExt::ShaderFloat16Int8:
            case DeviceExt::DepthClipEnable:
            case DeviceExt::ShaderIntegerDotProduct:
            case DeviceExt::ZeroInitializeWorkgroupMemory:
            case DeviceExt::DemoteToHelperInvocation:
            case DeviceExt::Maintenance4:
            case DeviceExt::Maintenance9:
            case DeviceExt::PipelineRobustness:
            case DeviceExt::Robustness2:
            case DeviceExt::SubgroupSizeControl:
            case DeviceExt::ShaderSubgroupExtendedTypes:
            case DeviceExt::ShaderBufferInt64Atomics:
            case DeviceExt::VulkanMemoryModel:
            case DeviceExt::CooperativeMatrix:
            case DeviceExt::RasterizationOrderAttachmentAccess:
            case DeviceExt::ShaderFloatControls:
            case DeviceExt::DescriptorIndexing:
            case DeviceExt::CreateRenderPass2:
            case DeviceExt::ExternalMemoryFD:
            case DeviceExt::ExternalMemoryZirconHandle:
            case DeviceExt::ExternalMemoryHost:
            case DeviceExt::ExternalSemaphoreFD:
            case DeviceExt::ExternalSemaphoreZirconHandle:
            case DeviceExt::QueueFamilyForeign:
            case DeviceExt::PhysicalDeviceDrm:
            case DeviceExt::ExtendedDynamicState:
            case DeviceExt::MaximalReconvergence:
            case DeviceExt::SubgroupUniformControlFlow:
                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::ImageDrmFormatModifier:
                hasDependencies = HasDep(DeviceExt::ImageFormatList);
                break;

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

            // Also requires VK_KHR_maintenance2 which is core in Vulkan 1.1.
            case DeviceExt::SwapchainMutableFormat:
                hasDependencies =
                    HasDep(DeviceExt::Swapchain) && HasDep(DeviceExt::ImageFormatList);
                break;

            case DeviceExt::ExternalMemoryAndroidHardwareBuffer:
                hasDependencies = HasDep(DeviceExt::QueueFamilyForeign);
                break;

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

            case DeviceExt::DepthStencilResolve:
                hasDependencies = HasDep(DeviceExt::CreateRenderPass2);
                break;

            case DeviceExt::DisplayTiming:
                hasDependencies = HasDep(DeviceExt::Swapchain);
                break;

            case DeviceExt::MultisampledRenderToSingleSampled:
                hasDependencies =
                    HasDep(DeviceExt::CreateRenderPass2) && HasDep(DeviceExt::DepthStencilResolve);
                break;

            case DeviceExt::Spirv14:
                hasDependencies = HasDep(DeviceExt::ShaderFloatControls);
                break;

            case DeviceExt::DynamicRendering:
                hasDependencies = HasDep(DeviceExt::DepthStencilResolve);
                break;

            case DeviceExt::Maintenance5:
                hasDependencies = HasDep(DeviceExt::DynamicRendering);
                break;

            case DeviceExt::EnumCount:
                DAWN_UNREACHABLE();
        }

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

    return trimmedSet;
}

// A static array for VulkanLayerInfo that can be indexed with VulkanLayers.
// GetVulkanLayerInfo 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 kVulkanLayerCount = static_cast<size_t>(VulkanLayer::EnumCount);
static constexpr std::array<VulkanLayerInfo, kVulkanLayerCount> sVulkanLayerInfos{{
    //
    {VulkanLayer::Validation, "VK_LAYER_KHRONOS_validation"},
    {VulkanLayer::LunargVkTrace, "VK_LAYER_LUNARG_vktrace"},
    {VulkanLayer::RenderDocCapture, "VK_LAYER_RENDERDOC_Capture"},
    {VulkanLayer::FuchsiaImagePipeSwapchain, "VK_LAYER_FUCHSIA_imagepipe_swapchain"},
    //
}};

const VulkanLayerInfo& GetVulkanLayerInfo(VulkanLayer layer) {
    uint32_t index = static_cast<uint32_t>(layer);
    DAWN_ASSERT(index < sVulkanLayerInfos.size());
    DAWN_ASSERT(sVulkanLayerInfos[index].layer == layer);
    return sVulkanLayerInfos[index];
}

absl::flat_hash_map<std::string, VulkanLayer> CreateVulkanLayerNameMap() {
    absl::flat_hash_map<std::string, VulkanLayer> result;
    for (const VulkanLayerInfo& info : sVulkanLayerInfos) {
        result.emplace(info.name, info.layer);
    }
    return result;
}

}  // namespace dawn::native::vulkan
