/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"

#if defined(SK_GANESH) && defined(SK_VULKAN)

#include "include/core/SkTypes.h"
#include "include/gpu/vk/VulkanTypes.h"
#include "src/base/SkAutoMalloc.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/vk/VkTestUtils.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <functional>
#include <initializer_list>
#include <vulkan/vulkan_core.h>

struct GrContextOptions;

#define ACQUIRE_VK_PROC_NOCHECK(name, instance) \
    PFN_vk##name grVk##name =                                                              \
            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE))

#define ACQUIRE_VK_PROC(name, instance)                                                    \
    PFN_vk##name grVk##name =                                                              \
            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
    do {                                                                                   \
        if (grVk##name == nullptr) {                                                       \
            if (instance != VK_NULL_HANDLE) {                                              \
                destroy_instance(getProc, instance);                                       \
            }                                                                              \
            return;                                                                        \
        }                                                                                  \
    } while (0)

#define ACQUIRE_VK_PROC_LOCAL(name, instance)                                              \
    PFN_vk##name grVk##name =                                                              \
            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
    do {                                                                                   \
        if (grVk##name == nullptr) {                                                       \
            return;                                                                        \
        }                                                                                  \
    } while (0)

#define GET_PROC_LOCAL(F, inst) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)

static void destroy_instance(const skgpu::VulkanGetProc& getProc, VkInstance inst) {
    ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst);
    grVkDestroyInstance(inst, nullptr);
}

// If the extension VK_EXT_GLOBAL_PRIORITY is supported, this test just tries to create a VkDevice
// using the various global priorities. The test passes if no errors are reported or the test
// doesn't crash.
DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(VulkanPriorityExtension,
                                   reporter,
                                   context_info,
                                   CtsEnforcement::kApiLevel_T) {
    PFN_vkGetInstanceProcAddr instProc;
    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
        return;
    }
    // This isn't the most effecient but we just use the instProc to get all ptrs.
    auto getProc = [instProc](const char* proc_name, VkInstance instance, VkDevice) {
        return instProc(instance, proc_name);
    };

    VkResult err;

    ACQUIRE_VK_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE);
    uint32_t instanceVersion = 0;
    // Vulkan 1.1 is required, so vkEnumerateInstanceVersion should always be available.
    SkASSERT(grVkEnumerateInstanceVersion != nullptr);
    err = grVkEnumerateInstanceVersion(&instanceVersion);
    if (err) {
        ERRORF(reporter, "failed ot enumerate instance version. Err: %d", err);
        return;
    }
    SkASSERT(instanceVersion >= VK_API_VERSION_1_1);
    // We can set the apiVersion to be whatever the highest api we may use in skia. For now we
    // set it to 1.1 since that is the most common Vulkan version on Android devices.
    const uint32_t apiVersion = VK_API_VERSION_1_1;

    instanceVersion = std::min(instanceVersion, apiVersion);

    VkPhysicalDevice physDev;
    VkDevice device;
    VkInstance inst;

    const VkApplicationInfo app_info = {
        VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
        nullptr,                            // pNext
        "vktest",                           // pApplicationName
        0,                                  // applicationVersion
        "vktest",                           // pEngineName
        0,                                  // engineVersion
        apiVersion,                         // apiVersion
    };

    const VkInstanceCreateInfo instance_create = {
        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,    // sType
        nullptr,                                   // pNext
        0,                                         // flags
        &app_info,                                 // pApplicationInfo
        0,                                         // enabledLayerNameCount
        nullptr,                                   // ppEnabledLayerNames
        0,                                         // enabledExtensionNameCount
        nullptr,                                   // ppEnabledExtensionNames
    };

    ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE);
    err = grVkCreateInstance(&instance_create, nullptr, &inst);
    if (err < 0) {
        ERRORF(reporter, "Failed to create VkInstance");
        return;
    }

    ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst);
    ACQUIRE_VK_PROC(GetPhysicalDeviceProperties, inst);
    ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst);
    ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst);
    ACQUIRE_VK_PROC(CreateDevice, inst);
    ACQUIRE_VK_PROC(GetDeviceQueue, inst);
    ACQUIRE_VK_PROC(DeviceWaitIdle, inst);
    ACQUIRE_VK_PROC(DestroyDevice, inst);

    uint32_t gpuCount;
    err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
    if (err) {
        ERRORF(reporter, "vkEnumeratePhysicalDevices failed: %d", err);
        destroy_instance(getProc, inst);
        return;
    }
    if (!gpuCount) {
        // Don't throw and error here, because this behavior is allowed by Android CTS. A device
        // count of 0 effectively means Vulkan is not supported.
        destroy_instance(getProc, inst);
        return;
    }
    // Just returning the first physical device instead of getting the whole array.
    // TODO: find best match for our needs
    gpuCount = 1;
    err = grVkEnumeratePhysicalDevices(inst, &gpuCount, &physDev);
    // VK_INCOMPLETE is returned when the count we provide is less than the total device count.
    if (err && VK_INCOMPLETE != err) {
        ERRORF(reporter, "vkEnumeratePhysicalDevices failed: %d", err);
        destroy_instance(getProc, inst);
        return;
    }

    // query to get the initial queue props size
    uint32_t queueCount;
    grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
    if (!queueCount) {
        ERRORF(reporter, "vkGetPhysicalDeviceQueueFamilyProperties returned no queues.");
        destroy_instance(getProc, inst);
        return;
    }

    SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties));
    // now get the actual queue props
    VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get();

    grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps);

    // iterate to find the graphics queue
    uint32_t graphicsQueueIndex = queueCount;
    for (uint32_t i = 0; i < queueCount; i++) {
        if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
            graphicsQueueIndex = i;
            break;
        }
    }
    if (graphicsQueueIndex == queueCount) {
        ERRORF(reporter, "Could not find any supported graphics queues.");
        destroy_instance(getProc, inst);
        return;
    }

    GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst);
    GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst);

    if (!EnumerateDeviceExtensionProperties ||
        !EnumerateDeviceLayerProperties) {
        destroy_instance(getProc, inst);
        return;
    }

    // device extensions
    // via Vulkan implementation and implicitly enabled layers
    uint32_t extensionCount = 0;
    err = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr);
    if (VK_SUCCESS != err) {
        ERRORF(reporter, "Could not  enumerate device extension properties.");
        destroy_instance(getProc, inst);
        return;
    }
    VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
    err = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
    if (VK_SUCCESS != err) {
        delete[] extensions;
        ERRORF(reporter, "Could not  enumerate device extension properties.");
        destroy_instance(getProc, inst);
        return;
    }
    bool hasPriorityExt = false;
    for (uint32_t i = 0; i < extensionCount; ++i) {
        if (!strcmp(extensions[i].extensionName, VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME)) {
            hasPriorityExt = true;
        }
    }
    delete[] extensions;

    if (!hasPriorityExt) {
        destroy_instance(getProc, inst);
        return;
    }

    const char* priorityExt = VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME;

    VkPhysicalDeviceFeatures deviceFeatures;
    grVkGetPhysicalDeviceFeatures(physDev, &deviceFeatures);

    // This looks like it would slow things down and we can't depend on it on all platforms.
    deviceFeatures.robustBufferAccess = VK_FALSE;

    float queuePriorities[1] = { 0.0 };

    VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo;
    queuePriorityCreateInfo.sType =
            VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
    queuePriorityCreateInfo.pNext = nullptr;

    VkDeviceQueueCreateInfo queueInfo = {
        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
        &queuePriorityCreateInfo,                   // pNext
        0,                                          // VkDeviceQueueCreateFlags
        graphicsQueueIndex,                         // queueFamilyIndex
        1,                                          // queueCount
        queuePriorities,                            // pQueuePriorities
    };

    for (VkQueueGlobalPriorityEXT globalPriority : { VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT,
                                                     VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT,
                                                     VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT,
                                                     VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT }) {
        queuePriorityCreateInfo.globalPriority = globalPriority;

        const VkDeviceCreateInfo deviceInfo = {
            VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,        // sType
            nullptr,                                     // pNext
            0,                                           // VkDeviceCreateFlags
            1,                                           // queueCreateInfoCount
            &queueInfo,                                  // pQueueCreateInfos
            0,                                           // layerCount
            nullptr,                                     // ppEnabledLayerNames
            1,                                           // extensionCount
            &priorityExt,                                // ppEnabledExtensionNames
            &deviceFeatures                              // ppEnabledFeatures
        };

        err = grVkCreateDevice(physDev, &deviceInfo, nullptr, &device);

        if (err != VK_SUCCESS && err != VK_ERROR_NOT_PERMITTED_EXT) {
            ERRORF(reporter, "CreateDevice failed: %d, priority %d", err, globalPriority);
            destroy_instance(getProc, inst);
            continue;
        }
        if (err != VK_ERROR_NOT_PERMITTED_EXT) {
            grVkDestroyDevice(device, nullptr);
        }
    }
    destroy_instance(getProc, inst);
}

#endif
