// 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.

#ifndef SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_
#define SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_

#include <string>
#include <unordered_map>

#include "dawn/common/ityp_bitset.h"

namespace dawn::native::vulkan {

// The list of known instance extensions. They must be in dependency order (this is checked
// inside EnsureDependencies)
enum class InstanceExt {
    // Promoted to 1.1
    GetPhysicalDeviceProperties2,
    ExternalMemoryCapabilities,
    ExternalSemaphoreCapabilities,

    // Surface extensions
    Surface,
    FuchsiaImagePipeSurface,
    MetalSurface,
    WaylandSurface,
    Win32Surface,
    XcbSurface,
    XlibSurface,
    AndroidSurface,

    // Others
    DebugUtils,
    ValidationFeatures,

    EnumCount,
};

// A bitset that is indexed with InstanceExt.
using InstanceExtSet = ityp::bitset<InstanceExt, static_cast<uint32_t>(InstanceExt::EnumCount)>;

// Information about a known instance extension.
struct InstanceExtInfo {
    InstanceExt index;
    const char* name;
    // The version in which this extension was promoted as built with VK_API_VERSION_1_x,
    // or NeverPromoted if it was never promoted.
    uint32_t versionPromoted;
};

// Returns the information about a known InstanceExt
const InstanceExtInfo& GetInstanceExtInfo(InstanceExt ext);
// Returns a map that maps a Vulkan extension name to its InstanceExt.
std::unordered_map<std::string, InstanceExt> CreateInstanceExtNameMap();

// Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version`
void MarkPromotedExtensions(InstanceExtSet* extensions, uint32_t version);
// From a set of extensions advertised as supported by the instance (or promoted), remove all
// extensions that don't have all their transitive dependencies in advertisedExts.
InstanceExtSet EnsureDependencies(const InstanceExtSet& advertisedExts);

// The list of known device extensions. They must be in dependency order (this is checked
// inside EnsureDependencies)
enum class DeviceExt {
    // Promoted to 1.1
    BindMemory2,
    Maintenance1,
    Maintenance2,
    Maintenance3,
    StorageBufferStorageClass,
    GetPhysicalDeviceProperties2,
    GetMemoryRequirements2,
    DedicatedAllocation,
    ExternalMemoryCapabilities,
    ExternalSemaphoreCapabilities,
    ExternalMemory,
    ExternalSemaphore,
    _16BitStorage,
    SamplerYCbCrConversion,

    // Promoted to 1.2
    DriverProperties,
    ImageFormatList,
    ShaderFloat16Int8,

    // Promoted to 1.3
    ShaderIntegerDotProduct,
    ZeroInitializeWorkgroupMemory,
    Maintenance4,

    // Others
    DepthClipEnable,
    ImageDrmFormatModifier,
    Swapchain,
    SubgroupSizeControl,
    QueueFamilyForeign,
    Robustness2,

    // External* extensions
    ExternalMemoryAndroidHardwareBuffer,
    ExternalMemoryFD,
    ExternalMemoryDmaBuf,
    ExternalMemoryZirconHandle,
    ExternalSemaphoreFD,
    ExternalSemaphoreZirconHandle,

    EnumCount,
};

// A bitset that is indexed with DeviceExt.
using DeviceExtSet = ityp::bitset<DeviceExt, static_cast<uint32_t>(DeviceExt::EnumCount)>;

// Information about a known device extension.
struct DeviceExtInfo {
    DeviceExt index;
    const char* name;
    // The version in which this extension was promoted as built with VK_API_VERSION_1_x,
    // or NeverPromoted if it was never promoted.
    uint32_t versionPromoted;
};

// Returns the information about a known DeviceExt
const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext);
// Returns a map that maps a Vulkan extension name to its DeviceExt.
std::unordered_map<std::string, DeviceExt> CreateDeviceExtNameMap();

// Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version`
void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version);
// From a set of extensions advertised as supported by the device (or promoted), remove all
// extensions that don't have all their transitive dependencies in advertisedExts or in
// instanceExts.
DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
                                const InstanceExtSet& instanceExts,
                                uint32_t icdVersion);

// The list of all known Vulkan layers.
enum class VulkanLayer {
    Validation,
    LunargVkTrace,
    RenderDocCapture,

    // Fuchsia implements the swapchain through a layer (VK_LAYER_FUCHSIA_image_pipe_swapchain),
    // which adds an instance extensions (VK_FUCHSIA_image_surface) to all ICDs.
    FuchsiaImagePipeSwapchain,

    EnumCount,
};

// A bitset that is indexed with VulkanLayer.
using VulkanLayerSet = ityp::bitset<VulkanLayer, static_cast<uint32_t>(VulkanLayer::EnumCount)>;

// Information about a known layer
struct VulkanLayerInfo {
    VulkanLayer layer;
    const char* name;
};

// Returns the information about a known VulkanLayer
const VulkanLayerInfo& GetVulkanLayerInfo(VulkanLayer layer);
// Returns a map that maps a Vulkan layer name to its VulkanLayer.
std::unordered_map<std::string, VulkanLayer> CreateVulkanLayerNameMap();

}  // namespace dawn::native::vulkan

#endif  // SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_
