Skip to content

Instantly share code, notes, and snippets.

@programmerjake programmerjake/patch1.diff
Last active Mar 10, 2017

Embed
What would you like to do?
Patch adding Vulkan support to libsdl
# HG changeset patch
# User Jacob Lifshay <programmerjake@gmail.com>
# Date 1487661491 28800
# Mon Feb 20 23:18:11 2017 -0800
# Node ID fd24ec69f7b848894158a1c19f5d4b05b68145fa
# Parent 5a6206d1d6a27febe595acda020128686c59ad54
add basic framework for vulkan support
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 include/SDL_video.h
--- a/include/SDL_video.h Mon Feb 20 11:02:35 2017 -0800
+++ b/include/SDL_video.h Mon Feb 20 23:18:11 2017 -0800
@@ -116,7 +116,8 @@
SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */
SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */
SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */
- SDL_WINDOW_POPUP_MENU = 0x00080000 /**< window should be treated as a popup menu */
+ SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */
+ SDL_WINDOW_VULKAN = 0x10000000, /**< window usable with Vulkan *//* value matches Tizen's implementation */
} SDL_WindowFlags;
/**
@@ -224,6 +225,16 @@
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
} SDL_GLcontextReleaseFlag;
+/**
+ * \brief An opaque handle to a Vulkan instance.
+ */
+typedef void *SDL_vulkanInstance; /* VK_DEFINE_HANDLE(VkInstance) */
+
+/**
+ * \brief An opaque handle to a Vulkan surface.
+ */
+typedef Uint64 SDL_vulkanSurface; /* VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) */
+
/* Function prototypes */
@@ -870,7 +881,7 @@
* \param window The window which will be made transparent or opaque
* \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be
* clamped internally between 0.0f and 1.0f.
- *
+ *
* \return 0 on success, or -1 if setting the opacity isn't supported.
*
* \sa SDL_GetWindowOpacity()
@@ -897,7 +908,7 @@
*
* \param modal_window The window that should be modal
* \param parent_window The parent window
- *
+ *
* \return 0 on success, or -1 otherwise.
*/
extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window);
@@ -910,7 +921,7 @@
* obscured by other windows.
*
* \param window The window that should get the input focus
- *
+ *
* \return 0 on success, or -1 otherwise.
* \sa SDL_RaiseWindow()
*/
@@ -1207,6 +1218,134 @@
/* @} *//* OpenGL support functions */
+/**
+ * \name Vulkan support functions
+ *
+ * \note Designed to be compatible with Tizen's implementation of Vulkan in SDL
+ */
+/* @{ */
+
+/**
+ * \brief Dynamically load a Vulkan loader library.
+ *
+ * \param path The platform dependent Vulkan loader library name, or \c NULL to open the
+ * default Vulkan loader library.
+ *
+ * \return \c 0 on success, or \c -1 if the library couldn't be loaded.
+ *
+ * This should be done after initializing the video driver, but before
+ * creating any Vulkan windows. If no Vulkan loader library is loaded, the default
+ * library will be loaded upon creation of the first Vulkan window.
+ *
+ * \note If you do this, you need to retrieve all of the Vulkan functions used in
+ * your program from the dynamic library using \c SDL_Vulkan_GetVkGetInstanceProcAddr().
+ *
+ * \sa SDL_Vulkan_GetVkGetInstanceProcAddr()
+ * \sa SDL_Vulkan_UnloadLibrary()
+ */
+extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path);
+
+/**
+ * \brief Get the address of the \c vkGetInstanceProcAddr function.
+ */
+extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
+
+/**
+ * \brief Unload the Vulkan loader library previously loaded by \c SDL_Vulkan_LoadLibrary().
+ *
+ * \sa SDL_Vulkan_LoadLibrary()
+ */
+extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
+
+/**
+ * \brief Get the list of Vulkan instance extensions required to use \c SDL_Vulkan_CreateSurface().
+ *
+ * \param window Window for which the required Vulkan instance extensions should be retrieved
+ * \param count pointer to an \c unsigned related to the number of required Vulkan instance extensions
+ * \param names \c NULL or a pointer to an array to be filled with the required Vulkan instance extensions
+ *
+ * \return \c SDL_TRUE on success, \c SDL_FALSE on error.
+ *
+ * If \c names is \c NULL, then return the number of required Vulkan instance extensions in \c count.
+ * If \c names is not \c NULL, then store the names of the required Vulkan instance extensions in \c names.
+ *
+ * \note the returned list of extensions will contain VK_KHR_surface and zero or more platform specific extensions
+ *
+ * \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
+ *
+ * \code
+ * unsigned count;
+ * // get count of required extensions
+ * if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
+ * handle_error();
+ *
+ * static const char *const additionalExtensions[] =
+ * {
+ * VK_EXT_DEBUG_REPORT_EXTENSION_NAME, // example additional extension
+ * };
+ * size_t additionalExtensionsCount = sizeof(additionalExtensions) / sizeof(additionalExtensions[0]);
+ * size_t extensionCount = count + additionalExtensionsCount;
+ * const char **names = malloc(sizeof(const char *) * extensionCount);
+ * if(!names)
+ * handle_error();
+ *
+ * // don't change count here for compatibility with Tizen
+ *
+ * // get names of required extensions
+ * if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
+ * handle_error();
+ *
+ * // copy additional extensions after required extensions
+ * for(size_t i = 0; i < additionalExtensionsCount; i++)
+ * names[i + count] = additionalExtensions[i];
+ *
+ * VkInstanceCreateInfo instanceCreateInfo = {};
+ * instanceCreateInfo.enabledExtensionCount = extensionCount;
+ * instanceCreateInfo.ppEnabledExtensionNames = names;
+ * // fill in rest of instanceCreateInfo
+ *
+ * VkInstance instance;
+ * // create the Vulkan instance
+ * VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &instance);
+ * free(names);
+ * \endcode
+ *
+ * \sa SDL_Vulkan_CreateSurface()
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, const char **names);
+
+/**
+ * \brief Create a Vulkan surface for a window.
+ *
+ * \param window Window for which the Vulkan surface should be created
+ * \param instance Vulkan instance for which the Vulkan surface should be created
+ * \param surface pointer to the variable for storing the new Vulkan surface
+ *
+ * \return \c SDL_TRUE on success, \c SDL_FALSE on error.
+ *
+ * \code
+ * VkInstance instance;
+ * SDL_Window *window;
+ *
+ * // create instance and window
+ *
+ * // create the Vulkan surface
+ * VkSurfaceKHR surface;
+ * if(!SDL_Vulkan_CreateSurface(window, instance, (SDL_vulkanSurface *)&surface))
+ * handle_error();
+ * \endcode
+ *
+ * \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
+ *
+ * \note \c instance should have been created with the extensions returned by \c SDL_Vulkan_CreateSurface() enabled
+ *
+ * \sa SDL_Vulkan_GetInstanceExtensions()
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window, SDL_vulkanInstance instance, SDL_vulkanSurface *surface);
+
+/* @} *//* Vulkan support functions */
+
+
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/dynapi/SDL_dynapi_overrides.h
--- a/src/dynapi/SDL_dynapi_overrides.h Mon Feb 20 11:02:35 2017 -0800
+++ b/src/dynapi/SDL_dynapi_overrides.h Mon Feb 20 23:18:11 2017 -0800
@@ -623,3 +623,8 @@
#define SDL_JoystickGetType SDL_JoystickGetType_REAL
#define SDL_MemoryBarrierReleaseFunction SDL_MemoryBarrierReleaseFunction_REAL
#define SDL_MemoryBarrierAcquireFunction SDL_MemoryBarrierAcquireFunction_REAL
+#define SDL_Vulkan_LoadLibrary SDL_Vulkan_LoadLibrary_REAL
+#define SDL_Vulkan_GetVkGetInstanceProcAddr SDL_Vulkan_GetVkGetInstanceProcAddr_REAL
+#define SDL_Vulkan_UnloadLibrary SDL_Vulkan_UnloadLibrary_REAL
+#define SDL_Vulkan_GetInstanceExtensions SDL_Vulkan_GetInstanceExtensions_REAL
+#define SDL_Vulkan_CreateSurface SDL_Vulkan_CreateSurface_REAL
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/dynapi/SDL_dynapi_procs.h
--- a/src/dynapi/SDL_dynapi_procs.h Mon Feb 20 11:02:35 2017 -0800
+++ b/src/dynapi/SDL_dynapi_procs.h Mon Feb 20 23:18:11 2017 -0800
@@ -655,3 +655,8 @@
SDL_DYNAPI_PROC(SDL_JoystickType,SDL_JoystickGetType,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_MemoryBarrierReleaseFunction,(void),(),)
SDL_DYNAPI_PROC(void,SDL_MemoryBarrierAcquireFunction,(void),(),)
+SDL_DYNAPI_PROC(int,SDL_Vulkan_LoadLibrary,(const char *a),(a),return)
+SDL_DYNAPI_PROC(void*,SDL_Vulkan_GetVkGetInstanceProcAddr,(void),(),return)
+SDL_DYNAPI_PROC(void,SDL_Vulkan_UnloadLibrary,(void),(),)
+SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_GetInstanceExtensions,(SDL_Window *a, unsigned *b, const char **c),(a,b,c),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, SDL_vulkanInstance b, SDL_vulkanSurface *c),(a,b,c),return)
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/video/SDL_sysvideo.h
--- a/src/video/SDL_sysvideo.h Mon Feb 20 11:02:35 2017 -0800
+++ b/src/video/SDL_sysvideo.h Mon Feb 20 23:18:11 2017 -0800
@@ -262,6 +262,15 @@
/* * * */
/*
+ * 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, SDL_vulkanInstance instance, SDL_vulkanSurface *surface);
+
+ /* * * */
+ /*
* Event manager functions
*/
void (*PumpEvents) (_THIS);
@@ -347,6 +356,17 @@
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;
struct SDL_GLDriverData *gl_data;
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/video/SDL_video.c
--- a/src/video/SDL_video.c Mon Feb 20 11:02:35 2017 -0800
+++ b/src/video/SDL_video.c Mon Feb 20 23:18:11 2017 -0800
@@ -1321,7 +1321,7 @@
}
#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_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)
@@ -1376,7 +1376,7 @@
/* 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
@@ -1390,6 +1390,24 @@
}
}
+ if(flags & SDL_WINDOW_VULKAN)
+ {
+ if(!_this->Vulkan_CreateSurface)
+ {
+ SDL_SetError("No Vulkan support 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.
*/
@@ -1565,6 +1583,16 @@
}
}
+ 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;
@@ -3855,4 +3883,115 @@
SDL_sqrt((double)den2));
}
+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("The specified window isn't 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,
+ SDL_vulkanInstance instance,
+ SDL_vulkanSurface *surface)
+{
+ CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+ if(!(window->flags & SDL_WINDOW_VULKAN))
+ {
+ SDL_SetError("The specified window isn't 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);
+}
+
/* vi: set ts=4 sw=4 expandtab: */
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/video/SDL_vulkan.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_vulkan.c Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,169 @@
+/*
+ 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_vulkan.h"
+#include "SDL_error.h"
+
+#if SDL_VULKAN_SUPPORTED
+
+enum
+{
+ VK_ERROR_FRAGMENTED_POOL = -12,
+ VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
+};
+
+extern 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>";
+}
+
+extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
+ Uint32 *extensionCount)
+{
+ Uint32 count = 0;
+ VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
+ VkExtensionProperties *retval;
+ 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)
+ {
+ if(*userCount != nameCount)
+ {
+ SDL_SetError(
+ "count doesn't match count from previous call of SDL_Vulkan_GetInstanceExtensions");
+ return SDL_FALSE;
+ }
+ for(unsigned i = 0; i < nameCount; i++)
+ {
+ userNames[i] = names[i];
+ }
+ }
+ else
+ {
+ *userCount = nameCount;
+ }
+ return SDL_TRUE;
+}
+
+#endif
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/video/SDL_vulkan.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_vulkan.h Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,43 @@
+/*
+ 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_h
+#define _SDL_vulkan_h
+
+#include "SDL_vulkan_internal.h"
+
+#if SDL_VULKAN_SUPPORTED
+
+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
diff -r 5a6206d1d6a2 -r fd24ec69f7b8 src/video/SDL_vulkan_internal.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_vulkan_internal.h Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,466 @@
+/*
+ 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"
+
+// Android does not support Vulkan in native code using the "armeabi" ABI.
+#if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
+#define SDL_VULKAN_SUPPORTED 0
+#elif !(HAVE_STDDEF_H || HAVE_LIBC) || defined(SDL_LOADSO_DISABLED)
+#define SDL_VULKAN_SUPPORTED 0
+#else
+#define SDL_VULKAN_SUPPORTED 1
+#endif
+
+#if SDL_VIDEO_DRIVER_ANDROID
+#define VK_USE_PLATFORM_ANDROID_KHR
+#endif
+#if SDL_VIDEO_DRIVER_MIR
+#define VK_USE_PLATFORM_MIR_KHR
+#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_VULKAN_SUPPORTED
+
+/* this file is a trimmed version of vulkan/vk_platform.h */
+
+//
+// File: vk_platform.h
+//
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that Vulkan clients call Vulkan commands
+ * with the same calling conventions that the Vulkan implementation expects.
+ *
+ * VKAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * VKAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+ * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+ */
+#if defined(_WIN32)
+ // On Windows, Vulkan commands use the stdcall convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
+ // Android does not support Vulkan in native code using the "armeabi" ABI.
+ #error "Vulkan requires the 'armeabi-v7a' or 'armeabi-v7a-hard' ABI on 32-bit ARM CPUs"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
+ // On Android/ARMv7a, Vulkan functions use the armeabi-v7a-hard calling
+ // convention, even if the application's native code is compiled with the
+ // armeabi-v7a calling convention.
+ #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+ #define VKAPI_CALL
+ #define VKAPI_PTR VKAPI_ATTR
+#else
+ // On other platforms, use the default calling convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <android/native_window.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#include <mir_toolkit/client_types.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include <wayland-client.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#include <X11/Xlib.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <X11/Xlib.h>
+//#include <xcb/xcb.h>
+typedef struct xcb_connection_t xcb_connection_t;
+typedef uint32_t xcb_window_t;
+typedef uint32_t xcb_visualid_t;
+typedef xcb_connection_t *(*PFN_XGetXCBConnection)(Display *dpy);
+#endif
+
+/* this file is a trimmed version of vulkan/vulkan.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2015-2016 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#define VK_VERSION_1_0 1
+
+#define VK_MAKE_VERSION(major, minor, patch) \
+ (((major) << 22) | ((minor) << 12) | (patch))
+
+// Vulkan 1.0 version number
+#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)
+
+#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
+#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
+#define VK_HEADER_VERSION 8
+#define VK_NULL_HANDLE 0
+
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+
+typedef uint32_t VkFlags;
+typedef uint32_t VkBool32;
+
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_HANDLE(VkPhysicalDevice)
+#define VK_TRUE 1
+#define VK_FALSE 0
+#define VK_MAX_EXTENSION_NAME_SIZE 256
+typedef enum VkResult {
+ VK_SUCCESS = 0,
+ VK_NOT_READY = 1,
+ VK_TIMEOUT = 2,
+ VK_EVENT_SET = 3,
+ VK_EVENT_RESET = 4,
+ VK_INCOMPLETE = 5,
+ VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+ VK_ERROR_INITIALIZATION_FAILED = -3,
+ VK_ERROR_DEVICE_LOST = -4,
+ VK_ERROR_MEMORY_MAP_FAILED = -5,
+ VK_ERROR_LAYER_NOT_PRESENT = -6,
+ VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+ VK_ERROR_FEATURE_NOT_PRESENT = -8,
+ VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+ VK_ERROR_TOO_MANY_OBJECTS = -10,
+ VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+ VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+ VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+ VK_SUBOPTIMAL_KHR = 1000001003,
+ VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+ VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+ VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+ VK_ERROR_INVALID_SHADER_NV = -1000012000,
+ VK_RESULT_BEGIN_RANGE = VK_ERROR_FORMAT_NOT_SUPPORTED,
+ VK_RESULT_END_RANGE = VK_INCOMPLETE,
+ VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FORMAT_NOT_SUPPORTED + 1),
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef enum VkStructureType {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+ VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+ VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
+ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+ VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
+ VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum VkSystemAllocationScope {
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
+ VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND,
+ VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE,
+ VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1),
+ VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF
+} VkSystemAllocationScope;
+
+typedef enum VkInternalAllocationType {
+ VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
+ VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1),
+ VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkInternalAllocationType;
+
+typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
+ void* pUserData,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)(
+ void* pUserData,
+ void* pOriginal,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkFreeFunction)(
+ void* pUserData,
+ void* pMemory);
+
+typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);
+
+typedef struct VkAllocationCallbacks {
+ void* pUserData;
+ PFN_vkAllocationFunction pfnAllocation;
+ PFN_vkReallocationFunction pfnReallocation;
+ PFN_vkFreeFunction pfnFree;
+ PFN_vkInternalAllocationNotification pfnInternalAllocation;
+ PFN_vkInternalFreeNotification pfnInternalFree;
+} VkAllocationCallbacks;
+
+typedef struct VkExtensionProperties {
+ char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+} VkExtensionProperties;
+
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+
+#define VK_KHR_surface 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+
+#define VK_KHR_SURFACE_SPEC_VERSION 25
+#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#define VK_KHR_xlib_surface 1
+#include <X11/Xlib.h>
+
+#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
+#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
+
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
+
+typedef struct VkXlibSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkXlibSurfaceCreateFlagsKHR flags;
+ Display* dpy;
+ Window window;
+} VkXlibSurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_XLIB_KHR */
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#define VK_KHR_xcb_surface 1
+
+#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
+#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
+
+typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
+
+typedef struct VkXcbSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkXcbSurfaceCreateFlagsKHR flags;
+ xcb_connection_t* connection;
+ xcb_window_t window;
+} VkXcbSurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_XCB_KHR */
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#define VK_KHR_wayland_surface 1
+#include <wayland-client.h>
+
+#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 5
+#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
+
+typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
+
+typedef struct VkWaylandSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkWaylandSurfaceCreateFlagsKHR flags;
+ struct wl_display* display;
+ struct wl_surface* surface;
+} VkWaylandSurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#define VK_KHR_mir_surface 1
+#include <mir_toolkit/client_types.h>
+
+#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
+#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
+
+typedef VkFlags VkMirSurfaceCreateFlagsKHR;
+
+typedef struct VkMirSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkMirSurfaceCreateFlagsKHR flags;
+ MirConnection* connection;
+ MirSurface* mirSurface;
+} VkMirSurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_MIR_KHR */
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#define VK_KHR_android_surface 1
+#include <android/native_window.h>
+
+#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
+#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
+
+typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
+
+typedef struct VkAndroidSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAndroidSurfaceCreateFlagsKHR flags;
+ ANativeWindow* window;
+} VkAndroidSurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_ANDROID_KHR */
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_win32_surface 1
+#include <windows.h>
+
+#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 5
+#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
+
+typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
+
+typedef struct VkWin32SurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkWin32SurfaceCreateFlagsKHR flags;
+ HINSTANCE hinstance;
+ HWND hwnd;
+} VkWin32SurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+/* vi: set ts=4 sw=4 expandtab: */
# HG changeset patch
# User Jacob Lifshay <programmerjake@gmail.com>
# 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 <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_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 <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.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: */
# HG changeset patch
# User Jacob Lifshay <programmerjake@gmail.com>
# Date 1487661491 28800
# Mon Feb 20 23:18:11 2017 -0800
# Node ID effeb24041ead856995617a27ad59f5b84980edb
# Parent 5046b8390345b414fabfe20bf6516a58101f3ba9
add vulkan test
diff -r 5046b8390345 -r effeb24041ea src/test/SDL_test_common.c
--- a/src/test/SDL_test_common.c Mon Feb 20 23:18:11 2017 -0800
+++ b/src/test/SDL_test_common.c Mon Feb 20 23:18:11 2017 -0800
@@ -876,7 +876,7 @@
if (!state->skip_renderer
&& (state->renderdriver
- || !(state->window_flags & SDL_WINDOW_OPENGL))) {
+ || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN)))) {
m = -1;
if (state->renderdriver) {
SDL_RendererInfo info;
diff -r 5046b8390345 -r effeb24041ea test/Makefile.in
--- a/test/Makefile.in Mon Feb 20 23:18:11 2017 -0800
+++ b/test/Makefile.in Mon Feb 20 23:18:11 2017 -0800
@@ -66,6 +66,7 @@
testdisplayinfo$(EXE) \
testqsort$(EXE) \
controllermap$(EXE) \
+ testvulkan$(EXE) \
all: Makefile $(TARGETS)
@@ -289,6 +290,9 @@
controllermap$(EXE): $(srcdir)/controllermap.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+testvulkan$(EXE): $(srcdir)/testvulkan.c
+ $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
clean:
rm -f $(TARGETS)
diff -r 5046b8390345 -r effeb24041ea test/testvulkan.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testvulkan.c Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,1144 @@
+/*
+ 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.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "SDL_test_common.h"
+
+#if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
+
+int main(int argc, char *argv[])
+{
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Vulkan support on this system\n");
+ return 1;
+}
+
+#else
+
+#define VK_NO_PROTOTYPES
+#include "vulkan/vulkan.h"
+
+#define VULKAN_FUNCTIONS() \
+ VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR) \
+ VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers) \
+ VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer) \
+ VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage) \
+ VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier) \
+ VULKAN_DEVICE_FUNCTION(vkCreateCommandPool) \
+ VULKAN_DEVICE_FUNCTION(vkCreateFence) \
+ VULKAN_DEVICE_FUNCTION(vkCreateImageView) \
+ VULKAN_DEVICE_FUNCTION(vkCreateSemaphore) \
+ VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR) \
+ VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool) \
+ VULKAN_DEVICE_FUNCTION(vkDestroyDevice) \
+ VULKAN_DEVICE_FUNCTION(vkDestroyFence) \
+ VULKAN_DEVICE_FUNCTION(vkDestroyImageView) \
+ VULKAN_DEVICE_FUNCTION(vkDestroySemaphore) \
+ VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR) \
+ VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle) \
+ VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer) \
+ VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers) \
+ VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue) \
+ VULKAN_DEVICE_FUNCTION(vkGetFenceStatus) \
+ VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR) \
+ VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR) \
+ VULKAN_DEVICE_FUNCTION(vkQueueSubmit) \
+ VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer) \
+ VULKAN_DEVICE_FUNCTION(vkResetFences) \
+ VULKAN_DEVICE_FUNCTION(vkWaitForFences) \
+ VULKAN_GLOBAL_FUNCTION(vkCreateInstance) \
+ VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties) \
+ VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties) \
+ VULKAN_INSTANCE_FUNCTION(vkCreateDevice) \
+ VULKAN_INSTANCE_FUNCTION(vkDestroyInstance) \
+ VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR) \
+ VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties) \
+ VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices) \
+ VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) \
+ VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)
+
+#define VULKAN_DEVICE_FUNCTION(name) static PFN_##name name = NULL;
+#define VULKAN_GLOBAL_FUNCTION(name) static PFN_##name name = NULL;
+#define VULKAN_INSTANCE_FUNCTION(name) static PFN_##name name = NULL;
+VULKAN_FUNCTIONS()
+#undef VULKAN_DEVICE_FUNCTION
+#undef VULKAN_GLOBAL_FUNCTION
+#undef VULKAN_INSTANCE_FUNCTION
+static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+
+enum
+{
+ VK_ERROR_FRAGMENTED_POOL = -12,
+ VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
+};
+
+static const char *getVulkanResultString(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>";
+}
+
+typedef struct VulkanContext
+{
+ VkInstance instance;
+ VkDevice device;
+ VkSurfaceKHR surface;
+ VkSwapchainKHR swapchain;
+ VkPhysicalDeviceProperties physicalDeviceProperties;
+ VkPhysicalDeviceFeatures physicalDeviceFeatures;
+ uint32_t graphicsQueueFamilyIndex;
+ uint32_t presentQueueFamilyIndex;
+ VkPhysicalDevice physicalDevice;
+ VkQueue graphicsQueue;
+ VkQueue presentQueue;
+ VkSemaphore imageAvailableSemaphore;
+ VkSemaphore renderingFinishedSemaphore;
+ VkSurfaceCapabilitiesKHR surfaceCapabilities;
+ VkSurfaceFormatKHR *surfaceFormats;
+ uint32_t surfaceFormatsAllocatedCount;
+ uint32_t surfaceFormatsCount;
+ uint32_t swapchainDesiredImageCount;
+ VkSurfaceFormatKHR surfaceFormat;
+ VkExtent2D swapchainSize;
+ VkCommandPool commandPool;
+ uint32_t swapchainImageCount;
+ VkImage *swapchainImages;
+ VkCommandBuffer *commandBuffers;
+ VkFence *fences;
+} VulkanContext;
+
+static SDLTest_CommonState *state;
+static VulkanContext vulkanContext = {};
+
+static void shutdownVulkan(void);
+
+/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
+static void quit(int rc)
+{
+ shutdownVulkan();
+ SDLTest_CommonQuit(state);
+ exit(rc);
+}
+
+static void loadGlobalFunctions(void)
+{
+ vkGetInstanceProcAddr = SDL_Vulkan_GetVkGetInstanceProcAddr();
+ if(!vkGetInstanceProcAddr)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n",
+ SDL_GetError());
+ quit(2);
+ }
+
+#define VULKAN_DEVICE_FUNCTION(name)
+#define VULKAN_GLOBAL_FUNCTION(name) \
+ name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
+ if(!name) \
+ { \
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
+ "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
+ quit(2); \
+ }
+#define VULKAN_INSTANCE_FUNCTION(name)
+ VULKAN_FUNCTIONS()
+#undef VULKAN_DEVICE_FUNCTION
+#undef VULKAN_GLOBAL_FUNCTION
+#undef VULKAN_INSTANCE_FUNCTION
+}
+
+static void createInstance(void)
+{
+ VkApplicationInfo appInfo = {};
+ appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ appInfo.apiVersion = VK_API_VERSION_1_0;
+ VkInstanceCreateInfo instanceCreateInfo = {};
+ instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ instanceCreateInfo.pApplicationInfo = &appInfo;
+ const char **extensions = NULL;
+ unsigned extensionCount = 0;
+ if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, NULL))
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "SDL_Vulkan_GetInstanceExtensions(): %s\n",
+ SDL_GetError());
+ quit(2);
+ }
+ extensions = SDL_malloc(sizeof(const char *) * extensionCount);
+ if(!extensions)
+ {
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, extensions))
+ {
+ SDL_free(extensions);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "SDL_Vulkan_GetInstanceExtensions(): %s\n",
+ SDL_GetError());
+ quit(2);
+ }
+ instanceCreateInfo.enabledExtensionCount = extensionCount;
+ instanceCreateInfo.ppEnabledExtensionNames = extensions;
+ VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance);
+ SDL_free(extensions);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.instance = VK_NULL_HANDLE;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkCreateInstance(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void loadInstanceFunctions(void)
+{
+#define VULKAN_DEVICE_FUNCTION(name)
+#define VULKAN_GLOBAL_FUNCTION(name)
+#define VULKAN_INSTANCE_FUNCTION(name) \
+ name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name); \
+ if(!name) \
+ { \
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
+ "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
+ quit(2); \
+ }
+ VULKAN_FUNCTIONS()
+#undef VULKAN_DEVICE_FUNCTION
+#undef VULKAN_GLOBAL_FUNCTION
+#undef VULKAN_INSTANCE_FUNCTION
+}
+
+static void createSurface(void)
+{
+ if(!SDL_Vulkan_CreateSurface(state->windows[0],
+ (SDL_vulkanInstance)vulkanContext.instance,
+ (SDL_vulkanSurface *)&vulkanContext.surface))
+ {
+ vulkanContext.surface = VK_NULL_HANDLE;
+ SDL_LogError(
+ SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError());
+ quit(2);
+ }
+}
+
+static void findPhysicalDevice(void)
+{
+ uint32_t physicalDeviceCount = 0;
+ VkResult result =
+ vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEnumeratePhysicalDevices(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ if(physicalDeviceCount == 0)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEnumeratePhysicalDevices(): no physical devices\n");
+ quit(2);
+ }
+ VkPhysicalDevice *physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
+ if(!physicalDevices)
+ {
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ result =
+ vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(physicalDevices);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEnumeratePhysicalDevices(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ VkQueueFamilyProperties *queueFamiliesProperties = NULL;
+ uint32_t queueFamiliesPropertiesAllocatedSize = 0;
+ VkExtensionProperties *deviceExtensions = NULL;
+ uint32_t deviceExtensionsAllocatedSize = 0;
+ vulkanContext.physicalDevice = NULL;
+ for(uint32_t physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount;
+ physicalDeviceIndex++)
+ {
+ VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
+ vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties);
+ if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1)
+ continue;
+ vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures);
+ uint32_t queueFamiliesCount = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL);
+ if(queueFamiliesCount == 0)
+ continue;
+ if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount)
+ {
+ SDL_free(queueFamiliesProperties);
+ queueFamiliesPropertiesAllocatedSize = queueFamiliesCount;
+ queueFamiliesProperties =
+ SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize);
+ if(!queueFamiliesProperties)
+ {
+ SDL_free(physicalDevices);
+ SDL_free(deviceExtensions);
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ }
+ vkGetPhysicalDeviceQueueFamilyProperties(
+ physicalDevice, &queueFamiliesCount, queueFamiliesProperties);
+ vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount;
+ vulkanContext.presentQueueFamilyIndex = queueFamiliesCount;
+ for(uint32_t queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount;
+ queueFamilyIndex++)
+ {
+ if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0)
+ continue;
+ if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+ vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex;
+ VkBool32 supported = 0;
+ result = vkGetPhysicalDeviceSurfaceSupportKHR(
+ physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(physicalDevices);
+ SDL_free(queueFamiliesProperties);
+ SDL_free(deviceExtensions);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ if(supported)
+ {
+ vulkanContext.presentQueueFamilyIndex = queueFamilyIndex;
+ if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+ break; // use this queue because it can present and do graphics
+ }
+ }
+ if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found
+ continue;
+ if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found
+ continue;
+ uint32_t deviceExtensionCount = 0;
+ result =
+ vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(physicalDevices);
+ SDL_free(queueFamiliesProperties);
+ SDL_free(deviceExtensions);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEnumerateDeviceExtensionProperties(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ if(deviceExtensionCount == 0)
+ continue;
+ if(deviceExtensionsAllocatedSize < deviceExtensionCount)
+ {
+ SDL_free(deviceExtensions);
+ deviceExtensionsAllocatedSize = deviceExtensionCount;
+ deviceExtensions =
+ SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize);
+ if(!deviceExtensions)
+ {
+ SDL_free(physicalDevices);
+ SDL_free(queueFamiliesProperties);
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ }
+ result = vkEnumerateDeviceExtensionProperties(
+ physicalDevice, NULL, &deviceExtensionCount, deviceExtensions);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(physicalDevices);
+ SDL_free(queueFamiliesProperties);
+ SDL_free(deviceExtensions);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEnumerateDeviceExtensionProperties(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ SDL_bool hasSwapchainExtension = SDL_FALSE;
+ for(uint32_t i = 0; i < deviceExtensionCount; i++)
+ {
+ if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
+ {
+ hasSwapchainExtension = SDL_TRUE;
+ break;
+ }
+ }
+ if(!hasSwapchainExtension)
+ continue;
+ vulkanContext.physicalDevice = physicalDevice;
+ break;
+ }
+ SDL_free(physicalDevices);
+ SDL_free(queueFamiliesProperties);
+ SDL_free(deviceExtensions);
+ if(!vulkanContext.physicalDevice)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found");
+ quit(2);
+ }
+}
+
+static void createDevice(void)
+{
+ VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {};
+ deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex;
+ deviceQueueCreateInfo->queueCount = 1;
+ static const float queuePriority[] = {1.0f};
+ deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0];
+ VkDeviceCreateInfo deviceCreateInfo = {};
+ deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+ deviceCreateInfo.queueCreateInfoCount = 1;
+ deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
+ deviceCreateInfo.pEnabledFeatures = NULL;
+ static const char *const deviceExtensionNames[] = {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ };
+ deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames);
+ deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;
+ VkResult result = vkCreateDevice(
+ vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.device = VK_NULL_HANDLE;
+ SDL_LogError(
+ SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void loadDeviceFunctions(void)
+{
+#define VULKAN_DEVICE_FUNCTION(name) \
+ name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name); \
+ if(!name) \
+ { \
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
+ "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
+ quit(2); \
+ }
+#define VULKAN_GLOBAL_FUNCTION(name)
+#define VULKAN_INSTANCE_FUNCTION(name)
+ VULKAN_FUNCTIONS()
+#undef VULKAN_DEVICE_FUNCTION
+#undef VULKAN_GLOBAL_FUNCTION
+#undef VULKAN_INSTANCE_FUNCTION
+}
+
+#undef VULKAN_FUNCTIONS
+
+static void getQueues(void)
+{
+ vkGetDeviceQueue(vulkanContext.device,
+ vulkanContext.graphicsQueueFamilyIndex,
+ 0,
+ &vulkanContext.graphicsQueue);
+ if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex)
+ vkGetDeviceQueue(vulkanContext.device,
+ vulkanContext.presentQueueFamilyIndex,
+ 0,
+ &vulkanContext.presentQueue);
+ else
+ vulkanContext.presentQueue = vulkanContext.graphicsQueue;
+}
+
+static void createSemaphore(VkSemaphore *semaphore)
+{
+ VkSemaphoreCreateInfo createInfo = {};
+ createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+ VkResult result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore);
+ if(result != VK_SUCCESS)
+ {
+ *semaphore = VK_NULL_HANDLE;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkCreateSemaphore(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void createSemaphores(void)
+{
+ createSemaphore(&vulkanContext.imageAvailableSemaphore);
+ createSemaphore(&vulkanContext.renderingFinishedSemaphore);
+}
+
+static void getSurfaceCaps(void)
+{
+ VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
+ vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+
+ // check surface usage
+ if(!(vulkanContext.surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Vulkan surface doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT\n");
+ quit(2);
+ }
+}
+
+static void getSurfaceFormats(void)
+{
+ VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
+ vulkanContext.surface,
+ &vulkanContext.surfaceFormatsCount,
+ NULL);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.surfaceFormatsCount = 0;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ if(vulkanContext.surfaceFormatsCount > vulkanContext.surfaceFormatsAllocatedCount)
+ {
+ vulkanContext.surfaceFormatsAllocatedCount = vulkanContext.surfaceFormatsCount;
+ SDL_free(vulkanContext.surfaceFormats);
+ vulkanContext.surfaceFormats =
+ SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext.surfaceFormatsAllocatedCount);
+ if(!vulkanContext.surfaceFormats)
+ {
+ vulkanContext.surfaceFormatsCount = 0;
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ }
+ result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
+ vulkanContext.surface,
+ &vulkanContext.surfaceFormatsCount,
+ vulkanContext.surfaceFormats);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.surfaceFormatsCount = 0;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void getSwapchainImages(void)
+{
+ SDL_free(vulkanContext.swapchainImages);
+ vulkanContext.swapchainImages = NULL;
+ VkResult result = vkGetSwapchainImagesKHR(
+ vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.swapchainImageCount = 0;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetSwapchainImagesKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ vulkanContext.swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext.swapchainImageCount);
+ if(!vulkanContext.swapchainImages)
+ {
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ result = vkGetSwapchainImagesKHR(vulkanContext.device,
+ vulkanContext.swapchain,
+ &vulkanContext.swapchainImageCount,
+ vulkanContext.swapchainImages);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(vulkanContext.swapchainImages);
+ vulkanContext.swapchainImages = NULL;
+ vulkanContext.swapchainImageCount = 0;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkGetSwapchainImagesKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static SDL_bool createSwapchain(void)
+{
+ // pick an image count
+ vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.minImageCount + 1;
+ if(vulkanContext.swapchainDesiredImageCount > vulkanContext.surfaceCapabilities.maxImageCount)
+ vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.maxImageCount;
+
+ // pick a format
+ if(vulkanContext.surfaceFormatsCount == 1
+ && vulkanContext.surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
+ {
+ // aren't any preferred formats, so we pick
+ vulkanContext.surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
+ vulkanContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM;
+ }
+ else
+ {
+ vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0];
+ for(uint32_t i = 0; i < vulkanContext.surfaceFormatsCount; i++)
+ {
+ if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM)
+ {
+ vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i];
+ break;
+ }
+ }
+ }
+
+ // get size
+ int w, h;
+ SDL_GL_GetDrawableSize(state->windows[0], &w, &h);
+ vulkanContext.swapchainSize.width = w;
+ vulkanContext.swapchainSize.height = h;
+ if(w == 0 || h == 0)
+ return SDL_FALSE;
+
+ VkSwapchainCreateInfoKHR createInfo = {};
+ createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ createInfo.surface = vulkanContext.surface;
+ createInfo.minImageCount = vulkanContext.swapchainDesiredImageCount;
+ createInfo.imageFormat = vulkanContext.surfaceFormat.format;
+ createInfo.imageColorSpace = vulkanContext.surfaceFormat.colorSpace;
+ createInfo.imageExtent = vulkanContext.swapchainSize;
+ createInfo.imageArrayLayers = 1;
+ createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ createInfo.preTransform = vulkanContext.surfaceCapabilities.currentTransform;
+ createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ createInfo.clipped = VK_TRUE;
+ createInfo.oldSwapchain = vulkanContext.swapchain;
+ VkResult result =
+ vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain);
+ if(createInfo.oldSwapchain)
+ vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.swapchain = VK_NULL_HANDLE;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkCreateSwapchainKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ getSwapchainImages();
+ return SDL_TRUE;
+}
+
+static void destorySwapchain(void)
+{
+ if(vulkanContext.swapchain)
+ vkDestroySwapchainKHR(vulkanContext.device, vulkanContext.swapchain, NULL);
+ vulkanContext.swapchain = VK_NULL_HANDLE;
+ SDL_free(vulkanContext.swapchainImages);
+ vulkanContext.swapchainImages = NULL;
+}
+
+static void destroyCommandBuffers(void)
+{
+ if(vulkanContext.commandBuffers)
+ vkFreeCommandBuffers(vulkanContext.device,
+ vulkanContext.commandPool,
+ vulkanContext.swapchainImageCount,
+ vulkanContext.commandBuffers);
+ SDL_free(vulkanContext.commandBuffers);
+ vulkanContext.commandBuffers = NULL;
+}
+
+static void destroyCommandPool(void)
+{
+ if(vulkanContext.commandPool)
+ vkDestroyCommandPool(vulkanContext.device, vulkanContext.commandPool, NULL);
+ vulkanContext.commandPool = VK_NULL_HANDLE;
+}
+
+static void createCommandPool(void)
+{
+ VkCommandPoolCreateInfo createInfo = {};
+ createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ createInfo.flags =
+ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
+ createInfo.queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex;
+ VkResult result =
+ vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool);
+ if(result != VK_SUCCESS)
+ {
+ vulkanContext.commandPool = VK_NULL_HANDLE;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkCreateCommandPool(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void createCommandBuffers(void)
+{
+ VkCommandBufferAllocateInfo allocateInfo = {};
+ allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ allocateInfo.commandPool = vulkanContext.commandPool;
+ allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount;
+ vulkanContext.commandBuffers =
+ SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount);
+ VkResult result =
+ vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers);
+ if(result != VK_SUCCESS)
+ {
+ SDL_free(vulkanContext.commandBuffers);
+ vulkanContext.commandBuffers = NULL;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkAllocateCommandBuffers(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void createFences(void)
+{
+ vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount);
+ if(!vulkanContext.fences)
+ {
+ SDL_OutOfMemory();
+ quit(2);
+ }
+ for(uint32_t i = 0; i < vulkanContext.swapchainImageCount; i++)
+ {
+ VkFenceCreateInfo createInfo = {};
+ createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+ VkResult result =
+ vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]);
+ if(result != VK_SUCCESS)
+ {
+ for(; i > 0; i--)
+ {
+ vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL);
+ }
+ SDL_free(vulkanContext.fences);
+ vulkanContext.fences = NULL;
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkCreateFence(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ }
+}
+
+static void destroyFences(void)
+{
+ if(!vulkanContext.fences)
+ return;
+ for(uint32_t i = 0; i < vulkanContext.swapchainImageCount; i++)
+ {
+ vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL);
+ }
+ SDL_free(vulkanContext.fences);
+ vulkanContext.fences = NULL;
+}
+
+static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer,
+ VkAccessFlags sourceAccessMask,
+ VkAccessFlags destAccessMask,
+ VkImageLayout sourceLayout,
+ VkImageLayout destLayout,
+ VkImage image)
+{
+ VkImageMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.srcAccessMask = sourceAccessMask;
+ barrier.dstAccessMask = destAccessMask;
+ barrier.oldLayout = sourceLayout;
+ barrier.newLayout = destLayout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image;
+ barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.levelCount = 1;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.layerCount = 1;
+ vkCmdPipelineBarrier(commandBuffer,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 1,
+ &barrier);
+}
+
+static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor)
+{
+ VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex];
+ VkImage image = vulkanContext.swapchainImages[frameIndex];
+ VkResult result = vkResetCommandBuffer(commandBuffer, 0);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkResetCommandBuffer(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ VkCommandBufferBeginInfo beginInfo = {};
+ beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
+ result = vkBeginCommandBuffer(commandBuffer, &beginInfo);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkBeginCommandBuffer(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ recordPipelineImageBarrier(commandBuffer,
+ 0,
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ image);
+ VkImageSubresourceRange clearRange;
+ clearRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ clearRange.baseMipLevel = 0;
+ clearRange.levelCount = 1;
+ clearRange.baseArrayLayer = 0;
+ clearRange.layerCount = 1;
+ vkCmdClearColorImage(
+ commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange);
+ recordPipelineImageBarrier(commandBuffer,
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_ACCESS_MEMORY_READ_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ image);
+ result = vkEndCommandBuffer(commandBuffer);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkEndCommandBuffer(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+}
+
+static void destroySwapchainAndSwapchainSpecificStuff(SDL_bool doDestroySwapchain)
+{
+ destroyFences();
+ destroyCommandBuffers();
+ destroyCommandPool();
+ if(doDestroySwapchain)
+ destorySwapchain();
+}
+
+static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void)
+{
+ destroySwapchainAndSwapchainSpecificStuff(SDL_FALSE);
+ getSurfaceCaps();
+ getSurfaceFormats();
+ if(!createSwapchain())
+ return SDL_FALSE;
+ createCommandPool();
+ createCommandBuffers();
+ createFences();
+ return SDL_TRUE;
+}
+
+static void initVulkan(void)
+{
+ SDL_memset(&vulkanContext, 0, sizeof(VulkanContext));
+ loadGlobalFunctions();
+ createInstance();
+ loadInstanceFunctions();
+ createSurface();
+ findPhysicalDevice();
+ createDevice();
+ loadDeviceFunctions();
+ getQueues();
+ createSemaphores();
+ createNewSwapchainAndSwapchainSpecificStuff();
+}
+
+static void shutdownVulkan(void)
+{
+ if(vulkanContext.device && vkDeviceWaitIdle)
+ vkDeviceWaitIdle(vulkanContext.device);
+ destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE);
+ if(vulkanContext.imageAvailableSemaphore && vkDestroySemaphore)
+ vkDestroySemaphore(vulkanContext.device, vulkanContext.imageAvailableSemaphore, NULL);
+ if(vulkanContext.renderingFinishedSemaphore && vkDestroySemaphore)
+ vkDestroySemaphore(vulkanContext.device, vulkanContext.renderingFinishedSemaphore, NULL);
+ if(vulkanContext.device && vkDestroyDevice)
+ vkDestroyDevice(vulkanContext.device, NULL);
+ if(vulkanContext.surface && vkDestroySurfaceKHR)
+ vkDestroySurfaceKHR(vulkanContext.instance, vulkanContext.surface, NULL);
+ if(vulkanContext.instance && vkDestroyInstance)
+ vkDestroyInstance(vulkanContext.instance, NULL);
+ SDL_free(vulkanContext.surfaceFormats);
+}
+
+static SDL_bool render(void)
+{
+ if(!vulkanContext.swapchain)
+ {
+ SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff();
+ if(!retval)
+ SDL_Delay(100);
+ return retval;
+ }
+ uint32_t frameIndex;
+ VkResult result = vkAcquireNextImageKHR(vulkanContext.device,
+ vulkanContext.swapchain,
+ UINT64_MAX,
+ vulkanContext.imageAvailableSemaphore,
+ VK_NULL_HANDLE,
+ &frameIndex);
+ if(result == VK_ERROR_OUT_OF_DATE_KHR)
+ return createNewSwapchainAndSwapchainSpecificStuff();
+ if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkAcquireNextImageKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ result = vkWaitForFences(
+ vulkanContext.device, 1, &vulkanContext.fences[frameIndex], VK_FALSE, UINT64_MAX);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(
+ SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result));
+ quit(2);
+ }
+ result = vkResetFences(vulkanContext.device, 1, &vulkanContext.fences[frameIndex]);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(
+ SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result));
+ quit(2);
+ }
+ double currentTime = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();
+ VkClearColorValue clearColor = {};
+ clearColor.float32[0] = 0.5 + 0.5 * SDL_sin(currentTime);
+ clearColor.float32[1] = 0.5 + 0.5 * SDL_sin(currentTime + M_PI * 2 / 3);
+ clearColor.float32[2] = 0.5 + 0.5 * SDL_sin(currentTime + M_PI * 4 / 3);
+ clearColor.float32[3] = 1;
+ rerecordCommandBuffer(frameIndex, &clearColor);
+ VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkSubmitInfo submitInfo = {};
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.waitSemaphoreCount = 1;
+ submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore;
+ submitInfo.pWaitDstStageMask = &waitDestStageMask;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex];
+ submitInfo.signalSemaphoreCount = 1;
+ submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore;
+ result = vkQueueSubmit(
+ vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]);
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(
+ SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result));
+ quit(2);
+ }
+ VkPresentInfoKHR presentInfo = {};
+ presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+ presentInfo.waitSemaphoreCount = 1;
+ presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore;
+ presentInfo.swapchainCount = 1;
+ presentInfo.pSwapchains = &vulkanContext.swapchain;
+ presentInfo.pImageIndices = &frameIndex;
+ result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo);
+ if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
+ {
+ return createNewSwapchainAndSwapchainSpecificStuff();
+ }
+ if(result != VK_SUCCESS)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "vkQueuePresentKHR(): %s\n",
+ getVulkanResultString(result));
+ quit(2);
+ }
+ int w, h;
+ SDL_GL_GetDrawableSize(state->windows[0], &w, &h);
+ if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height)
+ {
+ return createNewSwapchainAndSwapchainSpecificStuff();
+ }
+ return SDL_TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ int fsaa, accel;
+ int value;
+ int i, done;
+ SDL_DisplayMode mode;
+ SDL_Event event;
+ Uint32 then, now, frames;
+ int status;
+ int dw, dh;
+
+ /* Enable standard application logging */
+ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
+
+ /* Initialize parameters */
+ fsaa = 0;
+ accel = -1;
+
+ /* Initialize test framework */
+ state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
+ if(!state)
+ {
+ return 1;
+ }
+ for(i = 1; i < argc;)
+ {
+ int consumed;
+
+ consumed = SDLTest_CommonArg(state, i);
+ if(consumed < 0)
+ {
+ SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
+ quit(1);
+ }
+ i += consumed;
+ }
+
+ /* Set Vulkan parameters */
+ state->window_flags |= SDL_WINDOW_VULKAN;
+ state->num_windows = 1;
+
+ if(!SDLTest_CommonInit(state))
+ {
+ quit(2);
+ }
+
+ SDL_GetCurrentDisplayMode(0, &mode);
+ SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
+ SDL_GetWindowSize(state->windows[0], &dw, &dh);
+ SDL_Log("Window Size : %d,%d\n", dw, dh);
+ SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
+ SDL_Log("Draw Size : %d,%d\n", dw, dh);
+ SDL_Log("\n");
+
+ initVulkan();
+
+ /* Main render loop */
+ frames = 0;
+ then = SDL_GetTicks();
+ done = 0;
+ while(!done)
+ {
+ /* Check for events */
+ ++frames;
+ while(SDL_PollEvent(&event))
+ {
+ SDLTest_CommonEvent(state, &event, &done);
+ }
+
+ render();
+ }
+
+ /* Print out some timing information */
+ now = SDL_GetTicks();
+ if(now > then)
+ {
+ SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then));
+ }
+ quit(0);
+ return 0;
+}
+
+#endif
diff -r 5046b8390345 -r effeb24041ea test/vulkan/vk_platform.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/vulkan/vk_platform.h Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,127 @@
+//
+// File: vk_platform.h
+//
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+
+#ifndef VK_PLATFORM_H_
+#define VK_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+* Platform-specific directives and type declarations
+***************************************************************************************************
+*/
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that Vulkan clients call Vulkan commands
+ * with the same calling conventions that the Vulkan implementation expects.
+ *
+ * VKAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * VKAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+ * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+ */
+#if defined(_WIN32)
+ // On Windows, Vulkan commands use the stdcall convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
+ // Android does not support Vulkan in native code using the "armeabi" ABI.
+ #error "Vulkan requires the 'armeabi-v7a' or 'armeabi-v7a-hard' ABI on 32-bit ARM CPUs"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
+ // On Android/ARMv7a, Vulkan functions use the armeabi-v7a-hard calling
+ // convention, even if the application's native code is compiled with the
+ // armeabi-v7a calling convention.
+ #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+ #define VKAPI_CALL
+ #define VKAPI_PTR VKAPI_ATTR
+#else
+ // On other platforms, use the default calling convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+#endif
+
+#include <stddef.h>
+
+#if !defined(VK_NO_STDINT_H)
+ #if defined(_MSC_VER) && (_MSC_VER < 1600)
+ typedef signed __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #else
+ #include <stdint.h>
+ #endif
+#endif // !defined(VK_NO_STDINT_H)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+// Platform-specific headers required by platform window system extensions.
+// These are enabled prior to #including "vulkan.h". The same enable then
+// controls inclusion of the extension interfaces in vulkan.h.
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <android/native_window.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#include <mir_toolkit/client_types.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include <wayland-client.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#include <X11/Xlib.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <xcb/xcb.h>
+#endif
+
+#endif
diff -r 5046b8390345 -r effeb24041ea test/vulkan/vulkan.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/vulkan/vulkan.h Mon Feb 20 23:18:11 2017 -0800
@@ -0,0 +1,3842 @@
+#ifndef VULKAN_H_
+#define VULKAN_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2015-2016 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/*
+** This header is generated from the Khronos Vulkan XML API Registry.
+**
+*/
+
+
+#define VK_VERSION_1_0 1
+#include "vk_platform.h"
+
+#define VK_MAKE_VERSION(major, minor, patch) \
+ (((major) << 22) | ((minor) << 12) | (patch))
+
+// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead.
+//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0)
+
+// Vulkan 1.0 version number
+#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)
+
+#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
+#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
+// Version of this file
+#define VK_HEADER_VERSION 8
+
+
+#define VK_NULL_HANDLE 0
+
+
+
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+
+#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+
+
+
+typedef uint32_t VkFlags;
+typedef uint32_t VkBool32;
+typedef uint64_t VkDeviceSize;
+typedef uint32_t VkSampleMask;
+
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_HANDLE(VkPhysicalDevice)
+VK_DEFINE_HANDLE(VkDevice)
+VK_DEFINE_HANDLE(VkQueue)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
+VK_DEFINE_HANDLE(VkCommandBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+
+#define VK_LOD_CLAMP_NONE 1000.0f
+#define VK_REMAINING_MIP_LEVELS (~0U)
+#define VK_REMAINING_ARRAY_LAYERS (~0U)
+#define VK_WHOLE_SIZE (~0ULL)
+#define VK_ATTACHMENT_UNUSED (~0U)
+#define VK_TRUE 1
+#define VK_FALSE 0
+#define VK_QUEUE_FAMILY_IGNORED (~0U)
+#define VK_SUBPASS_EXTERNAL (~0U)
+#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
+#define VK_UUID_SIZE 16
+#define VK_MAX_MEMORY_TYPES 32
+#define VK_MAX_MEMORY_HEAPS 16
+#define VK_MAX_EXTENSION_NAME_SIZE 256
+#define VK_MAX_DESCRIPTION_SIZE 256
+
+
+typedef enum VkPipelineCacheHeaderVersion {
+ VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
+ VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE,
+ VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE,
+ VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1),
+ VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCacheHeaderVersion;
+
+typedef enum VkResult {
+ VK_SUCCESS = 0,
+ VK_NOT_READY = 1,
+ VK_TIMEOUT = 2,
+ VK_EVENT_SET = 3,
+ VK_EVENT_RESET = 4,
+ VK_INCOMPLETE = 5,
+ VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+ VK_ERROR_INITIALIZATION_FAILED = -3,
+ VK_ERROR_DEVICE_LOST = -4,
+ VK_ERROR_MEMORY_MAP_FAILED = -5,
+ VK_ERROR_LAYER_NOT_PRESENT = -6,
+ VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+ VK_ERROR_FEATURE_NOT_PRESENT = -8,
+ VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+ VK_ERROR_TOO_MANY_OBJECTS = -10,
+ VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+ VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+ VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+ VK_SUBOPTIMAL_KHR = 1000001003,
+ VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+ VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+ VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+ VK_ERROR_INVALID_SHADER_NV = -1000012000,
+ VK_RESULT_BEGIN_RANGE = VK_ERROR_FORMAT_NOT_SUPPORTED,
+ VK_RESULT_END_RANGE = VK_INCOMPLETE,
+ VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FORMAT_NOT_SUPPORTED + 1),
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef enum VkStructureType {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
+ VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
+ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
+ VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
+ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
+ VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
+ VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
+ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
+ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
+ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
+ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
+ VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
+ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
+ VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
+ VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
+ VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
+ VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+ VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
+ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
+ VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
+ VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum VkSystemAllocationScope {
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
+ VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
+ VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND,
+ VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE,
+ VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1),
+ VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF
+} VkSystemAllocationScope;
+
+typedef enum VkInternalAllocationType {
+ VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
+ VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1),
+ VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkInternalAllocationType;
+
+typedef enum VkFormat {
+ VK_FORMAT_UNDEFINED = 0,
+ VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+ VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+ VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+ VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+ VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+ VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+ VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+ VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+ VK_FORMAT_R8_UNORM = 9,
+ VK_FORMAT_R8_SNORM = 10,
+ VK_FORMAT_R8_USCALED = 11,
+ VK_FORMAT_R8_SSCALED = 12,
+ VK_FORMAT_R8_UINT = 13,
+ VK_FORMAT_R8_SINT = 14,
+ VK_FORMAT_R8_SRGB = 15,
+ VK_FORMAT_R8G8_UNORM = 16,
+ VK_FORMAT_R8G8_SNORM = 17,
+ VK_FORMAT_R8G8_USCALED = 18,
+ VK_FORMAT_R8G8_SSCALED = 19,
+ VK_FORMAT_R8G8_UINT = 20,
+ VK_FORMAT_R8G8_SINT = 21,
+ VK_FORMAT_R8G8_SRGB = 22,
+ VK_FORMAT_R8G8B8_UNORM = 23,
+ VK_FORMAT_R8G8B8_SNORM = 24,
+ VK_FORMAT_R8G8B8_USCALED = 25,
+ VK_FORMAT_R8G8B8_SSCALED = 26,
+ VK_FORMAT_R8G8B8_UINT = 27,
+ VK_FORMAT_R8G8B8_SINT = 28,
+ VK_FORMAT_R8G8B8_SRGB = 29,
+ VK_FORMAT_B8G8R8_UNORM = 30,
+ VK_FORMAT_B8G8R8_SNORM = 31,
+ VK_FORMAT_B8G8R8_USCALED = 32,
+ VK_FORMAT_B8G8R8_SSCALED = 33,
+ VK_FORMAT_B8G8R8_UINT = 34,
+ VK_FORMAT_B8G8R8_SINT = 35,
+ VK_FORMAT_B8G8R8_SRGB = 36,
+ VK_FORMAT_R8G8B8A8_UNORM = 37,
+ VK_FORMAT_R8G8B8A8_SNORM = 38,
+ VK_FORMAT_R8G8B8A8_USCALED = 39,
+ VK_FORMAT_R8G8B8A8_SSCALED = 40,
+ VK_FORMAT_R8G8B8A8_UINT = 41,
+ VK_FORMAT_R8G8B8A8_SINT = 42,
+ VK_FORMAT_R8G8B8A8_SRGB = 43,
+ VK_FORMAT_B8G8R8A8_UNORM = 44,
+ VK_FORMAT_B8G8R8A8_SNORM = 45,
+ VK_FORMAT_B8G8R8A8_USCALED = 46,
+ VK_FORMAT_B8G8R8A8_SSCALED = 47,
+ VK_FORMAT_B8G8R8A8_UINT = 48,
+ VK_FORMAT_B8G8R8A8_SINT = 49,
+ VK_FORMAT_B8G8R8A8_SRGB = 50,
+ VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+ VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+ VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+ VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+ VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+ VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+ VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+ VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+ VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+ VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+ VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+ VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+ VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+ VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+ VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+ VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+ VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+ VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+ VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+ VK_FORMAT_R16_UNORM = 70,
+ VK_FORMAT_R16_SNORM = 71,
+ VK_FORMAT_R16_USCALED = 72,
+ VK_FORMAT_R16_SSCALED = 73,
+ VK_FORMAT_R16_UINT = 74,
+ VK_FORMAT_R16_SINT = 75,
+ VK_FORMAT_R16_SFLOAT = 76,
+ VK_FORMAT_R16G16_UNORM = 77,
+ VK_FORMAT_R16G16_SNORM = 78,
+ VK_FORMAT_R16G16_USCALED = 79,
+ VK_FORMAT_R16G16_SSCALED = 80,
+ VK_FORMAT_R16G16_UINT = 81,
+ VK_FORMAT_R16G16_SINT = 82,
+ VK_FORMAT_R16G16_SFLOAT = 83,
+ VK_FORMAT_R16G16B16_UNORM = 84,
+ VK_FORMAT_R16G16B16_SNORM = 85,
+ VK_FORMAT_R16G16B16_USCALED = 86,
+ VK_FORMAT_R16G16B16_SSCALED = 87,
+ VK_FORMAT_R16G16B16_UINT = 88,
+ VK_FORMAT_R16G16B16_SINT = 89,
+ VK_FORMAT_R16G16B16_SFLOAT = 90,
+ VK_FORMAT_R16G16B16A16_UNORM = 91,
+ VK_FORMAT_R16G16B16A16_SNORM = 92,
+ VK_FORMAT_R16G16B16A16_USCALED = 93,
+ VK_FORMAT_R16G16B16A16_SSCALED = 94,
+ VK_FORMAT_R16G16B16A16_UINT = 95,
+ VK_FORMAT_R16G16B16A16_SINT = 96,
+ VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+ VK_FORMAT_R32_UINT = 98,
+ VK_FORMAT_R32_SINT = 99,
+ VK_FORMAT_R32_SFLOAT = 100,
+ VK_FORMAT_R32G32_UINT = 101,
+ VK_FORMAT_R32G32_SINT = 102,
+ VK_FORMAT_R32G32_SFLOAT = 103,
+ VK_FORMAT_R32G32B32_UINT = 104,
+ VK_FORMAT_R32G32B32_SINT = 105,
+ VK_FORMAT_R32G32B32_SFLOAT = 106,
+ VK_FORMAT_R32G32B32A32_UINT = 107,
+ VK_FORMAT_R32G32B32A32_SINT = 108,
+ VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+ VK_FORMAT_R64_UINT = 110,
+ VK_FORMAT_R64_SINT = 111,
+ VK_FORMAT_R64_SFLOAT = 112,
+ VK_FORMAT_R64G64_UINT = 113,
+ VK_FORMAT_R64G64_SINT = 114,
+ VK_FORMAT_R64G64_SFLOAT = 115,
+ VK_FORMAT_R64G64B64_UINT = 116,
+ VK_FORMAT_R64G64B64_SINT = 117,
+ VK_FORMAT_R64G64B64_SFLOAT = 118,
+ VK_FORMAT_R64G64B64A64_UINT = 119,
+ VK_FORMAT_R64G64B64A64_SINT = 120,
+ VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+ VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+ VK_FORMAT_D16_UNORM = 124,
+ VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+ VK_FORMAT_D32_SFLOAT = 126,
+ VK_FORMAT_S8_UINT = 127,
+ VK_FORMAT_D16_UNORM_S8_UINT = 128,
+ VK_FORMAT_D24_UNORM_S8_UINT = 129,
+ VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+ VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+ VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+ VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+ VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+ VK_FORMAT_BC2_UNORM_BLOCK = 135,
+ VK_FORMAT_BC2_SRGB_BLOCK = 136,
+ VK_FORMAT_BC3_UNORM_BLOCK = 137,
+ VK_FORMAT_BC3_SRGB_BLOCK = 138,
+ VK_FORMAT_BC4_UNORM_BLOCK = 139,
+ VK_FORMAT_BC4_SNORM_BLOCK = 140,
+ VK_FORMAT_BC5_UNORM_BLOCK = 141,
+ VK_FORMAT_BC5_SNORM_BLOCK = 142,
+ VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+ VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+ VK_FORMAT_BC7_UNORM_BLOCK = 145,
+ VK_FORMAT_BC7_SRGB_BLOCK = 146,
+ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+ VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+ VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+ VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+ VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+ VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+ VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+ VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+ VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+ VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+ VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+ VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+ VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+ VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+ VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+ VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+ VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+ VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+ VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+ VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+ VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+ VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+ VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+ VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+ VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+ VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+ VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+ VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+ VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+ VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+ VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+ VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+ VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
+ VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED,
+ VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
+ VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1),
+ VK_FORMAT_MAX_ENUM = 0x7FFFFFFF
+} VkFormat;
+
+typedef enum VkImageType {
+ VK_IMAGE_TYPE_1D = 0,
+ VK_IMAGE_TYPE_2D = 1,
+ VK_IMAGE_TYPE_3D = 2,
+ VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D,
+ VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D,
+ VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1),
+ VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageType;
+
+typedef enum VkImageTiling {
+ VK_IMAGE_TILING_OPTIMAL = 0,
+ VK_IMAGE_TILING_LINEAR = 1,
+ VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL,
+ VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1),
+ VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF
+} VkImageTiling;
+
+typedef enum VkPhysicalDeviceType {
+ VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+ VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+ VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+ VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+ VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
+ VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER,
+ VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU,
+ VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1),
+ VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkPhysicalDeviceType;
+
+typedef enum VkQueryType {
+ VK_QUERY_TYPE_OCCLUSION = 0,
+ VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
+ VK_QUERY_TYPE_TIMESTAMP = 2,
+ VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION,
+ VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP,
+ VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1),
+ VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkQueryType;
+
+typedef enum VkSharingMode {
+ VK_SHARING_MODE_EXCLUSIVE = 0,
+ VK_SHARING_MODE_CONCURRENT = 1,
+ VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE,
+ VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT,
+ VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1),
+ VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSharingMode;
+
+typedef enum VkImageLayout {
+ VK_IMAGE_LAYOUT_UNDEFINED = 0,
+ VK_IMAGE_LAYOUT_GENERAL = 1,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+ VK_IMAGE_LAYOUT_DE