// Copyright 2019 Google LLC
//
// 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
//
//      https://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.

#include "iree/hal/vulkan/vulkan_driver.h"

#include <memory>

#include "absl/container/inlined_vector.h"
#include "iree/base/memory.h"
#include "iree/base/status.h"
#include "iree/base/target_platform.h"
#include "iree/base/tracing.h"
#include "iree/hal/device_info.h"
#include "iree/hal/vulkan/extensibility_util.h"
#include "iree/hal/vulkan/status_util.h"

namespace iree {
namespace hal {
namespace vulkan {

namespace {

// Returns a VkApplicationInfo struct populated with the default app info.
// We may allow hosting applications to override this via weak-linkage if it's
// useful, otherwise this is enough to create the application.
VkApplicationInfo GetDefaultApplicationInfo() {
  VkApplicationInfo info;
  info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  info.pNext = nullptr;
  info.pApplicationName = "IREE-ML";
  info.applicationVersion = 0;
  info.pEngineName = "IREE";
  info.engineVersion = 0;
#ifdef IREE_PLATFORM_ANDROID
  info.apiVersion = VK_API_VERSION_1_1;
#else
  info.apiVersion = VK_API_VERSION_1_2;
#endif
  return info;
}

// Populates device information from the given Vulkan physical device handle.
StatusOr<DeviceInfo> PopulateDeviceInfo(VkPhysicalDevice physical_device,
                                        const ref_ptr<DynamicSymbols>& syms) {
  VkPhysicalDeviceFeatures physical_device_features;
  syms->vkGetPhysicalDeviceFeatures(physical_device, &physical_device_features);
  // TODO(benvanik): check and optionally require these features:
  // - physical_device_features.robustBufferAccess
  // - physical_device_features.shaderInt16
  // - physical_device_features.shaderInt64
  // - physical_device_features.shaderFloat64

  VkPhysicalDeviceProperties physical_device_properties;
  syms->vkGetPhysicalDeviceProperties(physical_device,
                                      &physical_device_properties);
  // TODO(benvanik): check and optionally require reasonable limits.

  // TODO(benvanik): more clever/sanitized device naming.
  std::string name = std::string(physical_device_properties.deviceName);

  DeviceFeatureBitfield supported_features = DeviceFeature::kNone;
  // TODO(benvanik): implement debugging/profiling features.
  // TODO(benvanik): use props to determine if we have timing info.
  // supported_features |= DeviceFeature::kDebugging;
  // supported_features |= DeviceFeature::kCoverage;
  // supported_features |= DeviceFeature::kProfiling;
  return DeviceInfo("vulkan", std::move(name), supported_features,
                    reinterpret_cast<DriverDeviceID>(physical_device));
}

}  // namespace

// static
StatusOr<ref_ptr<VulkanDriver>> VulkanDriver::Create(
    Options options, ref_ptr<DynamicSymbols> syms) {
  IREE_TRACE_SCOPE0("VulkanDriver::Create");

  // Load and connect to RenderDoc before instance creation.
  // Note: RenderDoc assumes that only a single VkDevice is used:
  //   https://renderdoc.org/docs/behind_scenes/vulkan_support.html#current-support
  std::unique_ptr<RenderDocCaptureManager> renderdoc_capture_manager;
  if (options.enable_renderdoc) {
    renderdoc_capture_manager = std::make_unique<RenderDocCaptureManager>();
    IREE_RETURN_IF_ERROR(renderdoc_capture_manager->Connect());
  }

  // Find the layers and extensions we need (or want) that are also available
  // on the instance. This will fail when required ones are not present.
  IREE_ASSIGN_OR_RETURN(
      auto enabled_layer_names,
      MatchAvailableInstanceLayers(options.instance_extensibility, *syms));
  IREE_ASSIGN_OR_RETURN(
      auto enabled_extension_names,
      MatchAvailableInstanceExtensions(options.instance_extensibility, *syms));
  auto instance_extensions =
      PopulateEnabledInstanceExtensions(enabled_extension_names);

  // Create the instance this driver will use for all requests.
  VkApplicationInfo app_info = GetDefaultApplicationInfo();
  app_info.apiVersion = options.api_version;
  VkInstanceCreateInfo create_info;
  create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  create_info.pNext = nullptr;
  create_info.flags = 0;
  create_info.pApplicationInfo = &app_info;
  create_info.enabledLayerCount =
      static_cast<uint32_t>(enabled_layer_names.size());
  create_info.ppEnabledLayerNames = enabled_layer_names.data();
  create_info.enabledExtensionCount =
      static_cast<uint32_t>(enabled_extension_names.size());
  create_info.ppEnabledExtensionNames = enabled_extension_names.data();

  // If we have the debug_utils extension then we can chain a one-shot messenger
  // callback that we can use to log out the instance creation errors. Once we
  // have the real instance we can then register a real messenger.
  union {
    VkDebugUtilsMessengerCreateInfoEXT debug_utils_create_info;
    VkDebugReportCallbackCreateInfoEXT debug_report_create_info;
  };
  if (instance_extensions.debug_utils) {
    create_info.pNext = &debug_utils_create_info;
    DebugReporter::PopulateStaticCreateInfo(&debug_utils_create_info);
  } else if (instance_extensions.debug_report) {
    create_info.pNext = &debug_report_create_info;
    DebugReporter::PopulateStaticCreateInfo(&debug_report_create_info);
  }

  // Some ICDs appear to leak in here, out of our control.
  // Warning: leak checks remain disabled if an error is returned.
  IREE_DISABLE_LEAK_CHECKS();
  VkInstance instance = VK_NULL_HANDLE;
  VK_RETURN_IF_ERROR(
      syms->vkCreateInstance(&create_info, /*pAllocator=*/nullptr, &instance))
      << "Unable to create Vulkan instance";
  IREE_ENABLE_LEAK_CHECKS();

  // TODO(benvanik): enable validation layers if needed.

  // Now that the instance has been created we can fetch all of the instance
  // symbols.
  IREE_RETURN_IF_ERROR(syms->LoadFromInstance(instance));

  // The real debug messenger (not just the static one used above) can now be
  // created as we've loaded all the required symbols.
  // TODO(benvanik): strip in release builds.
  std::unique_ptr<DebugReporter> debug_reporter;
  if (instance_extensions.debug_utils) {
    IREE_ASSIGN_OR_RETURN(debug_reporter,
                          DebugReporter::CreateDebugUtilsMessenger(
                              instance, syms,
                              /*allocation_callbacks=*/nullptr));
  } else if (instance_extensions.debug_report) {
    IREE_ASSIGN_OR_RETURN(
        debug_reporter, DebugReporter::CreateDebugReportCallback(
                            instance, syms, /*allocation_callbacks=*/nullptr));
  }

  return assign_ref(new VulkanDriver(
      std::move(syms), instance,
      /*owns_instance=*/true, std::move(options.device_options),
      options.default_device_index, std::move(debug_reporter),
      std::move(renderdoc_capture_manager)));
}

// static
StatusOr<ref_ptr<VulkanDriver>> VulkanDriver::CreateUsingInstance(
    Options options, ref_ptr<DynamicSymbols> syms, VkInstance instance) {
  IREE_TRACE_SCOPE0("VulkanDriver::CreateUsingInstance");

  if (instance == VK_NULL_HANDLE) {
    return InvalidArgumentErrorBuilder(IREE_LOC)
           << "VkInstance must not be VK_NULL_HANDLE";
  }

  // Find the extensions we need (or want) that are also available on the
  // instance. This will fail when required ones are not present.
  //
  // Since the instance is already created, we can't actually enable any
  // extensions or query if they are really enabled - we just have to trust
  // that the caller already enabled them for us (or we may fail later).
  IREE_ASSIGN_OR_RETURN(
      auto enabled_extension_names,
      MatchAvailableInstanceExtensions(options.instance_extensibility, *syms));
  auto instance_extensions =
      PopulateEnabledInstanceExtensions(enabled_extension_names);

  IREE_RETURN_IF_ERROR(syms->LoadFromInstance(instance));

  // TODO(benvanik): strip in release builds.
  std::unique_ptr<DebugReporter> debug_reporter;
  if (instance_extensions.debug_utils) {
    IREE_ASSIGN_OR_RETURN(debug_reporter,
                          DebugReporter::CreateDebugUtilsMessenger(
                              instance, syms,
                              /*allocation_callbacks=*/nullptr));
  } else if (instance_extensions.debug_report) {
    IREE_ASSIGN_OR_RETURN(
        debug_reporter, DebugReporter::CreateDebugReportCallback(
                            instance, syms, /*allocation_callbacks=*/nullptr));
  }

  // Note: no RenderDocCaptureManager here since the VkInstance is already
  // created externally. Applications using this function must provide their
  // own RenderDoc / debugger integration as desired.

  return assign_ref(
      new VulkanDriver(std::move(syms), instance, /*owns_instance=*/false,
                       std::move(options.device_options),
                       options.default_device_index, std::move(debug_reporter),
                       /*debug_capture_manager=*/nullptr));
}

VulkanDriver::VulkanDriver(
    ref_ptr<DynamicSymbols> syms, VkInstance instance, bool owns_instance,
    VulkanDevice::Options device_options, int default_device_index,
    std::unique_ptr<DebugReporter> debug_reporter,
    std::unique_ptr<RenderDocCaptureManager> renderdoc_capture_manager)
    : Driver("vulkan"),
      syms_(std::move(syms)),
      instance_(instance),
      owns_instance_(owns_instance),
      device_options_(std::move(device_options)),
      default_device_index_(default_device_index),
      debug_reporter_(std::move(debug_reporter)),
      renderdoc_capture_manager_(std::move(renderdoc_capture_manager)) {}

VulkanDriver::~VulkanDriver() {
  IREE_TRACE_SCOPE0("VulkanDriver::dtor");
  debug_reporter_.reset();
  if (owns_instance_) {
    syms()->vkDestroyInstance(instance_, /*pAllocator=*/nullptr);
  }
}

StatusOr<std::vector<DeviceInfo>> VulkanDriver::EnumerateAvailableDevices() {
  IREE_TRACE_SCOPE0("VulkanDriver::EnumerateAvailableDevices");

  // Query all available devices (at this moment, note that this may change!).
  uint32_t physical_device_count = 0;
  VK_RETURN_IF_ERROR(syms()->vkEnumeratePhysicalDevices(
      instance_, &physical_device_count, nullptr));
  absl::InlinedVector<VkPhysicalDevice, 2> physical_devices(
      physical_device_count);
  VK_RETURN_IF_ERROR(syms()->vkEnumeratePhysicalDevices(
      instance_, &physical_device_count, physical_devices.data()));

  // Convert to our HAL structure.
  std::vector<DeviceInfo> device_infos;
  device_infos.reserve(physical_device_count);
  for (auto physical_device : physical_devices) {
    // TODO(benvanik): if we fail should we just ignore the device in the list?
    IREE_ASSIGN_OR_RETURN(auto device_info,
                          PopulateDeviceInfo(physical_device, syms()));
    device_infos.push_back(std::move(device_info));
  }
  return device_infos;
}

StatusOr<ref_ptr<Device>> VulkanDriver::CreateDefaultDevice() {
  IREE_TRACE_SCOPE0("VulkanDriver::CreateDefaultDevice");

  // Query available devices.
  IREE_ASSIGN_OR_RETURN(auto available_devices, EnumerateAvailableDevices());
  if (default_device_index_ < 0 ||
      default_device_index_ >= available_devices.size()) {
    return NotFoundErrorBuilder(IREE_LOC)
           << "Device index " << default_device_index_ << " not found "
           << "(of " << available_devices.size() << ")";
  }

  // Just create the first one we find.
  return CreateDevice(available_devices[default_device_index_].device_id());
}

StatusOr<ref_ptr<Device>> VulkanDriver::CreateDevice(DriverDeviceID device_id) {
  IREE_TRACE_SCOPE0("VulkanDriver::CreateDevice");

  auto physical_device = reinterpret_cast<VkPhysicalDevice>(device_id);
  IREE_ASSIGN_OR_RETURN(auto device_info,
                        PopulateDeviceInfo(physical_device, syms()));

  // Attempt to create the device.
  // This may fail if the device was enumerated but is in exclusive use,
  // disabled by the system, or permission is denied.
  IREE_ASSIGN_OR_RETURN(
      auto device,
      VulkanDevice::Create(add_ref(this), instance(), device_info,
                           physical_device, device_options_, syms(),
                           renderdoc_capture_manager_.get()));

  IREE_LOG(INFO) << "Created Vulkan Device: " << device->info().name();

  return device;
}

StatusOr<ref_ptr<Device>> VulkanDriver::WrapDevice(
    VkPhysicalDevice physical_device, VkDevice logical_device,
    const QueueSet& compute_queue_set, const QueueSet& transfer_queue_set) {
  IREE_TRACE_SCOPE0("VulkanDriver::WrapDevice");

  IREE_ASSIGN_OR_RETURN(auto device_info,
                        PopulateDeviceInfo(physical_device, syms()));

  // Attempt to create the device.
  // This may fail if the VkDevice does not support all necessary features.
  IREE_ASSIGN_OR_RETURN(
      auto device,
      VulkanDevice::Wrap(add_ref(this), instance(), device_info,
                         physical_device, logical_device, device_options_,
                         compute_queue_set, transfer_queue_set, syms()));
  return device;
}

}  // namespace vulkan
}  // namespace hal
}  // namespace iree
