// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/vulkan/vulkan_memory.h"

#include <vulkan/vulkan.h>

#include "base/logging.h"
#include "build/build_config.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace gpu {
namespace {

absl::optional<uint32_t> FindMemoryTypeIndex(
    VkPhysicalDevice physical_device,
    const VkMemoryRequirements* requirements,
    VkMemoryPropertyFlags flags) {
  VkPhysicalDeviceMemoryProperties properties;
  vkGetPhysicalDeviceMemoryProperties(physical_device, &properties);
  constexpr uint32_t kMaxIndex = 31;
  for (uint32_t i = 0; i <= kMaxIndex; i++) {
    if (((1u << i) & requirements->memoryTypeBits) == 0) {
      continue;
    }
    if ((properties.memoryTypes[i].propertyFlags & flags) != flags) {
      continue;
    }
    return i;
  }
  NOTREACHED();
  return absl::nullopt;
}

}  // namespace

VulkanMemory::VulkanMemory(base::PassKey<VulkanMemory> pass_key) {}

VulkanMemory::~VulkanMemory() {
  DCHECK(!device_queue_);
  DCHECK(device_memory_ == VK_NULL_HANDLE);
}

// static
std::unique_ptr<VulkanMemory> VulkanMemory::Create(
    VulkanDeviceQueue* device_queue,
    VkDeviceMemory device_memory,
    VkDeviceSize size,
    uint32_t type_index) {
  auto memory = std::make_unique<VulkanMemory>(base::PassKey<VulkanMemory>());
  memory->device_queue_ = device_queue;
  memory->device_memory_ = device_memory;
  memory->size_ = size;
  memory->type_index_ = type_index;
  return memory;
}

// static
std::unique_ptr<VulkanMemory> VulkanMemory::Create(
    VulkanDeviceQueue* device_queue,
    const VkMemoryRequirements* requirements,
    const void* extra_allocate_info) {
  auto memory = std::make_unique<VulkanMemory>(base::PassKey<VulkanMemory>());
  if (!memory->Initialize(device_queue, requirements, extra_allocate_info)) {
    return nullptr;
  }
  return memory;
}

void VulkanMemory::Destroy() {
  if (!device_queue_) {
    return;
  }
  VkDevice vk_device = device_queue_->GetVulkanDevice();
  if (device_memory_ != VK_NULL_HANDLE) {
    vkFreeMemory(vk_device, device_memory_, nullptr /* pAllocator */);
    device_memory_ = VK_NULL_HANDLE;
  }
  device_queue_ = nullptr;
}

bool VulkanMemory::Initialize(VulkanDeviceQueue* device_queue,
                              const VkMemoryRequirements* requirements,
                              const void* extra_allocate_info) {
  auto index =
      FindMemoryTypeIndex(device_queue->GetVulkanPhysicalDevice(), requirements,
                          VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

  if (!index) {
    DLOG(ERROR) << "Cannot find validate memory type index.";
    return false;
  }

  VkMemoryAllocateInfo memory_allocate_info = {
      .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
      .pNext = extra_allocate_info,
      .allocationSize = requirements->size,
      .memoryTypeIndex = index.value(),
  };

  VkDevice vk_device = device_queue->GetVulkanDevice();
  VkResult result = vkAllocateMemory(vk_device, &memory_allocate_info,
                                     nullptr /* pAllocator */, &device_memory_);
  if (result != VK_SUCCESS) {
    DLOG(ERROR) << "vkAllocateMemory failed result:" << result;
    return false;
  }

  device_queue_ = device_queue;
  size_ = requirements->size;
  type_index_ = index.value();

  return true;
}

#if BUILDFLAG(IS_POSIX)
base::ScopedFD VulkanMemory::GetMemoryFd(
    VkExternalMemoryHandleTypeFlagBits handle_type) {
  VkMemoryGetFdInfoKHR get_fd_info = {
      .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
      .memory = device_memory_,
      .handleType = handle_type,

  };

  VkDevice device = device_queue_->GetVulkanDevice();
  int memory_fd = -1;
  vkGetMemoryFdKHR(device, &get_fd_info, &memory_fd);
  if (memory_fd < 0) {
    DLOG(ERROR) << "Unable to extract file descriptor out of external VkImage";
    return base::ScopedFD();
  }

  return base::ScopedFD(memory_fd);
}
#endif  // BUILDFLAG(IS_POSIX)

#if BUILDFLAG(IS_WIN)
base::win::ScopedHandle VulkanMemory::GetMemoryHandle(
    VkExternalMemoryHandleTypeFlagBits handle_type) {
  VkMemoryGetWin32HandleInfoKHR get_handle_info = {
      .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
      .memory = device_memory(),
      .handleType = handle_type,
  };

  VkDevice device = device_queue_->GetVulkanDevice();

  HANDLE handle = nullptr;
  vkGetMemoryWin32HandleKHR(device, &get_handle_info, &handle);
  if (handle == nullptr) {
    DLOG(ERROR) << "Unable to extract file handle out of external VkImage";
    return base::win::ScopedHandle();
  }

  return base::win::ScopedHandle(handle);
}
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_FUCHSIA)
zx::vmo VulkanMemory::GetMemoryZirconHandle() {
  VkMemoryGetZirconHandleInfoFUCHSIA get_handle_info = {
      .sType = VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
      .memory = device_memory(),
      .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA,
  };

  VkDevice device = device_queue_->GetVulkanDevice();
  zx::vmo vmo;
  VkResult result = vkGetMemoryZirconHandleFUCHSIA(device, &get_handle_info,
                                                   vmo.reset_and_get_address());
  if (result != VK_SUCCESS) {
    DLOG(ERROR) << "vkGetMemoryFuchsiaHandleKHR failed: " << result;
    vmo.reset();
  }

  return vmo;
}
#endif  // BUILDFLAG(IS_FUCHSIA)

}  // namespace gpu
