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

#ifndef SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_
#define SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_

#include <string>

#include "absl/container/flat_hash_map.h"
#include "src/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 : uint32_t {
    // 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;
};

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

// 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). Remove extensions from this list once kRequiredVulkanVersion
// is updated to the version they were promoted in.
enum class DeviceExt : uint32_t {
    // Promoted to 1.2
    DriverProperties,
    ImageFormatList,
    ShaderFloat16Int8,
    ShaderSubgroupExtendedTypes,
    ShaderBufferInt64Atomics,
    DrawIndirectCount,
    VulkanMemoryModel,
    ShaderFloatControls,
    Spirv14,
    DescriptorIndexing,
    CreateRenderPass2,
    DepthStencilResolve,

    // Promoted to 1.3
    ShaderIntegerDotProduct,
    ZeroInitializeWorkgroupMemory,
    DemoteToHelperInvocation,
    Maintenance4,
    SubgroupSizeControl,
    DynamicRendering,
    ExtendedDynamicState,

    // Promoted to 1.4
    PipelineRobustness,
    Maintenance5,

    // Others
    DepthClipEnable,
    ImageDrmFormatModifier,
    Swapchain,
    QueueFamilyForeign,
    Robustness2,
    DisplayTiming,
    CooperativeMatrix,
    MultisampledRenderToSingleSampled,
    PhysicalDeviceDrm,
    RasterizationOrderAttachmentAccess,

    // External* extensions
    ExternalMemoryAndroidHardwareBuffer,
    ExternalMemoryFD,
    ExternalMemoryDmaBuf,
    ExternalMemoryZirconHandle,
    ExternalMemoryHost,
    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;
};

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

// 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 version);

// The list of all known Vulkan layers.
enum class VulkanLayer : uint8_t {
    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.
absl::flat_hash_map<std::string, VulkanLayer> CreateVulkanLayerNameMap();

}  // namespace dawn::native::vulkan

#endif  // SRC_DAWN_NATIVE_VULKAN_VULKANEXTENSIONS_H_
