/*
  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_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#include "SDL_assert.h"

#include "SDL_loadso.h"
#include "SDL_kmsdrm_legacy_vulkan.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_LEGACY_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_LEGACY_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_LEGACY_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_LEGACY_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_LEGACY_Vulkan_GetInstanceExtensions(), like we do with       */
/* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */                
/***********************************************************************/
SDL_bool KMSDRM_LEGACY_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_LEGACY_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: */
