vulkan: Initial Vulkan support!

This work was done by Jacob Lifshay and Mark Callow; I'm just merging it
into revision control.
This commit is contained in:
Ryan C. Gordon
2017-08-27 22:15:57 -04:00
parent 8e7998e19d
commit 25e3a1ec90
60 changed files with 5456 additions and 80 deletions

View File

@@ -26,6 +26,7 @@
#include "SDL_messagebox.h"
#include "SDL_shape.h"
#include "SDL_thread.h"
#include "SDL_vulkan.h"
/* The SDL video driver */
@@ -260,6 +261,16 @@ struct SDL_VideoDevice
int (*GL_SwapWindow) (_THIS, SDL_Window * window);
void (*GL_DeleteContext) (_THIS, SDL_GLContext context);
/* * * */
/*
* Vulkan support
*/
int (*Vulkan_LoadLibrary) (_THIS, const char *path);
void (*Vulkan_UnloadLibrary) (_THIS);
SDL_bool (*Vulkan_GetInstanceExtensions) (_THIS, SDL_Window *window, unsigned *count, const char **names);
SDL_bool (*Vulkan_CreateSurface) (_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface);
void (*Vulkan_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h);
/* * * */
/*
* Event manager functions
@@ -348,6 +359,17 @@ struct SDL_VideoDevice
SDL_TLSID current_glwin_tls;
SDL_TLSID current_glctx_tls;
/* * * */
/* Data used by the Vulkan drivers */
struct
{
void *vkGetInstanceProcAddr;
void *vkEnumerateInstanceExtensionProperties;
int loader_loaded;
char loader_path[256];
void *loader_handle;
} vulkan_config;
/* * * */
/* Data private to this driver */
void *driverdata;

View File

@@ -1329,7 +1329,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
}
#define CREATE_FLAGS \
(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN )
(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN)
static void
SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
@@ -1384,7 +1384,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
/* Some platforms have OpenGL enabled by default */
#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
if (!_this->is_dummy) {
if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) {
flags |= SDL_WINDOW_OPENGL;
}
#endif
@@ -1398,6 +1398,25 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
}
}
if(flags & SDL_WINDOW_VULKAN)
{
if(!_this->Vulkan_CreateSurface)
{
SDL_SetError("Vulkan support is either not configured in SDL "
"or not available in video driver");
return NULL;
}
if(flags & SDL_WINDOW_OPENGL)
{
SDL_SetError("Vulkan and OpenGL not supported on same window");
return NULL;
}
if(SDL_Vulkan_LoadLibrary(NULL) < 0)
{
return NULL;
}
}
/* Unless the user has specified the high-DPI disabling hint, respect the
* SDL_WINDOW_ALLOW_HIGHDPI flag.
*/
@@ -1573,6 +1592,16 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
}
}
if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) {
SDL_SetError("Can't change SDL_WINDOW_VULKAN window flag");
return -1;
}
if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("Vulkan and OpenGL not supported on same window");
return -1;
}
window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
window->last_fullscreen_flags = window->flags;
window->is_destroying = SDL_FALSE;
@@ -2632,6 +2661,9 @@ SDL_DestroyWindow(SDL_Window * window)
if (window->flags & SDL_WINDOW_OPENGL) {
SDL_GL_UnloadLibrary();
}
if (window->flags & SDL_WINDOW_VULKAN) {
SDL_Vulkan_UnloadLibrary();
}
display = SDL_GetDisplayForWindow(window);
if (display->fullscreen_window == window) {
@@ -3946,4 +3978,128 @@ void SDL_OnApplicationDidBecomeActive(void)
}
}
#define NOT_A_VULKAN_WINDOW "The specified window isn't a Vulkan window."
int SDL_Vulkan_LoadLibrary(const char *path)
{
int retval;
if(!_this)
{
SDL_UninitializedVideo();
return -1;
}
if(_this->vulkan_config.loader_loaded)
{
if(path && SDL_strcmp(path, _this->vulkan_config.loader_path) != 0)
{
return SDL_SetError("Vulkan loader library already loaded");
}
retval = 0;
}
else
{
if(!_this->Vulkan_LoadLibrary)
{
return SDL_SetError("No Vulkan support in video driver");
}
retval = _this->Vulkan_LoadLibrary(_this, path);
}
if(retval == 0)
{
_this->vulkan_config.loader_loaded++;
}
return retval;
}
void *SDL_Vulkan_GetVkGetInstanceProcAddr(void)
{
if(!_this)
{
SDL_UninitializedVideo();
return NULL;
}
if(!_this->vulkan_config.loader_loaded)
{
SDL_SetError("No Vulkan loader has been loaded");
}
return _this->vulkan_config.vkGetInstanceProcAddr;
}
void SDL_Vulkan_UnloadLibrary(void)
{
if(!_this)
{
SDL_UninitializedVideo();
return;
}
if(_this->vulkan_config.loader_loaded > 0)
{
if(--_this->vulkan_config.loader_loaded > 0)
{
return;
}
if(_this->Vulkan_UnloadLibrary)
{
_this->Vulkan_UnloadLibrary(_this);
}
}
}
SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, const char **names)
{
CHECK_WINDOW_MAGIC(window, SDL_FALSE);
if(!(window->flags & SDL_WINDOW_VULKAN))
{
SDL_SetError(NOT_A_VULKAN_WINDOW);
return SDL_FALSE;
}
if(!count)
{
SDL_SetError("invalid count");
return SDL_FALSE;
}
return _this->Vulkan_GetInstanceExtensions(_this, window, count, names);
}
SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
CHECK_WINDOW_MAGIC(window, SDL_FALSE);
if(!(window->flags & SDL_WINDOW_VULKAN))
{
SDL_SetError(NOT_A_VULKAN_WINDOW);
return SDL_FALSE;
}
if(!instance)
{
SDL_SetError("invalid instance");
return SDL_FALSE;
}
if(!surface)
{
SDL_SetError("invalid surface");
return SDL_FALSE;
}
return _this->Vulkan_CreateSurface(_this, window, instance, surface);
}
void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h)
{
CHECK_WINDOW_MAGIC(window,);
if (_this->Vulkan_GetDrawableSize) {
_this->Vulkan_GetDrawableSize(_this, window, w, h);
} else {
SDL_GetWindowSize(window, w, h);
}
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,80 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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.
*/
#ifndef _SDL_vulkan_internal_h
#define _SDL_vulkan_internal_h
#include "../SDL_internal.h"
#include "SDL_stdinc.h"
#if defined(SDL_LOADSO_DISABLED)
#undef SDL_VIDEO_VULKAN_SURFACE
#define SDL_VIDEO_VULKAN_SURFACE 0
#endif
#if SDL_VIDEO_DRIVER_ANDROID
#define VK_USE_PLATFORM_ANDROID_KHR
#endif
#if SDL_VIDEO_DRIVER_COCOA
#define VK_USE_PLATFORM_MACOS_MVK
#endif
#if SDL_VIDEO_DRIVER_MIR
#define VK_USE_PLATFORM_MIR_KHR
#endif
#if SDL_VIDEO_DRIVER_UIKIT
#define VK_USE_PLATFORM_IOS_MVK
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
#define VK_USE_PLATFORM_WAYLAND_KHR
#endif
#if SDL_VIDEO_DRIVER_WINDOWS
#define VK_USE_PLATFORM_WIN32_KHR
#endif
#if SDL_VIDEO_DRIVER_X11
#define VK_USE_PLATFORM_XLIB_KHR
#define VK_USE_PLATFORM_XCB_KHR
#endif
#if SDL_VIDEO_VULKAN_SURFACE
/* Need vulkan.h for the following declarations. Must ensure the first
* inclusion of vulkan has the appropriate USE_PLATFORM defined, hence
* the above. */
#define VK_NO_PROTOTYPES
#include "vulkan/vulkan.h"
extern const char *SDL_Vulkan_GetResultString(VkResult result);
extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
Uint32 *extensionCount); /* free returned list with SDL_free */
/* Implements functionality of SDL_Vulkan_GetInstanceExtensions for a list of
* names passed in nameCount and names. */
extern SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
const char **userNames,
unsigned nameCount,
const char *const *names);
#endif
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,191 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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.
*/
#include "../SDL_internal.h"
#include "SDL_vulkan_internal.h"
#include "SDL_error.h"
#if SDL_VIDEO_VULKAN_SURFACE
/* Based on the headers found in
* https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers
*/
#if VK_HEADER_VERSION < 22
enum
{
VK_ERROR_FRAGMENTED_POOL = -12,
};
#endif
#if VK_HEADER_VERSION < 38
enum {
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
};
#endif
const char *SDL_Vulkan_GetResultString(VkResult result)
{
switch((int)result)
{
case VK_SUCCESS:
return "VK_SUCCESS";
case VK_NOT_READY:
return "VK_NOT_READY";
case VK_TIMEOUT:
return "VK_TIMEOUT";
case VK_EVENT_SET:
return "VK_EVENT_SET";
case VK_EVENT_RESET:
return "VK_EVENT_RESET";
case VK_INCOMPLETE:
return "VK_INCOMPLETE";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_INITIALIZATION_FAILED:
return "VK_ERROR_INITIALIZATION_FAILED";
case VK_ERROR_DEVICE_LOST:
return "VK_ERROR_DEVICE_LOST";
case VK_ERROR_MEMORY_MAP_FAILED:
return "VK_ERROR_MEMORY_MAP_FAILED";
case VK_ERROR_LAYER_NOT_PRESENT:
return "VK_ERROR_LAYER_NOT_PRESENT";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "VK_ERROR_EXTENSION_NOT_PRESENT";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "VK_ERROR_FEATURE_NOT_PRESENT";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "VK_ERROR_INCOMPATIBLE_DRIVER";
case VK_ERROR_TOO_MANY_OBJECTS:
return "VK_ERROR_TOO_MANY_OBJECTS";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
case VK_ERROR_FRAGMENTED_POOL:
return "VK_ERROR_FRAGMENTED_POOL";
case VK_ERROR_SURFACE_LOST_KHR:
return "VK_ERROR_SURFACE_LOST_KHR";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
case VK_SUBOPTIMAL_KHR:
return "VK_SUBOPTIMAL_KHR";
case VK_ERROR_OUT_OF_DATE_KHR:
return "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "VK_ERROR_VALIDATION_FAILED_EXT";
case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
case VK_ERROR_INVALID_SHADER_NV:
return "VK_ERROR_INVALID_SHADER_NV";
case VK_RESULT_MAX_ENUM:
case VK_RESULT_RANGE_SIZE:
break;
}
if(result < 0)
return "VK_ERROR_<Unknown>";
return "VK_<Unknown>";
}
VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
Uint32 *extensionCount)
{
Uint32 count = 0;
VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
VkExtensionProperties *retval;
if(result == VK_ERROR_INCOMPATIBLE_DRIVER)
{
SDL_SetError(
"You probably don't have a working Vulkan driver installed: getting Vulkan "
"extensions failed: vkEnumerateInstanceExtensionProperties returned %s(%d)",
SDL_Vulkan_GetResultString(result),
(int)result);
return NULL;
}
else if(result != VK_SUCCESS)
{
SDL_SetError(
"Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
"%s(%d)",
SDL_Vulkan_GetResultString(result),
(int)result);
return NULL;
}
if(count == 0)
{
retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null
if(!retval)
{
SDL_OutOfMemory();
return NULL;
}
*extensionCount = 0;
}
retval = SDL_calloc(count, sizeof(VkExtensionProperties));
if(!retval)
{
SDL_OutOfMemory();
return NULL;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval);
if(result != VK_SUCCESS)
{
SDL_SetError(
"Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
"%s(%d)",
SDL_Vulkan_GetResultString(result),
(int)result);
SDL_free(retval);
return NULL;
}
*extensionCount = count;
return retval;
}
SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
const char **userNames,
unsigned nameCount,
const char *const *names)
{
if(userNames)
{
unsigned int i;
if(*userCount != nameCount)
{
SDL_SetError(
"Count doesn't match count from previous call of SDL_Vulkan_GetInstanceExtensions");
return SDL_FALSE;
}
for(i = 0; i < nameCount; i++)
{
userNames[i] = names[i];
}
}
else
{
*userCount = nameCount;
}
return SDL_TRUE;
}
#endif

View File

@@ -40,6 +40,7 @@
#include "SDL_androidmouse.h"
#include "SDL_androidtouch.h"
#include "SDL_androidwindow.h"
#include "SDL_androidvulkan.h"
#define ANDROID_VID_DRIVER_NAME "Android"
@@ -132,6 +133,13 @@ Android_CreateDevice(int devindex)
device->GL_SwapWindow = Android_GLES_SwapWindow;
device->GL_DeleteContext = Android_GLES_DeleteContext;
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface;
#endif
/* Screensaver */
device->SuspendScreenSaver = Android_SuspendScreenSaver;

View File

@@ -0,0 +1,174 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidvideo.h"
#include "SDL_androidwindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_androidvulkan.h"
#include "SDL_syswm.h"
int Android_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasAndroidSurfaceExtension = 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->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(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_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasAndroidSurfaceExtension = 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(!hasAndroidSurfaceExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void Android_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForAndroid[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_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(extensionsForMir),
extensionsForAndroid);
}
SDL_bool Android_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
(PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateAndroidSurfaceKHR");
VkAndroidSurfaceCreateInfoKHR createInfo = {};
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateAndroidSurfaceKHR)
{
SDL_SetError(VK_KHR_Android_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_Android_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.window = windowData->native_window;
result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_androidvulkan_h
#define _SDL_androidvulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_ANDROID
int Android_Vulkan_LoadLibrary(_THIS, const char *path);
void Android_Vulkan_UnloadLibrary(_THIS);
SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool Android_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* _SDL_androidvulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,61 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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 Mark Callow, www.edgewise-consulting.com.
*
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
* how to add a CAMetalLayer backed view.
*/
#ifndef _SDL_cocoametalview_h
#define _SDL_cocoametalview_h
#import "../SDL_sysvideo.h"
#import "SDL_cocoawindow.h"
#import <Cocoa/Cocoa.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#define METALVIEW_TAG 255
@interface SDL_cocoametalview : NSView {
NSInteger _tag;
bool _useHighDPI;
}
- (instancetype)initWithFrame:(NSRect)frame
useHighDPI:(bool)useHighDPI;
/* Override superclass tag so this class can set it. */
@property (assign, readonly) NSInteger tag;
@end
SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
void Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
#endif /* _SDL_cocoametalview_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,124 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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 Mark Callow, www.edgewise-consulting.com.
*
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
* how to add a CAMetalLayer backed view.
*/
/* this is (currently) only used with Vulkan. Remove this #if when that changes! */
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
#import "SDL_cocoametalview.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include <dlfcn.h>
@implementation SDL_cocoametalview
/* The synthesized getter should be called by super's viewWithTag. */
@synthesize tag = _tag;
/* Return a Metal-compatible layer. */
+ (Class)layerClass
{
return [CAMetalLayer class];
}
/* Indicate the view wants to draw using a backing layer instead of drawRect. */
-(BOOL) wantsUpdateLayer { return YES; }
/* When the wantsLayer property is set to YES, this method will be invoked to
* return a layer instance.
*/
-(CALayer*) makeBackingLayer { return [self.class.layerClass layer]; }
- (instancetype)initWithFrame:(NSRect)frame
useHighDPI:(bool)useHighDPI
{
if ((self = [super initWithFrame:frame])) {
/* Allow resize. */
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
_tag = METALVIEW_TAG;
_useHighDPI = useHighDPI;
[self updateDrawableSize];
}
return self;
}
/* Set the size of the metal drawables when the view is resized. */
- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
[super resizeSubviewsWithOldSize:oldSize];
[self updateDrawableSize];
}
- (void)updateDrawableSize
{
if (_useHighDPI) {
NSSize size = [self convertRectToBacking:[self bounds]].size;
/* Isn't there a better way to convert from NSSize to CGSize? */
CGSize cgsize = *(CGSize*)&size;
((CAMetalLayer *) self.layer).drawableSize = cgsize;
}
}
@end
SDL_cocoametalview*
Cocoa_Mtl_AddMetalView(SDL_Window* window)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
NSView *view = data->nswindow.contentView;
SDL_cocoametalview *metalview
= [[SDL_cocoametalview alloc] initWithFrame:view.frame
useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)];
[view addSubview:metalview];
return metalview;
}
void
Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
{
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
NSView *view = data->nswindow.contentView;
SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
if (metalview) {
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
assert(layer != NULL);
if (w)
*w = layer.drawableSize.width;
if (h)
*h = layer.drawableSize.height;
}
}
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -26,6 +26,7 @@
#include "SDL_endian.h"
#include "SDL_cocoavideo.h"
#include "SDL_cocoashape.h"
#include "SDL_cocoavulkan.h"
#include "SDL_assert.h"
/* Initialization/Query functions */
@@ -122,6 +123,14 @@ Cocoa_CreateDevice(int devindex)
device->GL_DeleteContext = Cocoa_GL_DeleteContext;
#endif
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = Cocoa_Vulkan_CreateSurface;
device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
#endif
device->StartTextInput = Cocoa_StartTextInput;
device->StopTextInput = Cocoa_StopTextInput;
device->SetTextInputRect = Cocoa_SetTextInputRect;

View File

@@ -0,0 +1,55 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_cocoavulkan_h
#define _SDL_cocoavulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path);
void Cocoa_Vulkan_UnloadLibrary(_THIS);
SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
#endif
#endif /* _SDL_cocoavulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,217 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
#include "SDL_cocoavideo.h"
#include "SDL_cocoawindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_cocoametalview.h"
#include "SDL_cocoavulkan.h"
#include "SDL_syswm.h"
#include <dlfcn.h>
#define DEFAULT_MOLTENVK "libMoltenVK.dylib"
/* Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF. */
#define DEFAULT_HANDLE RTLD_DEFAULT
int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasMacOSSurfaceExtension = SDL_FALSE;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
if(_this->vulkan_config.loader_handle)
{
SDL_SetError("MoltenVK/Vulkan already loaded");
return -1;
}
/* Load the Vulkan loader library */
if(!path)
path = SDL_getenv("SDL_VULKAN_LIBRARY");
if(!path)
{
/* MoltenVK framework, currently, v0.17.0, has a static library and is
* the recommended way to use the package. There is likely no object to
* load. */
vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
"vkGetInstanceProcAddr");
}
if(vkGetInstanceProcAddr)
{
_this->vulkan_config.loader_handle = DEFAULT_HANDLE;
}
else
{
if (!path)
{
/* Look for the .dylib packaged with the application instead. */
path = DEFAULT_MOLTENVK;
}
_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)
{
SDL_SetError("Failed to find %s in either executable or %s: %s",
"vkGetInstanceProcAddr",
DEFAULT_MOLTENVK,
(const char *) dlerror());
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_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasMacOSSurfaceExtension = SDL_TRUE;
}
SDL_free(extensions);
if(!hasSurfaceExtension)
{
SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
VK_KHR_SURFACE_EXTENSION_NAME " extension");
goto fail;
}
else if(!hasMacOSSurfaceExtension)
{
SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void Cocoa_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE)
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForCocoa[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_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(extensionsForCocoa),
extensionsForCocoa);
}
SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
(PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateMacOSSurfaceMVK");
VkMacOSSurfaceCreateInfoMVK createInfo = {};
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateMacOSSurfaceMVK)
{
SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.pView = Cocoa_Mtl_AddMetalView(window);
result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
Cocoa_Mtl_GetDrawableSize(window, w, h);
}
#endif
/* vim: set ts=4 sw=4 expandtab: */

View File

@@ -36,6 +36,7 @@
#include "SDL_mirmouse.h"
#include "SDL_miropengl.h"
#include "SDL_mirvideo.h"
#include "SDL_mirvulkan.h"
#include "SDL_mirdyn.h"
@@ -232,6 +233,13 @@ MIR_CreateDevice(int device_index)
device->ShowMessageBox = NULL;
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = MIR_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = MIR_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = MIR_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = MIR_Vulkan_CreateSurface;
#endif
return device;
}

View File

@@ -28,6 +28,7 @@
#include <EGL/egl.h>
#include <mir_toolkit/mir_client_library.h>
#include "SDL_stdinc.h"
typedef struct MIR_Window MIR_Window;

View File

@@ -0,0 +1,175 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_MIR
#include "SDL_mirvideo.h"
#include "SDL_mirwindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_mirvulkan.h"
#include "SDL_syswm.h"
int MIR_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasMIRSurfaceExtension = 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->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(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_MIR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasMIRSurfaceExtension = 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(!hasMIRSurfaceExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_MIR_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void MIR_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForMir[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_MIR_SURFACE_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(extensionsForMir),
extensionsForMir);
}
SDL_bool MIR_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
MIR_Window *windowData = (MIR_Window *)window->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR =
(PFN_vkCreateMirSurfaceKHR)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateMirSurfaceKHR");
VkMirSurfaceCreateInfoKHR createInfo = {};
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateMirSurfaceKHR)
{
SDL_SetError(VK_KHR_MIR_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.connection = windowData->mir_data->connection;
createInfo.mirSurface = windowData->window;
result = vkCreateMirSurfaceKHR(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateMirSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif
/* vim: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_mirvulkan_h
#define _SDL_mirvulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_MIR
int MIR_Vulkan_LoadLibrary(_THIS, const char *path);
void MIR_Vulkan_UnloadLibrary(_THIS);
SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool MIR_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* _SDL_mirvulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,53 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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 Mark Callow, www.edgewise-consulting.com.
*
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
* how to add a CAMetalLayer backed view.
*/
#ifndef _SDL_uikitmetalview_h
#define _SDL_uikitmetalview_h
#import "../SDL_sysvideo.h"
#import "SDL_uikitwindow.h"
#import <UIKit/UIKit.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#define METALVIEW_TAG 255
@interface SDL_uikitmetalview : UIView
- (instancetype)initWithFrame:(CGRect)frame
scale:(CGFloat)scale
tag:(int)tag;
@end
SDL_uikitmetalview* UIKit_Mtl_AddMetalView(SDL_Window* window);
void UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
#endif /* _SDL_uikitmetalview_h */

View File

@@ -0,0 +1,146 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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 Mark Callow, www.edgewise-consulting.com.
*
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
* how to add a CAMetalLayer backed view.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
#import "../SDL_sysvideo.h"
#import "SDL_uikitwindow.h"
#import "SDL_uikitmetalview.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include <dlfcn.h>
static void* loader_handle;
@implementation SDL_uikitmetalview
/* Returns a Metal-compatible layer. */
+ (Class)layerClass
{
return [CAMetalLayer class];
}
- (instancetype)initWithFrame:(CGRect)frame
scale:(CGFloat)scale
tag:(int)tag
{
if ((self = [super initWithFrame:frame])) {
/* Resize properly when rotated. */
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
/* Set the appropriate scale (for retina display support) */
self.contentScaleFactor = scale;
self.tag = tag;
[self updateDrawableSize];
}
return self;
}
/* Set the size of the metal drawables when the view is resized. */
- (void)layoutSubviews
{
[super layoutSubviews];
[self updateDrawableSize];
}
- (void)updateDrawableSize
{
CGSize size = self.bounds.size;
size.width *= self.contentScaleFactor;
size.height *= self.contentScaleFactor;
((CAMetalLayer *) self.layer).drawableSize = size;
}
@end
SDL_uikitmetalview*
UIKit_Mtl_AddMetalView(SDL_Window* window)
{
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
CGFloat scale = 1.0;
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
/* Set the scale to the natural scale factor of the screen - the
* backing dimensions of the Metal view will match the pixel
* dimensions of the screen rather than the dimensions in points.
*/
#ifdef __IPHONE_8_0
if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
scale = data.uiwindow.screen.nativeScale;
} else
#endif
{
scale = data.uiwindow.screen.scale;
}
}
SDL_uikitmetalview *metalview
= [[SDL_uikitmetalview alloc] initWithFrame:view.frame
scale:scale
tag:METALVIEW_TAG];
#if 1
[view addSubview:metalview];
#else
/* Sets this view as the controller's view, and adds the view to
* the window hierarchy.
*
* Left here for information. Not used because I suspect that for correct
* operation it will be necesary to copy everything from the window's
* current SDL_uikitview instance to the SDL_uikitview portion of the
* SDL_metalview. The latter would be derived from SDL_uikitview rather
* than UIView. */
[metalview setSDLWindow:window];
#endif
return metalview;
}
void
UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
{
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
if (metalview) {
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
assert(layer != NULL);
if (w)
*w = layer.drawableSize.width;
if (h)
*h = layer.drawableSize.height;
} else
SDL_GetWindowSize(window, w, h);
}
#endif

View File

@@ -37,6 +37,7 @@
#include "SDL_uikitwindow.h"
#include "SDL_uikitopengles.h"
#include "SDL_uikitclipboard.h"
#include "SDL_uikitvulkan.h"
#define UIKITVID_DRIVER_NAME "uikit"
@@ -123,6 +124,15 @@ UIKit_CreateDevice(int devindex)
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
device->free = UIKit_DeleteDevice;
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions
= UIKit_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = UIKit_Vulkan_CreateSurface;
device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize;
#endif
device->gl_config.accelerated = 1;
return device;

View File

@@ -0,0 +1,54 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_uikitvulkan_h
#define _SDL_uikitvulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
int UIKit_Vulkan_LoadLibrary(_THIS, const char *path);
void UIKit_Vulkan_UnloadLibrary(_THIS);
SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
#endif
#endif /* _SDL_uikitvulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,221 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
#include "SDL_uikitvideo.h"
#include "SDL_uikitwindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_uikitvulkan.h"
#include "SDL_uikitmetalview.h"
#include "SDL_syswm.h"
#include <dlfcn.h>
#define DEFAULT_MOLTENVK "libMoltenVK.dylib"
/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future
* proofing. */
#define DEFAULT_HANDLE RTLD_DEFAULT
int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasIOSSurfaceExtension = SDL_FALSE;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
if(_this->vulkan_config.loader_handle)
return SDL_SetError("MoltenVK/Vulkan already loaded");
/* Load the Vulkan loader library */
if(!path)
path = SDL_getenv("SDL_VULKAN_LIBRARY");
if(!path)
{
/* MoltenVK framework, currently, v0.17.0, has a static library and is
* the recommended way to use the package. There is likely no object to
* load. */
vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
"vkGetInstanceProcAddr");
}
if(vkGetInstanceProcAddr)
{
_this->vulkan_config.loader_handle = DEFAULT_HANDLE;
}
else
{
if (!path)
{
/* Look for the .dylib packaged with the application instead. */
path = DEFAULT_MOLTENVK;
}
_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)
{
SDL_SetError("Failed to find %s in either executable or %s: %s",
"vkGetInstanceProcAddr",
DEFAULT_MOLTENVK,
(const char *) dlerror());
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)
{
SDL_SetError("No vkEnumerateInstanceExtensionProperties found.");
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_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasIOSSurfaceExtension = SDL_TRUE;
}
SDL_free(extensions);
if(!hasSurfaceExtension)
{
SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
VK_KHR_SURFACE_EXTENSION_NAME " extension");
goto fail;
}
else if(!hasIOSSurfaceExtension)
{
SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void UIKit_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE)
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForUIKit[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_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(extensionsForUIKit),
extensionsForUIKit);
}
SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK =
(PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateIOSSurfaceMVK");
VkIOSSurfaceCreateInfoMVK createInfo = {};
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateIOSSurfaceMVK)
{
SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.pView = (__bridge void *)UIKit_Mtl_AddMetalView(window);
result = vkCreateIOSSurfaceMVK(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
UIKit_Mtl_GetDrawableSize(window, w, h);
}
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -35,6 +35,7 @@
#include "SDL_waylandmouse.h"
#include "SDL_waylandtouch.h"
#include "SDL_waylandclipboard.h"
#include "SDL_waylandvulkan.h"
#include <sys/types.h>
#include <unistd.h>
@@ -181,6 +182,13 @@ Wayland_CreateDevice(int devindex)
device->GetClipboardText = Wayland_GetClipboardText;
device->HasClipboardText = Wayland_HasClipboardText;
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface;
#endif
device->free = Wayland_DeleteDevice;
return device;

View File

@@ -0,0 +1,175 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WAYLAND
#include "SDL_waylandvideo.h"
#include "SDL_waylandwindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_waylandvulkan.h"
#include "SDL_syswm.h"
int Wayland_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasWaylandSurfaceExtension = 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->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(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_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasWaylandSurfaceExtension = 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(!hasWaylandSurfaceExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void Wayland_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForWayland[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_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(extensionsForWayland),
extensionsForWayland);
}
SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR =
(PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateWaylandSurfaceKHR");
VkWaylandSurfaceCreateInfoKHR createInfo = {};
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateWaylandSurfaceKHR)
{
SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.display = windowData->waylandData->display;
createInfo.surface = windowData->surface;
result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif
/* vim: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_waylandvulkan_h
#define _SDL_waylandvulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WAYLAND
int Wayland_Vulkan_LoadLibrary(_THIS, const char *path);
void Wayland_Vulkan_UnloadLibrary(_THIS);
SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* _SDL_waylandvulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -33,6 +33,7 @@
#include "SDL_windowsvideo.h"
#include "SDL_windowsframebuffer.h"
#include "SDL_windowsshape.h"
#include "SDL_windowsvulkan.h"
/* Initialization/Query functions */
static int WIN_VideoInit(_THIS);
@@ -190,6 +191,13 @@ WIN_CreateDevice(int devindex)
device->GL_SwapWindow = WIN_GLES_SwapWindow;
device->GL_DeleteContext = WIN_GLES_DeleteContext;
#endif
#if SDL_VIDEO_VULKAN_SURFACE
device->Vulkan_LoadLibrary = WIN_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = WIN_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface;
#endif
device->StartTextInput = WIN_StartTextInput;
device->StopTextInput = WIN_StopTextInput;
device->SetTextInputRect = WIN_SetTextInputRect;

View File

@@ -0,0 +1,176 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WINDOWS
#include "SDL_windowsvideo.h"
#include "SDL_windowswindow.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_windowsvulkan.h"
#include "SDL_syswm.h"
int WIN_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
Uint32 i;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasWin32SurfaceExtension = 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 = "vulkan-1.dll";
_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_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasWin32SurfaceExtension = 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(!hasWin32SurfaceExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void WIN_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForWin32[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_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(extensionsForWin32),
extensionsForWin32);
}
SDL_bool WIN_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
(PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(
(VkInstance)instance,
"vkCreateWin32SurfaceKHR");
VkWin32SurfaceCreateInfoKHR createInfo;
VkResult result;
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if(!vkCreateWin32SurfaceKHR)
{
SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.hinstance = windowData->hinstance;
createInfo.hwnd = windowData->hwnd;
result = vkCreateWin32SurfaceKHR(instance, &createInfo,
NULL, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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 Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_windowsvulkan_h
#define _SDL_windowsvulkan_h
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WINDOWS
int WIN_Vulkan_LoadLibrary(_THIS, const char *path);
void WIN_Vulkan_UnloadLibrary(_THIS);
SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
SDL_bool WIN_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* _SDL_windowsvulkan_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -40,6 +40,8 @@
#include "SDL_x11opengles.h"
#endif
#include "SDL_x11vulkan.h"
/* Initialization/Query functions */
static int X11_VideoInit(_THIS);
static void X11_VideoQuit(_THIS);
@@ -107,6 +109,9 @@ static void
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);
}
@@ -291,6 +296,13 @@ X11_CreateDevice(int devindex)
device->free = X11_DeleteDevice;
#if SDL_VIDEO_VULKAN_SURFACE
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;
}

View File

@@ -68,6 +68,7 @@
#include "SDL_x11mouse.h"
#include "SDL_x11opengl.h"
#include "SDL_x11window.h"
#include "SDL_x11vulkan.h"
/* Private display data */
@@ -140,6 +141,12 @@ typedef struct SDL_VideoData
KeyCode filter_code;
Time filter_time;
#if SDL_VIDEO_VULKAN_SURFACE
/* 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);

View File

@@ -0,0 +1,239 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_X11
#include "SDL_x11video.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_x11vulkan.h"
#include <X11/Xlib.h>
//#include <xcb/xcb.h>
typedef uint32_t xcb_window_t;
typedef uint32_t xcb_visualid_t;
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;
Uint32 i;
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->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_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("Installed 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("Installed Vulkan doesn't implement either 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,
VkInstance instance,
VkSurfaceKHR *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(VK_KHR_XCB_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
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, 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(VK_KHR_XLIB_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
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, surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
}
#endif
/* vim: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,48 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_x11vulkan_h
#define _SDL_x11vulkan_h
#include "../SDL_vulkan_internal.h"
#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_X11
typedef struct xcb_connection_t xcb_connection_t;
typedef xcb_connection_t *(*PFN_XGetXCBConnection)(Display *dpy);
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,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* _SDL_x11vulkan_h */
/* vi: set ts=4 sw=4 expandtab: */