// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "utils.h"

#include "src/graphics/tests/common/vulkan_context.h"

VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsTestCallback(
    VkDebugUtilsMessageSeverityFlagBitsEXT msg_severity, VkDebugUtilsMessageTypeFlagsEXT msg_types,
    const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *user_data) {
  auto context_with_data = reinterpret_cast<VulkanContext::ContextWithUserData *>(user_data);
  if (msg_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
    fprintf(stderr, "%s\n", callback_data->pMessage);
    EXPECT_TRUE(context_with_data->context()->validation_errors_ignored());
  } else {
    fprintf(stdout, "%s\n", callback_data->pMessage);
  }
  return VK_FALSE;
}

VulkanExtensionSupportState GetVulkanTimelineSemaphoreSupport(uint32_t instance_api_version) {
  vk::ApplicationInfo app_info;
  app_info.apiVersion = instance_api_version;

  vk::InstanceCreateInfo instance_info;
  instance_info.pApplicationInfo = &app_info;

  auto [instance_result, instance] = vk::createInstanceUnique(instance_info);
  if (instance_result != vk::Result::eSuccess) {
    RTN_MSG(VulkanExtensionSupportState::kNotSupported, "Failed to create Vulkan instance.\n");
  }

  auto [phy_dev_result, physical_devices] = instance->enumeratePhysicalDevices();
  if (phy_dev_result != vk::Result::eSuccess) {
    RTN_MSG(VulkanExtensionSupportState::kNotSupported, "Failed to get physical devices.\n");
  }

  if (physical_devices.size() == 0) {
    RTN_MSG(VulkanExtensionSupportState::kNotSupported, "Zero physical devices found.\n");
  }

  const uint32_t kDeviceIndex = 0u;
  const auto &physical_device = physical_devices[kDeviceIndex];
  auto device_properties = physical_device.getProperties();

  // We check Vulkan core support only if both the instance version and device
  // API version are no earlier than 1.2.
  if (instance_api_version >= VK_API_VERSION_1_2 &&
      device_properties.apiVersion >= VK_API_VERSION_1_2) {
    auto supported_features =
        physical_device
            .getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan12Features>();
    if (supported_features.get<vk::PhysicalDeviceVulkan12Features>().timelineSemaphore) {
      return VulkanExtensionSupportState::kSupportedInCore;
    }
  }

  // If device / instance API version < 1.2, we should check if the device supports
  // VK_KHR_timeline_semaphore extension.
  auto extension_rv = physical_device.enumerateDeviceExtensionProperties();
  if (extension_rv.result != vk::Result::eSuccess) {
    RTN_MSG(VulkanExtensionSupportState::kNotSupported,
            "Failed to get device extension properties.\n");
  }

  auto extensions = extension_rv.value;
  auto found_ext = std::find_if(extensions.begin(), extensions.end(), [](const auto &extension) {
                     return strcmp(extension.extensionName.data(),
                                   VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME) == 0;
                   }) != extensions.end();

  if (found_ext) {
    auto supported_features =
        physical_device.getFeatures2<vk::PhysicalDeviceFeatures2,
                                     vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>();
    if (supported_features.get<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>()
            .timelineSemaphore) {
      return VulkanExtensionSupportState::kSupportedAsExtensionOnly;
    }
  }
  return VulkanExtensionSupportState::kNotSupported;
}
