sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_waylandvulkan.c (6852B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 
     22 /*
     23  * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
     24  * SDL_x11vulkan.c.
     25  */
     26 
     27 #include "../../SDL_internal.h"
     28 
     29 #if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WAYLAND
     30 
     31 #include "SDL_waylandvideo.h"
     32 #include "SDL_waylandwindow.h"
     33 
     34 #include "SDL_loadso.h"
     35 #include "SDL_waylandvulkan.h"
     36 #include "SDL_syswm.h"
     37 
     38 #if defined(__OpenBSD__)
     39 #define DEFAULT_VULKAN  "libvulkan.so"
     40 #else
     41 #define DEFAULT_VULKAN  "libvulkan.so.1"
     42 #endif
     43 
     44 int Wayland_Vulkan_LoadLibrary(_THIS, const char *path)
     45 {
     46     VkExtensionProperties *extensions = NULL;
     47     Uint32 i, extensionCount = 0;
     48     SDL_bool hasSurfaceExtension = SDL_FALSE;
     49     SDL_bool hasWaylandSurfaceExtension = SDL_FALSE;
     50     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
     51     if(_this->vulkan_config.loader_handle)
     52         return SDL_SetError("Vulkan already loaded");
     53 
     54     /* Load the Vulkan loader library */
     55     if(!path)
     56         path = SDL_getenv("SDL_VULKAN_LIBRARY");
     57     if(!path)
     58         path = DEFAULT_VULKAN;
     59     _this->vulkan_config.loader_handle = SDL_LoadObject(path);
     60     if(!_this->vulkan_config.loader_handle)
     61         return -1;
     62     SDL_strlcpy(_this->vulkan_config.loader_path, path,
     63                 SDL_arraysize(_this->vulkan_config.loader_path));
     64     vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
     65         _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
     66     if(!vkGetInstanceProcAddr)
     67         goto fail;
     68     _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
     69     _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
     70         (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
     71             VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
     72     if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
     73         goto fail;
     74     extensions = SDL_Vulkan_CreateInstanceExtensionsList(
     75         (PFN_vkEnumerateInstanceExtensionProperties)
     76             _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
     77         &extensionCount);
     78     if(!extensions)
     79         goto fail;
     80     for(i = 0; i < extensionCount; i++)
     81     {
     82         if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
     83             hasSurfaceExtension = SDL_TRUE;
     84         else if(SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
     85             hasWaylandSurfaceExtension = SDL_TRUE;
     86     }
     87     SDL_free(extensions);
     88     if(!hasSurfaceExtension)
     89     {
     90         SDL_SetError("Installed Vulkan doesn't implement the "
     91                      VK_KHR_SURFACE_EXTENSION_NAME " extension");
     92         goto fail;
     93     }
     94     else if(!hasWaylandSurfaceExtension)
     95     {
     96         SDL_SetError("Installed Vulkan doesn't implement the "
     97                      VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension");
     98         goto fail;
     99     }
    100     return 0;
    101 
    102 fail:
    103     SDL_UnloadObject(_this->vulkan_config.loader_handle);
    104     _this->vulkan_config.loader_handle = NULL;
    105     return -1;
    106 }
    107 
    108 void Wayland_Vulkan_UnloadLibrary(_THIS)
    109 {
    110     if(_this->vulkan_config.loader_handle)
    111     {
    112         SDL_UnloadObject(_this->vulkan_config.loader_handle);
    113         _this->vulkan_config.loader_handle = NULL;
    114     }
    115 }
    116 
    117 SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
    118                                           SDL_Window *window,
    119                                           unsigned *count,
    120                                           const char **names)
    121 {
    122     static const char *const extensionsForWayland[] = {
    123         VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
    124     };
    125     if(!_this->vulkan_config.loader_handle)
    126     {
    127         SDL_SetError("Vulkan is not loaded");
    128         return SDL_FALSE;
    129     }
    130     return SDL_Vulkan_GetInstanceExtensions_Helper(
    131             count, names, SDL_arraysize(extensionsForWayland),
    132             extensionsForWayland);
    133 }
    134 
    135 void Wayland_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
    136 {
    137     SDL_WindowData *data;
    138     if (window->driverdata) {
    139         data = (SDL_WindowData *) window->driverdata;
    140 
    141         if (w) {
    142             *w = window->w * data->scale_factor;
    143         }
    144 
    145         if (h) {
    146             *h = window->h * data->scale_factor;
    147         }
    148     }
    149 }
    150 
    151 SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
    152                                   SDL_Window *window,
    153                                   VkInstance instance,
    154                                   VkSurfaceKHR *surface)
    155 {
    156     SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
    157     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
    158         (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
    159     PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR =
    160         (PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr(
    161                                             instance,
    162                                             "vkCreateWaylandSurfaceKHR");
    163     VkWaylandSurfaceCreateInfoKHR createInfo;
    164     VkResult result;
    165 
    166     if(!_this->vulkan_config.loader_handle)
    167     {
    168         SDL_SetError("Vulkan is not loaded");
    169         return SDL_FALSE;
    170     }
    171 
    172     if(!vkCreateWaylandSurfaceKHR)
    173     {
    174         SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
    175                      " extension is not enabled in the Vulkan instance.");
    176         return SDL_FALSE;
    177     }
    178     SDL_zero(createInfo);
    179     createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
    180     createInfo.pNext = NULL;
    181     createInfo.flags = 0;
    182     createInfo.display = windowData->waylandData->display;
    183     createInfo.surface =  windowData->surface;
    184     result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
    185                                        NULL, surface);
    186     if(result != VK_SUCCESS)
    187     {
    188         SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
    189                      SDL_Vulkan_GetResultString(result));
    190         return SDL_FALSE;
    191     }
    192     return SDL_TRUE;
    193 }
    194 
    195 #endif
    196 
    197 /* vim: set ts=4 sw=4 expandtab: */