/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

/*
 * @author Manuel Alfayate Corchere <redwindwanderer@gmail.com>.
 * Based on Jacob Lifshay's SDL_x11vulkan.c.
 */

#include "../../SDL_internal.h"

#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_KMSDRM

#include "SDL_kmsdrmvideo.h"
#include "SDL_kmsdrmdyn.h"
#include "SDL_assert.h"

#include "SDL_loadso.h"
#include "SDL_kmsdrmvulkan.h"
#include "SDL_syswm.h"
#include "sys/ioctl.h"

#if defined(__OpenBSD__)
#define DEFAULT_VULKAN  "libvulkan.so"
#else
#define DEFAULT_VULKAN  "libvulkan.so.1"
#endif

int KMSDRM_Vulkan_LoadLibrary(_THIS, const char *path)
{
    VkExtensionProperties *extensions = NULL;
    Uint32 i, extensionCount = 0;
    SDL_bool hasSurfaceExtension = SDL_FALSE;
    SDL_bool hasDisplayExtension = SDL_FALSE;
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;

    if(_this->vulkan_config.loader_handle)
        return SDL_SetError("Vulkan already loaded");

    /* Load the Vulkan library */
    if(!path)
        path = SDL_getenv("SDL_VULKAN_LIBRARY");
    if(!path)
        path = DEFAULT_VULKAN;

    _this->vulkan_config.loader_handle = SDL_LoadObject(path);

    if(!_this->vulkan_config.loader_handle)
        return -1;

    SDL_strlcpy(_this->vulkan_config.loader_path, path,
                SDL_arraysize(_this->vulkan_config.loader_path));

    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");

    if(!vkGetInstanceProcAddr)
        goto fail;

    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");

    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
        goto fail;

    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
        (PFN_vkEnumerateInstanceExtensionProperties)
            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
        &extensionCount);

    if(!extensions)
        goto fail;

    for(i = 0; i < extensionCount; i++)
    {
        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
            hasSurfaceExtension = SDL_TRUE;
        else if(SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0)
            hasDisplayExtension = SDL_TRUE;
    }

    SDL_free(extensions);

    if(!hasSurfaceExtension)
    {
        SDL_SetError("Installed Vulkan doesn't implement the "
                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
        goto fail;
    }
    else if(!hasDisplayExtension)
    {
        SDL_SetError("Installed Vulkan doesn't implement the "
                     VK_KHR_DISPLAY_EXTENSION_NAME "extension");
        goto fail;
    }

    return 0;

fail:
    SDL_UnloadObject(_this->vulkan_config.loader_handle);
    _this->vulkan_config.loader_handle = NULL;
    return -1;
}

void KMSDRM_Vulkan_UnloadLibrary(_THIS)
{
    if(_this->vulkan_config.loader_handle)
    {
        SDL_UnloadObject(_this->vulkan_config.loader_handle);
        _this->vulkan_config.loader_handle = NULL;
    }
}

/*********************************************************************/
/* Here we can put whatever Vulkan extensions we want to be enabled  */
/* at instance creation, which is done in the programs, not in SDL.  */
/* So: programs call SDL_Vulkan_GetInstanceExtensions() and here     */
/* we put the extensions specific to this backend so the programs    */
/* get a list with the extension we want, so they can include that   */
/* list in the ppEnabledExtensionNames and EnabledExtensionCount     */
/* members of the VkInstanceCreateInfo struct passed to              */
/* vkCreateInstance().                                               */
/*********************************************************************/
SDL_bool KMSDRM_Vulkan_GetInstanceExtensions(_THIS,
                                          SDL_Window *window,
                                          unsigned *count,
                                          const char **names)
{
    static const char *const extensionsForKMSDRM[] = {
        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME
    };
    if(!_this->vulkan_config.loader_handle)
    {
        SDL_SetError("Vulkan is not loaded");
        return SDL_FALSE;
    }
    return SDL_Vulkan_GetInstanceExtensions_Helper(
            count, names, SDL_arraysize(extensionsForKMSDRM),
            extensionsForKMSDRM);
}

void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
    if (w) {
        *w = window->w;
    }

    if (h) {
        *h = window->h;
    }
}

/***********************************************************************/
/* First thing to know is that we don't call vkCreateInstance() here.  */
/* Instead, programs using SDL and Vulkan create their Vulkan instance */
/* and we get it here, ready to use.                                   */
/* Extensions specific for this platform are activated in              */
/* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with       */
/* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */                
/***********************************************************************/
SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
                                  SDL_Window *window,
                                  VkInstance instance,
                                  VkSurfaceKHR *surface)
{
    VkPhysicalDevice gpu;
    uint32_t gpu_count;
    uint32_t display_count;
    uint32_t mode_count;
    uint32_t plane_count;

    VkPhysicalDevice *physical_devices = NULL;
    VkDisplayPropertiesKHR *displays_props = NULL;
    VkDisplayModePropertiesKHR *modes_props = NULL;
    VkDisplayPlanePropertiesKHR *planes_props = NULL;

    VkDisplayModeCreateInfoKHR display_mode_create_info;
    VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;

    VkExtent2D image_size;
    VkDisplayModeKHR *display_mode = NULL;
    VkDisplayModePropertiesKHR display_mode_props = {0};
    VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0};

    VkResult result;
    SDL_bool ret = SDL_FALSE;
    SDL_bool mode_found = SDL_FALSE;

    /* We don't receive a display index in KMSDRM_CreateDevice(), only
       a device index, which determines the GPU to use, but not the output.
       So we simply use the first connected output (ie, the first connected
       video output) for now.
       In other words, change this index to select a different output. Easy! */
    int display_index = 0;

    int i;

    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);

    /* Get the function pointers for the functions we will use. */
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;

    PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR =
        (PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr(
            instance, "vkCreateDisplayPlaneSurfaceKHR");

    PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices =
        (PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(
            instance, "vkEnumeratePhysicalDevices");

    PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR =
        (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr(
            instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");

    PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR =
        (PFN_vkGetDisplayModePropertiesKHR)vkGetInstanceProcAddr(
            instance, "vkGetDisplayModePropertiesKHR");

    PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR =
        (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
            instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");

    /*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
        (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
            instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
    
    PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
        (PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
            instance, "vkGetDisplayPlaneCapabilitiesKHR");
    */

    PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
        (PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
            instance, "vkCreateDisplayModeKHR");

    if(!_this->vulkan_config.loader_handle)
    {
        SDL_SetError("Vulkan is not loaded");
        goto clean;
    }

    /*************************************/
    /* Block for vulkan surface creation */
    /*************************************/

    /****************************************************************/
    /* If we got vkCreateDisplayPlaneSurfaceKHR() pointer, it means */
    /* that the VK_KHR_Display extension is active on the instance. */
    /* That's the central extension we need for x-less VK!          */
    /****************************************************************/
    if(!vkCreateDisplayPlaneSurfaceKHR)
    {
        SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME
                     " extension is not enabled in the Vulkan instance.");
        goto clean;
    }

    /* Get the physical device count. */
    vkEnumeratePhysicalDevices(instance, &gpu_count, NULL);

    if (gpu_count == 0) {
        SDL_SetError("Vulkan can't find physical devices (gpus).");
        goto clean;
    }

    /* Get the physical devices. */
    physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count);
    vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);

    /* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more
       than one video output doen't need to have more than one GPU, like the Pi4
       which has 1 GPU and 2 video outputs.
       We grab the GPU/physical_device with the index we got in KMSDR_CreateDevice(). */
    gpu = physical_devices[viddata->devindex]; 

    /* A display is a video output. 1 GPU can have N displays.
       Vulkan only counts the connected displays.
       Get the display count of the GPU. */
    vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, NULL);
    if (display_count == 0) {
        SDL_SetError("Vulkan can't find any displays.");
        goto clean;
    }

    /* Get the props of the displays of the physical device. */
    displays_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*displays_props));
    vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
                                           &display_count,
                                           displays_props);

    /* Get the videomode count for the first display. */
    vkGetDisplayModePropertiesKHR(gpu,
                                 displays_props[display_index].display,
                                 &mode_count, NULL);

    if (mode_count == 0) {
        SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0,
                               displays_props[display_index].displayName);
        goto clean;
    }

    /* Get the props of the videomodes for the first display. */
    modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
    vkGetDisplayModePropertiesKHR(gpu,
                                 displays_props[display_index].display,
                                 &mode_count, modes_props);

    /* Get the planes count of the physical device. */
    vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
    if (plane_count == 0) {
        SDL_SetError("Vulkan can't find any planes.");
        goto clean;
    }

    /* Get the props of the planes for the physical device. */
    planes_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
    vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);

    /* Get a video mode equal or smaller than the window size. REMEMBER:
       We have to get a small enough videomode for the window size,
       because videomode determines how big the scanout region is and we can't
       scanout a region bigger than the window (we would be reading past the
       buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
    for (i = 0; i < mode_count; i++) {
        if (modes_props[i].parameters.visibleRegion.width <= window->w &&
            modes_props[i].parameters.visibleRegion.height <= window->h)
        {
            display_mode_props = modes_props[i];
            mode_found = SDL_TRUE;
            break;
        }
    }

    if (mode_found &&
        display_mode_props.parameters.visibleRegion.width > 0 &&
        display_mode_props.parameters.visibleRegion.height > 0 ) {
        /* Found a suitable mode among the predefined ones. Use that. */
        display_mode = &(display_mode_props.displayMode);
    } else {
        /* Can't find a suitable mode among the predefined ones, so try to create our own. */
        new_mode_parameters.visibleRegion.width = window->w;
        new_mode_parameters.visibleRegion.height = window->h;
        new_mode_parameters.refreshRate = 60000; /* Always use 60Hz for now. */
        display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
        display_mode_create_info.parameters = new_mode_parameters;
        result = vkCreateDisplayModeKHR(gpu,
                                        displays_props[display_index].display,
                                        &display_mode_create_info,
                                        NULL, display_mode);
        if (result != VK_SUCCESS) {
            SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode.");
            goto clean;
         }
    }

    /* Just in case we get here without a display_mode. */
    if (!display_mode) {
            SDL_SetError("Vulkan couldn't get a display mode.");
            goto clean;
    }

    /********************************************/
    /* Let's finally create the Vulkan surface! */
    /********************************************/

    image_size.width = window->w;
    image_size.height = window->h;
    
    display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
    display_plane_surface_create_info.displayMode = *display_mode;
    /* For now, simply use the first plane. */
    display_plane_surface_create_info.planeIndex = 0;
    display_plane_surface_create_info.imageExtent = image_size;
    result = vkCreateDisplayPlaneSurfaceKHR(instance,
                                     &display_plane_surface_create_info,
                                     NULL,
                                     surface);
    if(result != VK_SUCCESS)
    {
        SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
            SDL_Vulkan_GetResultString(result));
        goto clean;
    }

    ret = SDL_TRUE;

clean:
    if (physical_devices)
        SDL_free (physical_devices);
    if (displays_props)
        SDL_free (displays_props);
    if (planes_props)
        SDL_free (planes_props);
    if (modes_props)
        SDL_free (modes_props);

    return ret;
}

#endif

/* vim: set ts=4 sw=4 expandtab: */
