// Copyright 2018 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 INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_
#define INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_

#include <vulkan/vulkan.h>

#include <array>
#include <vector>

#include "dawn/dawn_wsi.h"
#include "dawn/native/DawnNative.h"

namespace dawn::native::vulkan {

DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device);

DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName);

DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device,
                                                                         ::VkSurfaceKHR surface);
DAWN_NATIVE_EXPORT WGPUTextureFormat
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);

struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
    AdapterDiscoveryOptions();

    bool forceSwiftShader = false;
};

enum class NeedsDedicatedAllocation {
    Yes,
    No,
    // Use Vulkan reflection to detect whether a dedicated allocation is needed.
    Detect,
};

struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor {
  public:
    // The following members may be ignored if |ExternalImageDescriptor::isInitialized| is false
    // since the import does not need to preserve texture contents.

    // See https://www.khronos.org/registry/vulkan/specs/1.1/html/chap7.html. The acquire
    // operation old/new layouts must match exactly the layouts in the release operation. So
    // we may need to issue two barriers releasedOldLayout -> releasedNewLayout ->
    // cTextureDescriptor.usage if the new layout is not compatible with the desired usage.
    // The first barrier is the queue transfer, the second is the layout transition to our
    // desired usage.
    VkImageLayout releasedOldLayout = VK_IMAGE_LAYOUT_GENERAL;
    VkImageLayout releasedNewLayout = VK_IMAGE_LAYOUT_GENERAL;

    // Try to detect the need to use a dedicated allocation for imported images by default but let
    // the application override this as drivers have bugs and forget to require a dedicated
    // allocation.
    NeedsDedicatedAllocation dedicatedAllocation = NeedsDedicatedAllocation::Detect;

  protected:
    using ExternalImageDescriptor::ExternalImageDescriptor;
};

struct ExternalImageExportInfoVk : ExternalImageExportInfo {
  public:
    // See comments in |ExternalImageDescriptorVk|
    // Contains the old/new layouts used in the queue release operation.
    VkImageLayout releasedOldLayout;
    VkImageLayout releasedNewLayout;

  protected:
    using ExternalImageExportInfo::ExternalImageExportInfo;
};

// Can't use DAWN_PLATFORM_IS(LINUX) since header included in both Dawn and Chrome
#ifdef __linux__

// Common properties of external images represented by FDs. On successful import the file
// descriptor's ownership is transferred to the Dawn implementation and they shouldn't be
// used outside of Dawn again. TODO(enga): Also transfer ownership in the error case so the
// caller can assume the FD is always consumed.
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptorVk {
  public:
    int memoryFD;              // A file descriptor from an export of the memory of the image
    std::vector<int> waitFDs;  // File descriptors of semaphores which will be waited on

  protected:
    using ExternalImageDescriptorVk::ExternalImageDescriptorVk;
};

// Descriptor for opaque file descriptor image import
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorOpaqueFD : ExternalImageDescriptorFD {
    ExternalImageDescriptorOpaqueFD();

    VkDeviceSize allocationSize;  // Must match VkMemoryAllocateInfo from image creation
    uint32_t memoryTypeIndex;     // Must match VkMemoryAllocateInfo from image creation
};

// The plane-wise offset and stride.
struct DAWN_NATIVE_EXPORT PlaneLayout {
    uint64_t offset;
    uint32_t stride;
};

// Descriptor for dma-buf file descriptor image import
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDmaBuf : ExternalImageDescriptorFD {
    ExternalImageDescriptorDmaBuf();

    static constexpr uint32_t kMaxPlanes = 3;
    std::array<PlaneLayout, kMaxPlanes> planeLayouts;
    uint64_t drmModifier;  // DRM modifier of the buffer
};

// Info struct that is written to in |ExportVulkanImage|.
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoFD : ExternalImageExportInfoVk {
  public:
    // Contains the exported semaphore handles.
    std::vector<int> semaphoreHandles;

  protected:
    using ExternalImageExportInfoVk::ExternalImageExportInfoVk;
};

struct DAWN_NATIVE_EXPORT ExternalImageExportInfoOpaqueFD : ExternalImageExportInfoFD {
    ExternalImageExportInfoOpaqueFD();
};

struct DAWN_NATIVE_EXPORT ExternalImageExportInfoDmaBuf : ExternalImageExportInfoFD {
    ExternalImageExportInfoDmaBuf();
};

#ifdef __ANDROID__

// Descriptor for AHardwareBuffer image import
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorAHardwareBuffer : ExternalImageDescriptorVk {
  public:
    ExternalImageDescriptorAHardwareBuffer();

    struct AHardwareBuffer* handle;  // The AHardwareBuffer which contains the memory of the image
    std::vector<int> waitFDs;        // File descriptors of semaphores which will be waited on

  protected:
    using ExternalImageDescriptorVk::ExternalImageDescriptorVk;
};

struct DAWN_NATIVE_EXPORT ExternalImageExportInfoAHardwareBuffer : ExternalImageExportInfoFD {
    ExternalImageExportInfoAHardwareBuffer();
};

#endif  // __ANDROID__

#endif  // __linux__

// Imports external memory into a Vulkan image. Internally, this uses external memory /
// semaphore extensions to import the image and wait on the provided synchronizaton
// primitives before the texture can be used.
// On failure, returns a nullptr.
DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice device,
                                               const ExternalImageDescriptorVk* descriptor);

// Exports external memory from a Vulkan image. This must be called on wrapped textures
// before they are destroyed. It writes the semaphore to wait on and the old/new image
// layouts to |info|. Pass VK_IMAGE_LAYOUT_UNDEFINED as |desiredLayout| if you don't want to
// perform a layout transition.
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture,
                                          VkImageLayout desiredLayout,
                                          ExternalImageExportInfoVk* info);
// |ExportVulkanImage| with default desiredLayout of VK_IMAGE_LAYOUT_UNDEFINED.
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info);

}  // namespace dawn::native::vulkan

#endif  // INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_
