[PATCH 2 of 3] add vulkan implementation for x11

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 2 of 3] add vulkan implementation for x11

Jacob Lifshay
# HG changeset patch
# User Jacob Lifshay <[hidden email]>
# Date 1487661491 28800
#      Mon Feb 20 23:18:11 2017 -0800
# Node ID 5046b8390345b414fabfe20bf6516a58101f3ba9
# Parent  fd24ec69f7b848894158a1c19f5d4b05b68145fa
add vulkan implementation for x11

diff -r fd24ec69f7b8 -r 5046b8390345 src/video/x11/SDL_x11video.c
--- a/src/video/x11/SDL_x11video.c Mon Feb 20 23:18:11 2017 -0800
+++ b/src/video/x11/SDL_x11video.c Mon Feb 20 23:18:11 2017 -0800
@@ -39,6 +39,8 @@
 #include "SDL_x11opengles.h"
 #endif
 
+#include "SDL_x11vulkan.h"
+
 /* Initialization/Query functions */
 static int X11_VideoInit(_THIS);
 static void X11_VideoQuit(_THIS);
@@ -106,6 +108,9 @@
 X11_DeleteDevice(SDL_VideoDevice * device)
 {
     SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
+    if (device->vulkan_config.loader_handle) {
+        device->Vulkan_UnloadLibrary(device);
+    }
     if (data->display) {
         X11_XCloseDisplay(data->display);
     }
@@ -290,6 +295,13 @@
 
     device->free = X11_DeleteDevice;
 
+#if SDL_VULKAN_SUPPORTED
+    device->Vulkan_LoadLibrary = X11_Vulkan_LoadLibrary;
+    device->Vulkan_UnloadLibrary = X11_Vulkan_UnloadLibrary;
+    device->Vulkan_GetInstanceExtensions = X11_Vulkan_GetInstanceExtensions;
+    device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface;
+#endif
+
     return device;
 }
 
diff -r fd24ec69f7b8 -r 5046b8390345 src/video/x11/SDL_x11video.h
--- a/src/video/x11/SDL_x11video.h Mon Feb 20 23:18:11 2017 -0800
+++ b/src/video/x11/SDL_x11video.h Mon Feb 20 23:18:11 2017 -0800
@@ -68,6 +68,7 @@
 #include "SDL_x11mouse.h"
 #include "SDL_x11opengl.h"
 #include "SDL_x11window.h"
+#include "SDL_x11vulkan.h"
 
 /* Private display data */
 
@@ -139,6 +140,12 @@
     KeyCode filter_code;
     Time    filter_time;
 
+#if SDL_VULKAN_SUPPORTED
+    /* Vulkan variables only valid if _this->vulkan_config.loader_handle is not NULL */
+    void *vulkan_xlib_xcb_library;
+    PFN_XGetXCBConnection vulkan_XGetXCBConnection;
+#endif
+
 } SDL_VideoData;
 
 extern SDL_bool X11_UseDirectColorVisuals(void);
diff -r fd24ec69f7b8 -r 5046b8390345 src/video/x11/SDL_x11vulkan.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_x11vulkan.c Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,231 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 Sam Lantinga <[hidden email]>
+
+  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.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_x11vulkan.h"
+
+#if SDL_VULKAN_SUPPORTED
+
+int X11_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+    VkExtensionProperties *extensions = NULL;
+    Uint32 extensionCount = 0;
+    SDL_bool hasSurfaceExtension = SDL_FALSE;
+    SDL_bool hasXlibSurfaceExtension = SDL_FALSE;
+    SDL_bool hasXCBSurfaceExtension = SDL_FALSE;
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+    if(_this->vulkan_config.loader_handle)
+        return SDL_SetError("Vulkan already loaded");
+
+    /* Load the Vulkan loader library */
+    if(!path)
+        path = SDL_getenv("SDL_VULKAN_LIBRARY");
+    if(!path)
+        path = "libvulkan.so.1";
+    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+    if(!_this->vulkan_config.loader_handle)
+        return -1;
+    SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_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(Uint32 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_XCB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+            hasXCBSurfaceExtension = SDL_TRUE;
+        else if(SDL_strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+            hasXlibSurfaceExtension = SDL_TRUE;
+    }
+    SDL_free(extensions);
+    if(!hasSurfaceExtension)
+    {
+        SDL_SetError("Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension");
+        goto fail;
+    }
+    if(hasXlibSurfaceExtension)
+    {
+        videoData->vulkan_xlib_xcb_library = NULL;
+    }
+    else if(!hasXCBSurfaceExtension)
+    {
+        SDL_SetError("Vulkan doesn't implement either of the " VK_KHR_XCB_SURFACE_EXTENSION_NAME
+                     " extension or the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension");
+        goto fail;
+    }
+    else
+    {
+        const char *libX11XCBLibraryName = SDL_getenv("SDL_X11_XCB_LIBRARY");
+        if(!libX11XCBLibraryName)
+            libX11XCBLibraryName = "libX11-xcb.so";
+        videoData->vulkan_xlib_xcb_library = SDL_LoadObject(libX11XCBLibraryName);
+        if(!videoData->vulkan_xlib_xcb_library)
+            goto fail;
+        videoData->vulkan_XGetXCBConnection =
+            SDL_LoadFunction(videoData->vulkan_xlib_xcb_library, "XGetXCBConnection");
+        if(!videoData->vulkan_XGetXCBConnection)
+        {
+            SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
+            goto fail;
+        }
+    }
+    return 0;
+
+fail:
+    SDL_UnloadObject(_this->vulkan_config.loader_handle);
+    _this->vulkan_config.loader_handle = NULL;
+    return -1;
+}
+
+void X11_Vulkan_UnloadLibrary(_THIS)
+{
+    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+    if(_this->vulkan_config.loader_handle)
+    {
+        if(videoData->vulkan_xlib_xcb_library)
+            SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
+        SDL_UnloadObject(_this->vulkan_config.loader_handle);
+        _this->vulkan_config.loader_handle = NULL;
+    }
+}
+
+SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
+                                          SDL_Window *window,
+                                          unsigned *count,
+                                          const char **names)
+{
+    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+    if(!_this->vulkan_config.loader_handle)
+    {
+        SDL_SetError("Vulkan is not loaded");
+        return SDL_FALSE;
+    }
+    if(videoData->vulkan_xlib_xcb_library)
+    {
+        static const char *const extensionsForXCB[] = {
+            VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+        };
+        return SDL_Vulkan_GetInstanceExtensions_Helper(
+            count, names, SDL_arraysize(extensionsForXCB), extensionsForXCB);
+    }
+    else
+    {
+        static const char *const extensionsForXlib[] = {
+            VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+        };
+        return SDL_Vulkan_GetInstanceExtensions_Helper(
+            count, names, SDL_arraysize(extensionsForXlib), extensionsForXlib);
+    }
+}
+
+SDL_bool X11_Vulkan_CreateSurface(_THIS,
+                                  SDL_Window *window,
+                                  SDL_vulkanInstance instance,
+                                  SDL_vulkanSurface *surface)
+{
+    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+    if(!_this->vulkan_config.loader_handle)
+    {
+        SDL_SetError("Vulkan is not loaded");
+        return SDL_FALSE;
+    }
+    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+    if(videoData->vulkan_xlib_xcb_library)
+    {
+        PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR =
+            (PFN_vkCreateXcbSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
+                                                             "vkCreateXcbSurfaceKHR");
+        VkXcbSurfaceCreateInfoKHR createInfo = {};
+        VkResult result;
+        if(!vkCreateXcbSurfaceKHR)
+        {
+            SDL_SetError("Vulkan instance does not have " VK_KHR_XCB_SURFACE_EXTENSION_NAME
+                         " extension");
+            return SDL_FALSE;
+        }
+        createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+        createInfo.connection = videoData->vulkan_XGetXCBConnection(videoData->display);
+        if(!createInfo.connection)
+        {
+            SDL_SetError("XGetXCBConnection failed");
+            return SDL_FALSE;
+        }
+        createInfo.window = (xcb_window_t)windowData->xwindow;
+        result = vkCreateXcbSurfaceKHR(instance, &createInfo, NULL, (VkSurfaceKHR *)surface);
+        if(result != VK_SUCCESS)
+        {
+            SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+            return SDL_FALSE;
+        }
+        return SDL_TRUE;
+    }
+    else
+    {
+        PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
+            (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
+                                                              "vkCreateXlibSurfaceKHR");
+        VkXlibSurfaceCreateInfoKHR createInfo = {};
+        VkResult result;
+        if(!vkCreateXlibSurfaceKHR)
+        {
+            SDL_SetError("Vulkan instance does not have " VK_KHR_XLIB_SURFACE_EXTENSION_NAME
+                         " extension");
+            return SDL_FALSE;
+        }
+        createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+        createInfo.dpy = videoData->display;
+        createInfo.window = (xcb_window_t)windowData->xwindow;
+        result = vkCreateXlibSurfaceKHR(instance, &createInfo, NULL, (VkSurfaceKHR *)surface);
+        if(result != VK_SUCCESS)
+        {
+            SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+            return SDL_FALSE;
+        }
+        return SDL_TRUE;
+    }
+}
+
+#endif
+
+#endif
diff -r fd24ec69f7b8 -r 5046b8390345 src/video/x11/SDL_x11vulkan.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_x11vulkan.h Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,45 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 Sam Lantinga <[hidden email]>
+
+  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.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef _SDL_x11vulkan_h
+#define _SDL_x11vulkan_h
+
+#include "../SDL_vulkan.h"
+
+#if SDL_VULKAN_SUPPORTED
+
+int X11_Vulkan_LoadLibrary(_THIS, const char *path);
+void X11_Vulkan_UnloadLibrary(_THIS);
+SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
+                                          SDL_Window *window,
+                                          unsigned *count,
+                                          const char **names);
+SDL_bool X11_Vulkan_CreateSurface(_THIS,
+                                  SDL_Window *window,
+                                  SDL_vulkanInstance instance,
+                                  SDL_vulkanSurface *surface);
+
+#endif
+
+#endif /* _SDL_x11vulkan_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org