From 06479ba53507b7b8e4b9575fbaf6ec659c58fdc8 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 10 Oct 2015 16:35:06 +0100 Subject: [PATCH 01/42] Wayland: Implement HiDPI support Windows now keep track of the monitors they are on, so we can calculate the best scaling factor for them, by using the maximum of each of the monitors. The compositor scales down the buffer automatically when it is on a lower density monitor, instead of the previous way where it was scaling up the buffer on higher density monitors, which makes the application look much better on those ones. --- src/wl_init.c | 8 ++++- src/wl_monitor.c | 5 +++ src/wl_platform.h | 10 +++++- src/wl_window.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index a27bf6fc9..cceef16ba 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -36,6 +36,11 @@ #include +static inline int min(int n1, int n2) +{ + return n1 < n2 ? n1 : n2; +} + static void pointerHandleEnter(void* data, struct wl_pointer* pointer, uint32_t serial, @@ -381,7 +386,8 @@ static void registryHandleGlobal(void* data, if (strcmp(interface, "wl_compositor") == 0) { _glfw.wl.compositor = - wl_registry_bind(registry, name, &wl_compositor_interface, 1); + wl_registry_bind(registry, name, &wl_compositor_interface, + min(3, version)); } else if (strcmp(interface, "wl_shm") == 0) { diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 967f05e9f..7c58c8f84 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -97,6 +97,9 @@ static void scale(void* data, struct wl_output* output, int32_t factor) { + struct _GLFWmonitor *monitor = data; + + monitor->wl.scale = factor; } static const struct wl_output_listener output_listener = { @@ -142,6 +145,8 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland)); monitor->wl.modesSize = 4; + monitor->wl.scale = 1; + monitor->wl.output = output; wl_output_add_listener(output, &output_listener, monitor); diff --git a/src/wl_platform.h b/src/wl_platform.h index 5b8c25d8a..a734ec1e7 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -65,8 +65,16 @@ typedef struct _GLFWwindowWayland struct wl_egl_window* native; struct wl_shell_surface* shell_surface; struct wl_callback* callback; + _GLFWcursor* currentCursor; double cursorPosX, cursorPosY; + + // We need to track the monitors the window spans on to calculate the + // optimal scaling factor. + int scale; + _GLFWmonitor** monitors; + int monitorsCount; + int monitorsSize; } _GLFWwindowWayland; @@ -123,7 +131,7 @@ typedef struct _GLFWmonitorWayland int x; int y; - + int scale; } _GLFWmonitorWayland; diff --git a/src/wl_window.c b/src/wl_window.c index 713cda29e..00ce7135a 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -72,6 +72,79 @@ static const struct wl_shell_surface_listener shellSurfaceListener = { handlePopupDone }; +static void checkScaleChange(_GLFWwindow* window) +{ + int scaledWidth, scaledHeight; + int scale = 1; + int i; + int monitorScale; + + // Get the scale factor from the highest scale monitor. + for (i = 0; i < window->wl.monitorsCount; ++i) + { + monitorScale = window->wl.monitors[i]->wl.scale; + if (scale < monitorScale) + scale = monitorScale; + } + + // Only change the framebuffer size if the scale changed. + if (scale != window->wl.scale) + { + window->wl.scale = scale; + scaledWidth = window->wl.width * scale; + scaledHeight = window->wl.height * scale; + wl_surface_set_buffer_scale(window->wl.surface, scale); + wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0); + _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); + } +} + +static void handleEnter(void *data, + struct wl_surface *surface, + struct wl_output *output) +{ + _GLFWwindow* window = data; + _GLFWmonitor* monitor = wl_output_get_user_data(output); + + if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) + { + ++window->wl.monitorsSize; + window->wl.monitors = + realloc(window->wl.monitors, + window->wl.monitorsSize * sizeof(_GLFWmonitor*)); + } + + window->wl.monitors[window->wl.monitorsCount++] = monitor; + + checkScaleChange(window); +} + +static void handleLeave(void *data, + struct wl_surface *surface, + struct wl_output *output) +{ + _GLFWwindow* window = data; + _GLFWmonitor* monitor = wl_output_get_user_data(output); + GLFWbool found; + int i; + + for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i) + { + if (monitor == window->wl.monitors[i]) + found = GLFW_TRUE; + if (found) + window->wl.monitors[i] = window->wl.monitors[i + 1]; + } + window->wl.monitors[--window->wl.monitorsCount] = NULL; + + checkScaleChange(window); +} + +static const struct wl_surface_listener surfaceListener = { + handleEnter, + handleLeave +}; + static GLFWbool createSurface(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { @@ -79,6 +152,10 @@ static GLFWbool createSurface(_GLFWwindow* window, if (!window->wl.surface) return GLFW_FALSE; + wl_surface_add_listener(window->wl.surface, + &surfaceListener, + window); + wl_surface_set_user_data(window->wl.surface, window); window->wl.native = wl_egl_window_create(window->wl.surface, @@ -98,6 +175,7 @@ static GLFWbool createSurface(_GLFWwindow* window, window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; + window->wl.scale = 1; return GLFW_TRUE; } @@ -262,6 +340,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, window->wl.currentCursor = NULL; + window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*)); + window->wl.monitorsCount = 0; + window->wl.monitorsSize = 1; + return GLFW_TRUE; } @@ -288,6 +370,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.surface) wl_surface_destroy(window->wl.surface); + + free(window->wl.monitors); } void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) @@ -322,9 +406,12 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { - wl_egl_window_resize(window->wl.native, width, height, 0, 0); + int scaledWidth = width * window->wl.scale; + int scaledHeight = height * window->wl.scale; window->wl.width = width; window->wl.height = height; + wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0); + _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); } void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, @@ -344,6 +431,8 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { _glfwPlatformGetWindowSize(window, width, height); + *width *= window->wl.scale; + *height *= window->wl.scale; } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, From cf6c11cfaa6be44a2ba69f814dc1a022e84e37c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 27 Dec 2015 10:42:45 +0800 Subject: [PATCH 02/42] wayland: Only set surface buffer scale when supported Although very unlikely, the wl_compositor version might not support wl_surface.set_buffer_scale while the wl_output emits a wl_output.scale that is larger than 1. So for correctness, bail on changing the buffer scale if we won't be able to set it later. --- src/wl_init.c | 3 ++- src/wl_platform.h | 2 ++ src/wl_window.c | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wl_init.c b/src/wl_init.c index cceef16ba..90dc507be 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -385,9 +385,10 @@ static void registryHandleGlobal(void* data, { if (strcmp(interface, "wl_compositor") == 0) { + _glfw.wl.wl_compositor_version = min(3, version); _glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface, - min(3, version)); + _glfw.wl.wl_compositor_version); } else if (strcmp(interface, "wl_shm") == 0) { diff --git a/src/wl_platform.h b/src/wl_platform.h index a734ec1e7..2bfdbb4ca 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -91,6 +91,8 @@ typedef struct _GLFWlibraryWayland struct wl_pointer* pointer; struct wl_keyboard* keyboard; + int wl_compositor_version; + struct wl_cursor_theme* cursorTheme; struct wl_surface* cursorSurface; uint32_t pointerSerial; diff --git a/src/wl_window.c b/src/wl_window.c index 00ce7135a..3a75daa42 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -79,6 +79,11 @@ static void checkScaleChange(_GLFWwindow* window) int i; int monitorScale; + // Check if we will be able to set the buffer scale or not. + if (_glfw.wl.wl_compositor_version < + WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + return; + // Get the scale factor from the highest scale monitor. for (i = 0; i < window->wl.monitorsCount; ++i) { From 06899bd9a6345982c9239c8ac0846ac9df3509e7 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Wed, 30 Dec 2015 16:20:40 +0200 Subject: [PATCH 03/42] Fix SetProcessDpiAwareness case mismatch Closes #678. --- src/win32_init.c | 8 ++++---- src/win32_platform.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index 3febdbd6a..c26b93db9 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -102,8 +102,8 @@ static GLFWbool loadLibraries(void) _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); if (_glfw.win32.shcore.instance) { - _glfw.win32.shcore.SetProcessDPIAwareness = (SETPROCESSDPIAWARENESS_T) - GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDPIAwareness"); + _glfw.win32.shcore.SetProcessDpiAwareness = (SETPROCESSDPIAWARENESS_T) + GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); } return GLFW_TRUE; @@ -357,8 +357,8 @@ int _glfwPlatformInit(void) createKeyTables(); - if (_glfw_SetProcessDPIAwareness) - _glfw_SetProcessDPIAwareness(PROCESS_PER_MONITOR_DPI_AWARE); + if (_glfw_SetProcessDpiAwareness) + _glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); else if (_glfw_SetProcessDPIAware) _glfw_SetProcessDPIAware(); diff --git a/src/win32_platform.h b/src/win32_platform.h index 982a07495..427663897 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -138,7 +138,7 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID); // shcore.dll function pointer typedefs typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); -#define _glfw_SetProcessDPIAwareness _glfw.win32.shcore.SetProcessDPIAwareness +#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness #include "win32_joystick.h" @@ -218,7 +218,7 @@ typedef struct _GLFWlibraryWin32 // shcore.dll struct { HINSTANCE instance; - SETPROCESSDPIAWARENESS_T SetProcessDPIAwareness; + SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness; } shcore; } _GLFWlibraryWin32; From d2d57c70e2340d04b69f1db2e3e666ac87cabb85 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 30 Dec 2015 21:05:27 +0100 Subject: [PATCH 04/42] Fix pkg-config file generation regression Fixes regression cased by 37c93ba031e18527f8ca70b8c6e733c63a5e4a30. Fixes #664. Closes #679. --- CMakeLists.txt | 7 +++++++ src/CMakeLists.txt | 8 +------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 780917c10..024fbdca1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,13 @@ if (BUILD_SHARED_LIBS) set(_GLFW_BUILD_DLL 1) endif() +if (BUILD_SHARED_LIBS AND UNIX) + # On Unix-like systems, shared libraries can use the soname system. + set(GLFW_LIB_NAME glfw) +else() + set(GLFW_LIB_NAME glfw3) +endif() + if (GLFW_USE_WAYLAND) set(GLFW_USE_EGL ON) elseif (GLFW_USE_MIR) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d94b4a21..590a10f8e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,6 +52,7 @@ endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) set_target_properties(glfw PROPERTIES + OUTPUT_NAME ${GLFW_LIB_NAME} VERSION ${GLFW_VERSION} SOVERSION ${GLFW_VERSION_MAJOR} POSITION_INDEPENDENT_CODE ON @@ -105,13 +106,6 @@ if (MSVC) target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) endif() -if (BUILD_SHARED_LIBS AND UNIX) - # On Unix-like systems, shared libraries can use the soname system. - set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw) -else() - set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw3) -endif() - if (GLFW_INSTALL) install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) endif() From 80cef675803a2c45a8181858435bb72b26ddf60e Mon Sep 17 00:00:00 2001 From: celestinmarot Date: Thu, 17 Dec 2015 12:38:53 +0100 Subject: [PATCH 05/42] Fix memory leak in X11 key LUT generation Closes #662. --- src/x11_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/x11_init.c b/src/x11_init.c index a2e526e07..52b9d784f 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -311,6 +311,7 @@ static void createKeyTables(void) XkbFreeNames(desc, XkbKeyNamesMask, True); XkbFreeClientMap(desc, 0, True); + XkbFreeKeyboard(desc, 0, True); } for (scancode = 0; scancode < 256; scancode++) From 2cc6caf18287eaa9533ddfb711f867aef06832ce Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 10 Jan 2016 20:08:14 +0100 Subject: [PATCH 06/42] Remove superfluous call --- src/x11_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index 52b9d784f..c890a3261 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -310,7 +310,6 @@ static void createKeyTables(void) } XkbFreeNames(desc, XkbKeyNamesMask, True); - XkbFreeClientMap(desc, 0, True); XkbFreeKeyboard(desc, 0, True); } From d0649e6868eb821cd59e4210812de4806cf09aea Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 27 Jan 2016 03:25:21 +0100 Subject: [PATCH 07/42] Fix confusing legacy parameter names --- include/GLFW/glfw3.h | 6 ++-- src/window.c | 66 ++++++++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 126234215..5201faf68 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1634,8 +1634,8 @@ GLFWAPI void glfwDefaultWindowHints(void); * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is * terminated. * - * @param[in] target The [window hint](@ref window_hints) to set. - * @param[in] hint The new value of the window hint. + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. * * @par Thread Safety * This function must only be called from the main thread. @@ -1647,7 +1647,7 @@ GLFWAPI void glfwDefaultWindowHints(void); * * @ingroup window */ -GLFWAPI void glfwWindowHint(int target, int hint); +GLFWAPI void glfwWindowHint(int hint, int value); /*! @brief Creates a window and its associated context. * diff --git a/src/window.c b/src/window.c index e9e01e50e..eff61be2c 100644 --- a/src/window.c +++ b/src/window.c @@ -270,104 +270,104 @@ void glfwDefaultWindowHints(void) _glfw.hints.refreshRate = GLFW_DONT_CARE; } -GLFWAPI void glfwWindowHint(int target, int hint) +GLFWAPI void glfwWindowHint(int hint, int value) { _GLFW_REQUIRE_INIT(); - switch (target) + switch (hint) { case GLFW_RED_BITS: - _glfw.hints.framebuffer.redBits = hint; + _glfw.hints.framebuffer.redBits = value; break; case GLFW_GREEN_BITS: - _glfw.hints.framebuffer.greenBits = hint; + _glfw.hints.framebuffer.greenBits = value; break; case GLFW_BLUE_BITS: - _glfw.hints.framebuffer.blueBits = hint; + _glfw.hints.framebuffer.blueBits = value; break; case GLFW_ALPHA_BITS: - _glfw.hints.framebuffer.alphaBits = hint; + _glfw.hints.framebuffer.alphaBits = value; break; case GLFW_DEPTH_BITS: - _glfw.hints.framebuffer.depthBits = hint; + _glfw.hints.framebuffer.depthBits = value; break; case GLFW_STENCIL_BITS: - _glfw.hints.framebuffer.stencilBits = hint; + _glfw.hints.framebuffer.stencilBits = value; break; case GLFW_ACCUM_RED_BITS: - _glfw.hints.framebuffer.accumRedBits = hint; + _glfw.hints.framebuffer.accumRedBits = value; break; case GLFW_ACCUM_GREEN_BITS: - _glfw.hints.framebuffer.accumGreenBits = hint; + _glfw.hints.framebuffer.accumGreenBits = value; break; case GLFW_ACCUM_BLUE_BITS: - _glfw.hints.framebuffer.accumBlueBits = hint; + _glfw.hints.framebuffer.accumBlueBits = value; break; case GLFW_ACCUM_ALPHA_BITS: - _glfw.hints.framebuffer.accumAlphaBits = hint; + _glfw.hints.framebuffer.accumAlphaBits = value; break; case GLFW_AUX_BUFFERS: - _glfw.hints.framebuffer.auxBuffers = hint; + _glfw.hints.framebuffer.auxBuffers = value; break; case GLFW_STEREO: - _glfw.hints.framebuffer.stereo = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_DOUBLEBUFFER: - _glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_SAMPLES: - _glfw.hints.framebuffer.samples = hint; + _glfw.hints.framebuffer.samples = value; break; case GLFW_SRGB_CAPABLE: - _glfw.hints.framebuffer.sRGB = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_RESIZABLE: - _glfw.hints.window.resizable = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_DECORATED: - _glfw.hints.window.decorated = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_FOCUSED: - _glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_AUTO_ICONIFY: - _glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_FLOATING: - _glfw.hints.window.floating = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_VISIBLE: - _glfw.hints.window.visible = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_CLIENT_API: - _glfw.hints.context.api = hint; + _glfw.hints.context.api = value; break; case GLFW_CONTEXT_VERSION_MAJOR: - _glfw.hints.context.major = hint; + _glfw.hints.context.major = value; break; case GLFW_CONTEXT_VERSION_MINOR: - _glfw.hints.context.minor = hint; + _glfw.hints.context.minor = value; break; case GLFW_CONTEXT_ROBUSTNESS: - _glfw.hints.context.robustness = hint; + _glfw.hints.context.robustness = value; break; case GLFW_OPENGL_FORWARD_COMPAT: - _glfw.hints.context.forward = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_OPENGL_DEBUG_CONTEXT: - _glfw.hints.context.debug = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_CONTEXT_NO_ERROR: - _glfw.hints.context.noerror = hint ? GLFW_TRUE : GLFW_FALSE; + _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE; break; case GLFW_OPENGL_PROFILE: - _glfw.hints.context.profile = hint; + _glfw.hints.context.profile = value; break; case GLFW_CONTEXT_RELEASE_BEHAVIOR: - _glfw.hints.context.release = hint; + _glfw.hints.context.release = value; break; case GLFW_REFRESH_RATE: - _glfw.hints.refreshRate = hint; + _glfw.hints.refreshRate = value; break; default: _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint"); From 0ebdad53e81ccae31395c2855d641f034a7ad506 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 17:56:36 +0100 Subject: [PATCH 08/42] Add asserts for public API pointer parameters --- src/context.c | 6 ++++++ src/input.c | 34 ++++++++++++++++++++++++++++++++++ src/monitor.c | 13 +++++++++++++ src/window.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/src/context.c b/src/context.c index 3da198649..455beeabd 100644 --- a/src/context.c +++ b/src/context.c @@ -27,6 +27,7 @@ #include "internal.h" +#include #include #include #include @@ -566,6 +567,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void) GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -595,6 +597,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension) { _GLFWwindow* window; + assert(extension); + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); window = _glfwPlatformGetCurrentContext(); @@ -657,6 +661,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension) GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) { + assert(procname); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (!_glfwPlatformGetCurrentContext()) diff --git a/src/input.c b/src/input.c index db33ff729..01184c324 100644 --- a/src/input.c +++ b/src/input.c @@ -27,6 +27,7 @@ #include "internal.h" +#include #include // Internal key state used for sticky keys @@ -239,6 +240,7 @@ GLFWbool _glfwIsPrintable(int key) GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT_OR_RETURN(0); @@ -259,6 +261,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -288,6 +291,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); @@ -310,6 +314,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); @@ -333,6 +338,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); if (xpos) *xpos = 0; @@ -355,6 +361,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -378,6 +385,8 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) { _GLFWcursor* cursor; + assert(image); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); cursor = calloc(1, sizeof(_GLFWcursor)); @@ -462,6 +471,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) { _GLFWwindow* window = (_GLFWwindow*) windowHandle; _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -473,6 +483,8 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); return cbfun; @@ -481,6 +493,8 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); return cbfun; @@ -489,6 +503,8 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); return cbfun; @@ -498,6 +514,8 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, GLFWmousebuttonfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); return cbfun; @@ -507,6 +525,8 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, GLFWcursorposfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); return cbfun; @@ -516,6 +536,8 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, GLFWcursorenterfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); return cbfun; @@ -525,6 +547,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, GLFWscrollfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); return cbfun; @@ -533,6 +557,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); return cbfun; @@ -553,6 +579,7 @@ GLFWAPI int glfwJoystickPresent(int joy) GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) { + assert(count); *count = 0; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -568,6 +595,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count) { + assert(count); *count = 0; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -597,6 +625,10 @@ GLFWAPI const char* glfwGetJoystickName(int joy) GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + + assert(string); + _GLFW_REQUIRE_INIT(); _glfwPlatformSetClipboardString(window, string); } @@ -604,6 +636,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return _glfwPlatformGetClipboardString(window); } diff --git a/src/monitor.c b/src/monitor.c index f9ab7b0d2..1aebf0ba8 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -27,6 +27,7 @@ #include "internal.h" +#include #include #include #include @@ -293,6 +294,7 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) { + assert(count); *count = 0; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -314,6 +316,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); if (xpos) *xpos = 0; @@ -328,6 +331,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); if (widthMM) *widthMM = 0; @@ -345,6 +349,8 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return monitor->name; } @@ -359,7 +365,9 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); + assert(count); *count = 0; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -374,6 +382,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -422,6 +431,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -434,6 +444,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor); + + assert(ramp); _GLFW_REQUIRE_INIT(); diff --git a/src/window.c b/src/window.c index eff61be2c..f0063e359 100644 --- a/src/window.c +++ b/src/window.c @@ -28,6 +28,7 @@ #include "internal.h" +#include #include #include @@ -124,6 +125,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, _GLFWwindow* window; _GLFWwindow* previous; + assert(title); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (width <= 0 || height <= 0) @@ -415,6 +418,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(0); return window->closed; } @@ -422,6 +427,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT(); window->closed = value; } @@ -429,6 +436,10 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + + assert(title); + _GLFW_REQUIRE_INIT(); _glfwPlatformSetWindowTitle(window, title); } @@ -436,6 +447,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); if (xpos) *xpos = 0; @@ -449,6 +461,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -465,6 +478,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); if (width) *width = 0; @@ -478,6 +492,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -495,6 +510,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, int maxwidth, int maxheight) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -509,6 +525,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -527,6 +544,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); if (width) *width = 0; @@ -542,6 +560,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, int* right, int* bottom) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); if (left) *left = 0; @@ -559,6 +578,8 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT(); _glfwPlatformIconifyWindow(window); } @@ -566,6 +587,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT(); _glfwPlatformRestoreWindow(window); } @@ -573,6 +596,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) GLFWAPI void glfwShowWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -585,6 +609,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle) GLFWAPI void glfwHideWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT(); @@ -597,6 +622,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); _GLFW_REQUIRE_INIT_OR_RETURN(0); @@ -643,6 +669,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return (GLFWmonitor*) window->monitor; } @@ -650,6 +678,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT(); window->userPointer = pointer; } @@ -657,6 +687,8 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return window->userPointer; } @@ -665,6 +697,8 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, GLFWwindowposfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); return cbfun; @@ -674,6 +708,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWwindowsizefun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); return cbfun; @@ -683,6 +719,8 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, GLFWwindowclosefun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); return cbfun; @@ -692,6 +730,8 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, GLFWwindowrefreshfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); return cbfun; @@ -701,6 +741,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, GLFWwindowfocusfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); return cbfun; @@ -710,6 +752,8 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, GLFWwindowiconifyfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); return cbfun; @@ -719,6 +763,8 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle GLFWframebuffersizefun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); return cbfun; From 12d49eaf6c9146be221f4204bfaa20aa73dd8c11 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 18:00:22 +0100 Subject: [PATCH 09/42] Update changelog --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1f003ba20..fcf4bf344 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ used by the tests and examples and are not required to build the library. - [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned - [X11] Bugfix: Monitor connection and disconnection events were not reported - [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end + - [X11] Bugfix: An XKB structure was leaked during `glfwInit` - [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate` - [WGL] Changed extension loading to only be performed once - [WGL] Removed dependency on external WGL headers From 276b1bc07a0532adc34eb8dcf3b6a55f79fc8585 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 19:17:18 +0100 Subject: [PATCH 10/42] Add check for EGL specific buffer swap issue Fixes #675. --- README.md | 2 ++ include/GLFW/glfw3.h | 3 +++ src/egl_context.c | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/README.md b/README.md index fcf4bf344..43c1abcad 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ used by the tests and examples and are not required to build the library. - [GLX] Bugfix: NetBSD does not provide `libGL.so.1` - [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling whether to use an existing `EGL/eglplatform.h` header + - [EGL] Added and documented test for if the context is current on the calling + thread during buffer swap - [EGL] Removed dependency on external EGL headers diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 5201faf68..a1f058f8d 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3429,6 +3429,9 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); * * @param[in] window The window whose buffers to swap. * + * @remarks __EGL:__ The context of the specified window must be current on the + * calling thread. + * * @par Thread Safety * This function may be called from any thread. * diff --git a/src/egl_context.c b/src/egl_context.c index 0eb0aa417..579e17f10 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -584,6 +584,13 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window) { + if (window != _glfwPlatformGetCurrentContext()) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: The context must be current on the calling thread when swapping buffers"); + return; + } + eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); } From 7e91b26bb1fadd5a8df766508b0a3e1623a72c4e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 6 Jul 2015 18:17:19 +0200 Subject: [PATCH 11/42] Add initial CONTRIBUTING.md --- CONTRIBUTING.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..057518788 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contribution Guide + +This file is a work in progress and you can report errors or submit patches for +it the same as any other file. + + +## Reporting a bug + +If GLFW is behaving unexpectedly, make sure you have set an error callback. +GLFW will often tell you the cause of an issue via this callback. + +If GLFW is crashing or triggering asserts, make sure that all your object +handles and other pointers are valid. + +Always include the __operating system name and version__ (i.e. `Windows +7 64-bit`). If you are using an official release of GLFW, include the __GLFW +release version__ (i.e. `3.1.2`), otherwise include the __GLFW commit ID__ (i.e. +`3795d78b14ef06008889cc422a1fb8d642597751`) from Git. If possible, please also +include the __GLFW version string__ (`"3.2.0 X11 EGL clock_gettime /dev/js XI +Xf86vm"`), as returned by glfwGetVersionString. + + +### Reporting a compile or link bug + +In addition to the information above, always include the complete build log. +Issue posts are editable so it can always be shortened later. + + +### Reporting a context creation bug + +__Note:__ Windows ships with graphics drivers that do not support OpenGL. If +GLFW says that your machine lacks support for OpenGL, it very likely does. + +__Note:__ AMD only supports OpenGL ES on Windows via EGL, which is not enabled +in GLFW by default. You need to enable EGL when compiling GLFW to use this. + +The `glfwinfo` tool lets you request any kind of context and framebuffer format +supported by the GLFW API without having to recompile. If context creation +fails in your application, please verify that it also fails with this tool +before reporting it as a bug. + +In addition to the information above, always include the __GPU model and driver +version__ (i.e. `GeForce GTX660 with 352.79`) when reporting this kind of bug. + + +### Reporting a monitor or video mode bug + +__Note:__ On headless systems on some platforms, no monitors are reported. This +causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are +prepared for. + +The `monitors` tool lists all information about connected monitors made +available by GLFW. + +In addition to the information above, if possible please also include the output +of the `monitors` tool when reporting this kind of bug. + + +### Reporting a window event bug + +The `events` tool prints all information provided to every callback supported by +GLFW as events occur. Each event is listed with the time and a unique number +to make discussions about event logs easier. The tool has command-line options +for creating multiple windows and full screen windows. + + +### Reporting a documentation bug + +If you found the error in the generated documentation then it's fine to just +link to that webpage. You don't need to figure out which documentation source +file the text comes from. + + +## Contributing a bug fix + +There should be text here, but there isn't. + + +## Contributing a feature + +This is not (yet) the text you are looking for. + From e94fa1c9b317bd3747de056ef73408a0a728857a Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 20:14:10 +0100 Subject: [PATCH 12/42] Contribution guide work --- CONTRIBUTING.md | 52 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 057518788..a73c65e00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,17 +13,19 @@ If GLFW is crashing or triggering asserts, make sure that all your object handles and other pointers are valid. Always include the __operating system name and version__ (i.e. `Windows -7 64-bit`). If you are using an official release of GLFW, include the __GLFW -release version__ (i.e. `3.1.2`), otherwise include the __GLFW commit ID__ (i.e. -`3795d78b14ef06008889cc422a1fb8d642597751`) from Git. If possible, please also -include the __GLFW version string__ (`"3.2.0 X11 EGL clock_gettime /dev/js XI -Xf86vm"`), as returned by glfwGetVersionString. +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (i.e. `3.1.2`), otherwise include the +__GLFW commit ID__ (i.e. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. +If possible, please also include the __GLFW version string__ (`3.2.0 X11 EGL +clock_gettime /dev/js XI Xf86vm`), as described +[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string). ### Reporting a compile or link bug -In addition to the information above, always include the complete build log. -Issue posts are editable so it can always be shortened later. +In addition to the information above, always include the complete build log from +your compiler and linker. Issue posts are editable so it can always be +shortened later. ### Reporting a context creation bug @@ -34,13 +36,15 @@ GLFW says that your machine lacks support for OpenGL, it very likely does. __Note:__ AMD only supports OpenGL ES on Windows via EGL, which is not enabled in GLFW by default. You need to enable EGL when compiling GLFW to use this. -The `glfwinfo` tool lets you request any kind of context and framebuffer format -supported by the GLFW API without having to recompile. If context creation -fails in your application, please verify that it also fails with this tool -before reporting it as a bug. +The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c` +and is built along with the library. It lets you request any kind of context +and framebuffer format supported by the GLFW API without having to recompile. +If context creation fails in your application, please verify that it also fails +with this tool before reporting it as a bug. -In addition to the information above, always include the __GPU model and driver -version__ (i.e. `GeForce GTX660 with 352.79`) when reporting this kind of bug. +In addition to the information above (OS and GLFW version), always include the +__GPU model and driver version__ (i.e. `GeForce GTX660 with 352.79`) when +reporting this kind of bug. ### Reporting a monitor or video mode bug @@ -49,19 +53,25 @@ __Note:__ On headless systems on some platforms, no monitors are reported. This causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are prepared for. -The `monitors` tool lists all information about connected monitors made -available by GLFW. +The `monitors` tool is included in the GLFW source tree as `tests/monitors.c` +and is built along with the library. lists all information about connected +monitors made available by GLFW. -In addition to the information above, if possible please also include the output -of the `monitors` tool when reporting this kind of bug. +In addition to the information above (OS and GLFW version), please also include +the output of the `monitors` tool when reporting this kind of bug. If it +doesn't work at all, please mention this. ### Reporting a window event bug -The `events` tool prints all information provided to every callback supported by -GLFW as events occur. Each event is listed with the time and a unique number -to make discussions about event logs easier. The tool has command-line options -for creating multiple windows and full screen windows. +__Note:__ While GLFW tries to provide the exact same behavior between platforms, +the exact ordering of related window events will sometimes differ. + +The `events` tool is included in the GLFW source tree as `tests/events.c` and is +built along with the library. It prints all information provided to every +callback supported by GLFW as events occur. Each event is listed with the time +and a unique number to make discussions about event logs easier. The tool has +command-line options for creating multiple windows and full screen windows. ### Reporting a documentation bug From 5499fd307a6a57349a374f147023ad2f45c0171f Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 20:22:53 +0100 Subject: [PATCH 13/42] Contribution guide work --- CONTRIBUTING.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a73c65e00..fbe09669b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,10 @@ clock_gettime /dev/js XI Xf86vm`), as described ### Reporting a compile or link bug +__Note:__ GLFW needs many system APIs to do its job. See the [Building +applications](http://www.glfw.org/docs/latest/build.html) guide for more +information. + In addition to the information above, always include the complete build log from your compiler and linker. Issue posts are editable so it can always be shortened later. @@ -32,9 +36,15 @@ shortened later. __Note:__ Windows ships with graphics drivers that do not support OpenGL. If GLFW says that your machine lacks support for OpenGL, it very likely does. +Install drivers from the computer manufacturer or graphics card manufacturer +([Nvidia](http://www.geforce.com/drivers), + [AMD](http://support.amd.com/en-us/download), + [Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to +fix this. -__Note:__ AMD only supports OpenGL ES on Windows via EGL, which is not enabled -in GLFW by default. You need to enable EGL when compiling GLFW to use this. +__Note:__ AMD only supports OpenGL ES on Windows via EGL. EGL support is not +enabled in GLFW by default. You need to [enable EGL when +compiling](http://www.glfw.org/docs/latest/compile.html) GLFW to use this. The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c` and is built along with the library. It lets you request any kind of context @@ -53,6 +63,10 @@ __Note:__ On headless systems on some platforms, no monitors are reported. This causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are prepared for. +__Note:__ Some third-party tools report more video modes than those approved of +by the OS. For safety and compatbility, GLFW only reports video modes the OS +wants programs to use. This is not a bug. + The `monitors` tool is included in the GLFW source tree as `tests/monitors.c` and is built along with the library. lists all information about connected monitors made available by GLFW. From 951a9583faf91bdbe96bacd5d24a8969c0cca418 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 21:32:14 +0100 Subject: [PATCH 14/42] Add Doxygen aliases for custom paragraphs --- docs/Doxyfile.in | 9 +- include/GLFW/glfw3.h | 581 ++++++++++++++----------------------- include/GLFW/glfw3native.h | 154 +++++----- 3 files changed, 296 insertions(+), 448 deletions(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index ed304d3a3..c27629ee9 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -195,7 +195,14 @@ TAB_SIZE = 8 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = "thread_safety=@par Thread safety\n" \ + "pointer_lifetime=@par Pointer lifetime\n" \ + "analysis=@par Analysis\n" \ + "reentrancy=@par Reentrancy\n" \ + "glfw3=@par\n__GLFW 3:__" \ + "x11=__X11:__" \ + "win32=__Windows:__" \ + "osx=__OS X:__" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index a1f058f8d..2e78c98a2 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -497,9 +497,8 @@ extern "C" { * This occurs if a GLFW function was called that must not be called unless the * library is [initialized](@ref intro_init). * - * @par Analysis - * Application programmer error. Initialize GLFW before calling any function - * that requires initialization. + * @analysis Application programmer error. Initialize GLFW before calling any + * function that requires initialization. */ #define GLFW_NOT_INITIALIZED 0x00010001 /*! @brief No context is current for this thread. @@ -508,9 +507,8 @@ extern "C" { * current OpenGL or OpenGL ES context but no context is current on the calling * thread. One such function is @ref glfwSwapInterval. * - * @par Analysis - * Application programmer error. Ensure a context is current before calling - * functions that require a current context. + * @analysis Application programmer error. Ensure a context is current before + * calling functions that require a current context. */ #define GLFW_NO_CURRENT_CONTEXT 0x00010002 /*! @brief One of the arguments to the function was an invalid enum value. @@ -519,8 +517,7 @@ extern "C" { * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref * glfwGetWindowAttrib. * - * @par Analysis - * Application programmer error. Fix the offending call. + * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_ENUM 0x00010003 /*! @brief One of the arguments to the function was an invalid value. @@ -531,17 +528,15 @@ extern "C" { * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead * result in a @ref GLFW_VERSION_UNAVAILABLE error. * - * @par Analysis - * Application programmer error. Fix the offending call. + * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_VALUE 0x00010004 /*! @brief A memory allocation failed. * * A memory allocation failed. * - * @par Analysis - * A bug in GLFW or the underlying operating system. Report the bug to our - * [issue tracker](https://github.com/glfw/glfw/issues). + * @analysis A bug in GLFW or the underlying operating system. Report the bug + * to our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_OUT_OF_MEMORY 0x00010005 /*! @brief GLFW could not find support for the requested client API on the @@ -551,10 +546,9 @@ extern "C" { * emitted by functions other than @ref glfwCreateWindow, no supported client * API was found. * - * @par Analysis - * The installed graphics driver does not support the requested client API, or - * does not support it via the chosen context creation backend. Below are - * a few examples. + * @analysis The installed graphics driver does not support the requested + * client API, or does not support it via the chosen context creation backend. + * Below are a few examples. * * @par * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only @@ -569,10 +563,9 @@ extern "C" { * The requested OpenGL or OpenGL ES version (including any requested context * or framebuffer hints) is not available on this machine. * - * @par Analysis - * The machine does not support your requirements. If your application is - * sufficiently flexible, downgrade your requirements and try again. - * Otherwise, inform the user that their machine does not match your + * @analysis The machine does not support your requirements. If your + * application is sufficiently flexible, downgrade your requirements and try + * again. Otherwise, inform the user that their machine does not match your * requirements. * * @par @@ -588,10 +581,9 @@ extern "C" { * A platform-specific error occurred that does not match any of the more * specific categories. * - * @par Analysis - * A bug or configuration error in GLFW, the underlying operating system or - * its drivers, or a lack of required resources. Report the issue to our - * [issue tracker](https://github.com/glfw/glfw/issues). + * @analysis A bug or configuration error in GLFW, the underlying operating + * system or its drivers, or a lack of required resources. Report the issue to + * our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_PLATFORM_ERROR 0x00010008 /*! @brief The requested format is not supported or available. @@ -602,8 +594,7 @@ extern "C" { * If emitted when querying the clipboard, the contents of the clipboard could * not be converted to the requested format. * - * @par Analysis - * If emitted during window creation, one or more + * @analysis If emitted during window creation, one or more * [hard constraints](@ref window_hints_hard) did not match any of the * available pixel formats. If your application is sufficiently flexible, * downgrade your requirements and try again. Otherwise, inform the user that @@ -619,8 +610,7 @@ extern "C" { * A window that does not have an OpenGL or OpenGL ES context was passed to * a function that requires it to have one. * - * @par Analysis - * Application programmer error. Fix the offending call. + * @analysis Application programmer error. Fix the offending call. */ #define GLFW_NO_WINDOW_CONTEXT 0x0001000A /*! @} */ @@ -1180,13 +1170,12 @@ typedef struct GLFWimage * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @remarks __OS X:__ This function will change the current directory of the + * @remark @osx This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with a * [compile-time option](@ref compile_options_osx). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwTerminate @@ -1209,16 +1198,14 @@ GLFWAPI int glfwInit(void); * call this function, as it is called by @ref glfwInit before it returns * failure. * - * @remarks This function may be called before @ref glfwInit. + * @remark This function may be called before @ref glfwInit. * * @warning The contexts of any remaining windows must not be current on any * other thread when this function is called. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwInit @@ -1242,10 +1229,9 @@ GLFWAPI void glfwTerminate(void); * @param[out] minor Where to store the minor version number, or `NULL`. * @param[out] rev Where to store the revision number, or `NULL`. * - * @remarks This function may be called before @ref glfwInit. + * @remark This function may be called before @ref glfwInit. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersionString @@ -1271,13 +1257,11 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); * * @return The GLFW version string. * - * @remarks This function may be called before @ref glfwInit. + * @remark This function may be called before @ref glfwInit. * - * @par Pointer Lifetime - * The returned string is static and compile-time generated. + * @pointer_lifetime The returned string is static and compile-time generated. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersion @@ -1308,10 +1292,9 @@ GLFWAPI const char* glfwGetVersionString(void); * callback. * @return The previously set callback, or `NULL` if no callback was set. * - * @remarks This function may be called before @ref glfwInit. + * @remark This function may be called before @ref glfwInit. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref error_handling * @@ -1332,13 +1315,11 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); * @return An array of monitor handles, or `NULL` if no monitors were found or * if an [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is guaranteed to be valid only until the monitor configuration - * changes or the library is terminated. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * monitor configuration changes or the library is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_monitors * @sa @ref monitor_event @@ -1358,10 +1339,9 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); * @return The primary monitor, or `NULL` if no monitors were found or if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * - * @remarks The primary monitor is always first in the array returned by @ref + * @remark The primary monitor is always first in the array returned by @ref * glfwGetMonitors. * * @sa @ref monitor_monitors @@ -1385,8 +1365,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * @@ -1415,11 +1394,10 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * @param[out] heightMM Where to store the height, in millimetres, of the * monitor's display area, or `NULL`. * - * @remarks __Windows:__ The OS calculates the returned physical size from the + * @remark @win32 calculates the returned physical size from the * current resolution and system DPI instead of querying the monitor EDID data. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * @@ -1439,13 +1417,11 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * @return The UTF-8 encoded name of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * @@ -1466,8 +1442,7 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_event * @@ -1490,21 +1465,18 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); * @return An array of video modes, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected, this - * function is called again for that monitor or the library is terminated. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected, this function is called again for that monitor or the library + * is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoMode * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Changed to return an array of modes for a specific monitor. + * @glfw3 Changed to return an array of modes for a specific monitor. * * @ingroup monitor */ @@ -1520,13 +1492,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); * @return The current mode of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoModes @@ -1546,8 +1516,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * @@ -1565,14 +1534,12 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned structure and its arrays are allocated and freed by GLFW. You - * should not free them yourself. They are valid until the specified monitor - * is disconnected, this function is called again for that monitor or the - * library is terminated. + * @pointer_lifetime The returned structure and its arrays are allocated and + * freed by GLFW. You should not free them yourself. They are valid until the + * specified monitor is disconnected, this function is called again for that + * monitor or the library is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * @@ -1591,16 +1558,15 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * - * @remarks Gamma ramp sizes other than 256 are not supported by all platforms + * @remark Gamma ramp sizes other than 256 are not supported by all platforms * or graphics hardware. * - * @remarks __Windows:__ The gamma ramp size must be 256. + * @remark @win32 The gamma ramp size must be 256. * - * @par Pointer Lifetime - * The specified gamma ramp is copied before this function returns. + * @pointer_lifetime The specified gamma ramp is copied before this function + * returns. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * @@ -1615,8 +1581,7 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); * This function resets all window hints to their * [default values](@ref window_hints_values). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwWindowHint @@ -1637,8 +1602,7 @@ GLFWAPI void glfwDefaultWindowHints(void); * @param[in] hint The [window hint](@ref window_hints) to set. * @param[in] value The new value of the window hint. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwDefaultWindowHints @@ -1708,52 +1672,50 @@ GLFWAPI void glfwWindowHint(int hint, int value); * @return The handle of the created window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @remarks __Windows:__ Window creation will fail if the Microsoft GDI - * software OpenGL implementation is the only one available. + * @remark @win32 Window creation will fail if the Microsoft GDI software + * OpenGL implementation is the only one available. * - * @remarks __Windows:__ If the executable has an icon resource named - * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is - * present, the `IDI_WINLOGO` icon will be used instead. + * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` + * it will be set as the icon for the window. If no such icon is present, the + * `IDI_WINLOGO` icon will be used instead. * - * @remarks __Windows:__ The context to share resources with must not be - * current on any other thread. + * @remark @win32 The context to share resources with must not be current on + * any other thread. * - * @remarks __OS X:__ The GLFW window has no icon, as it is not a document + * @remark @osx The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * - * @remarks __OS X:__ The first time a window is created the menu bar is - * populated with common commands like Hide, Quit and About. The About entry - * opens a minimal about dialog with information from the application's bundle. - * The menu bar can be disabled with a + * @remark @osx The first time a window is created the menu bar is populated + * with common commands like Hide, Quit and About. The About entry opens + * a minimal about dialog with information from the application's bundle. The + * menu bar can be disabled with a * [compile-time option](@ref compile_options_osx). * - * @remarks __OS X:__ On OS X 10.10 and later the window frame will not be - * rendered at full resolution on Retina displays unless the - * `NSHighResolutionCapable` key is enabled in the application bundle's - * `Info.plist`. For more information, see + * @remark @osx On OS X 10.10 and later the window frame will not be rendered + * at full resolution on Retina displays unless the `NSHighResolutionCapable` + * key is enabled in the application bundle's `Info.plist`. For more + * information, see * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) * in the Mac Developer Library. The GLFW test and example programs use * a custom `Info.plist` template for this, which can be found as * `CMake/MacOSXBundleInfo.plist.in` in the source tree. * - * @remarks __X11:__ There is no mechanism for setting the window icon yet. + * @remark @x11 There is no mechanism for setting the window icon yet. * - * @remarks __X11:__ Some window managers will not respect the placement of + * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * - * @remarks __X11:__ Due to the asynchronous nature of X11, it may take - * a moment for a window to reach its requested state. This means you may not - * be able to query the final size, position or other attributes directly after - * window creation. + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * a window to reach its requested state. This means you may not be able to + * query the final size, position or other attributes directly after window + * creation. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwDestroyWindow @@ -1777,11 +1739,9 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G * @note The context of the specified window must not be current on any other * thread when this function is called. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwCreateWindow @@ -1799,8 +1759,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); * @param[in] window The window to query. * @return The value of the close flag. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_close * @@ -1819,8 +1779,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); * @param[in] window The window whose flag to change. * @param[in] value The new value. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_close * @@ -1838,18 +1798,15 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * @param[in] window The window whose title to change. * @param[in] title The UTF-8 encoded window title. * - * @remarks __OS X:__ The window title will not be updated until the next time - * you process events. + * @remark @osx The window title will not be updated until the next time you + * process events. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1869,8 +1826,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the client area, or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwSetWindowPos @@ -1897,16 +1853,13 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwGetWindowPos * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1927,16 +1880,13 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * @param[out] height Where to store the height, in screen coordinates, of the * client area, or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwSetWindowSize * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1961,11 +1911,10 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); * @param[in] maxheight The maximum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * - * @remarks If you set size limits and an aspect ratio that conflict, the + * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowAspectRatio @@ -1998,11 +1947,10 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe * @param[in] denom The denominator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * - * @remarks If you set size limits and an aspect ratio that conflict, the + * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowSizeLimits @@ -2030,16 +1978,13 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * @param[in] width The desired width of the specified window. * @param[in] height The desired height of the specified window. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwGetWindowSize * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -2060,8 +2005,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); * @param[out] height Where to store the height, in pixels, of the framebuffer, * or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback @@ -2096,8 +2040,7 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height) * @param[out] bottom Where to store the size, in screen coordinates, of the * bottom edge of the window frame, or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @@ -2118,16 +2061,13 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * * @param[in] window The window to iconify. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwRestoreWindow * * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -2143,16 +2083,13 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); * * @param[in] window The window to restore. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow * * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -2166,8 +2103,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); * * @param[in] window The window to make visible. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwHideWindow @@ -2186,8 +2122,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window); * * @param[in] window The window to hide. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwShowWindow @@ -2207,8 +2142,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * @return The monitor, or `NULL` if the window is in windowed mode or an error * occurred. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor * @@ -2229,16 +2163,15 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @return The value of the attribute, or zero if an * [error](@ref error_handling) occurred. * - * @remarks Framebuffer related hints are not window attributes. See @ref + * @remark Framebuffer related hints are not window attributes. See @ref * window_attribs_fb for more information. * - * @remarks Zero is a valid value for many window and context related + * @remark Zero is a valid value for many window and context related * attributes so you cannot use a return value of zero as an indication of * errors. However, this function should not fail as long as it is passed * valid arguments and the library has been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs * @@ -2258,8 +2191,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @param[in] window The window whose pointer to set. * @param[in] pointer The new value. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_userptr * @sa glfwGetWindowUserPointer @@ -2277,8 +2210,8 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); * * @param[in] window The window whose pointer to return. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_userptr * @sa glfwSetWindowUserPointer @@ -2301,8 +2234,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @@ -2324,15 +2256,12 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup window */ @@ -2355,18 +2284,15 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @remarks __OS X:__ Selecting Quit from the application menu will - * trigger the close callback for all windows. + * @remark @osx Selecting Quit from the application menu will trigger the close + * callback for all windows. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_close * * @since Added in GLFW 2.5. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup window */ @@ -2388,15 +2314,12 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_refresh * * @since Added in GLFW 2.5. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup window */ @@ -2418,8 +2341,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * @@ -2440,8 +2362,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @@ -2462,8 +2383,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * @@ -2491,11 +2411,9 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * * Event processing is not required for joystick input to work. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwWaitEvents @@ -2534,11 +2452,9 @@ GLFWAPI void glfwPollEvents(void); * * Event processing is not required for joystick input to work. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents @@ -2558,8 +2474,7 @@ GLFWAPI void glfwWaitEvents(void); * of threads in applications that do not create windows, use your threading * library of choice. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref events * @sa glfwWaitEvents @@ -2580,8 +2495,7 @@ GLFWAPI void glfwPostEmptyEvent(void); * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa glfwSetInputMode * @@ -2626,8 +2540,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * `GLFW_STICKY_MOUSE_BUTTONS`. * @param[in] value The new value of the specified input mode. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa glfwGetInputMode * @@ -2648,13 +2561,11 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); * @param[in] scancode The scancode of the key to query. * @return The localized name of the key. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the next call to @ref glfwGetKeyName, or until - * the library is terminated. + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetKeyName, or until the library is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key_name * @@ -2690,15 +2601,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * not a valid key for this function. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup input */ @@ -2719,15 +2627,12 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * @param[in] button The desired [mouse button](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup input */ @@ -2757,8 +2662,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * @param[out] ypos Where to store the cursor y-coordinate, relative to the to * top edge of the client area, or `NULL`. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwSetCursorPos @@ -2792,12 +2696,11 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @param[in] ypos The desired y-coordinate, relative to the top edge of the * client area. * - * @remarks __X11:__ Due to the asynchronous nature of X11, it may take - * a moment for the window focus event to arrive. This means you may not be - * able to set the cursor position directly after window creation. + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * the window focus event to arrive. This means you may not be able to set the + * cursor position directly after window creation. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwGetCursorPos @@ -2829,14 +2732,12 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The specified image data is copied before this function returns. + * @pointer_lifetime The specified image data is copied before this function + * returns. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwDestroyCursor @@ -2858,11 +2759,9 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor @@ -2881,11 +2780,9 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); * * @param[in] cursor The cursor object to destroy. * - * @par Reentrancy - * This function must not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor @@ -2910,8 +2807,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); * @param[in] cursor The cursor to set, or `NULL` to switch back to the default * arrow cursor. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @@ -2951,15 +2847,12 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup input */ @@ -2990,15 +2883,12 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * * @since Added in GLFW 2.4. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup input */ @@ -3025,8 +2915,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or an * error occurred. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * @@ -3053,15 +2942,12 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @glfw3 Added window handle parameter. Updated callback signature. * * @ingroup input */ @@ -3080,8 +2966,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @@ -3103,8 +2988,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_enter * @@ -3129,8 +3013,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref scrolling * @@ -3156,8 +3039,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop * @@ -3174,8 +3056,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); * @param[in] joy The [joystick](@ref joysticks) to query. * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick * @@ -3195,13 +3076,12 @@ GLFWAPI int glfwJoystickPresent(int joy); * array. This is set to zero if an error occurred. * @return An array of axis values, or `NULL` if the joystick is not present. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_axis * @@ -3221,20 +3101,17 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); * array. This is set to zero if an error occurred. * @return An array of button states, or `NULL` if the joystick is not present. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_button * * @since Added in GLFW 2.2. - * - * @par - * __GLFW 3:__ Changed to return a dynamic array. + * @glfw3 Changed to return a dynamic array. * * @ingroup input */ @@ -3250,13 +3127,12 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_name * @@ -3274,11 +3150,10 @@ GLFWAPI const char* glfwGetJoystickName(int joy); * @param[in] window The window that will own the clipboard contents. * @param[in] string A UTF-8 encoded string. * - * @par Pointer Lifetime - * The specified string is copied before this function returns. + * @pointer_lifetime The specified string is copied before this function + * returns. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwGetClipboardString @@ -3300,14 +3175,12 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the next call to @ref + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library * is terminated. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwSetClipboardString @@ -3331,8 +3204,8 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); * @return The current value, in seconds, or zero if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref time * @@ -3350,12 +3223,11 @@ GLFWAPI double glfwGetTime(void); * * @param[in] time The new value, in seconds. * - * @remarks The upper limit of the timer is calculated as + * @remark The upper limit of the timer is calculated as * floor((264 - 1) / 109) and is due to implementations * storing nanoseconds in 64 bits. The limit may be increased in the future. * - * @par Thread Safety - * This function must only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref time * @@ -3385,8 +3257,7 @@ GLFWAPI void glfwSetTime(double time); * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwGetCurrentContext @@ -3405,8 +3276,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); * @return The window whose context is current, or `NULL` if no window's * context is current. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwMakeContextCurrent @@ -3429,19 +3299,16 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); * * @param[in] window The window whose buffers to swap. * - * @remarks __EGL:__ The context of the specified window must be current on the + * @remark __EGL:__ The context of the specified window must be current on the * calling thread. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapInterval * * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -3468,17 +3335,16 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); * @param[in] interval The minimum number of screen updates to wait for * until the buffers are swapped by @ref glfwSwapBuffers. * - * @remarks This function is not called during context creation, leaving the + * @remark This function is not called during context creation, leaving the * swap interval set to whatever is the default on that platform. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * - * @remarks Some GPU drivers do not honor the requested swap interval, either + * @remark Some GPU drivers do not honor the requested swap interval, either * because of a user setting that overrides the application's request or due to * bugs in the driver. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapBuffers @@ -3508,8 +3374,7 @@ GLFWAPI void glfwSwapInterval(int interval); * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` * otherwise. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwGetProcAddress @@ -3534,19 +3399,17 @@ GLFWAPI int glfwExtensionSupported(const char* extension); * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * - * @remarks The address of a given function is not guaranteed to be the same + * @remark The address of a given function is not guaranteed to be the same * between contexts. * - * @remarks This function may return a non-`NULL` address despite the + * @remark This function may return a non-`NULL` address despite the * associated version or extension not being available. Always check the * context version or extension string first. * - * @par Pointer Lifetime - * The returned function pointer is valid until the context is destroyed or the - * library is terminated. + * @pointer_lifetime The returned function pointer is valid until the context + * is destroyed or the library is terminated. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwExtensionSupported diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index c68e31a70..db75eacd4 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -127,11 +127,10 @@ extern "C" { * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in GLFW 3.1. * * @ingroup native */ @@ -143,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in GLFW 3.1. * * @ingroup native */ @@ -158,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -175,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -192,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in GLFW 3.1. * * @ingroup native */ @@ -207,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -224,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -241,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -256,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void); * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in GLFW 3.1. * * @ingroup native */ @@ -271,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in GLFW 3.1. * * @ingroup native */ @@ -286,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -303,11 +292,10 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -318,11 +306,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -335,11 +322,10 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); * @return The `struct wl_display*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -350,11 +336,10 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); * @return The `struct wl_output*` of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -365,11 +350,10 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); * @return The main `struct wl_surface*` of the specified window, or `NULL` if * an [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -382,11 +366,10 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); * @return The `MirConnection*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -397,11 +380,10 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void); * @return The Mir output ID of the specified monitor, or zero if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -412,11 +394,10 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); * @return The `MirSurface*` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.2. + * @since Added in GLFW 3.2. * * @ingroup native */ @@ -429,11 +410,10 @@ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window); * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -444,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ @@ -459,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in GLFW 3.0. * * @ingroup native */ From 832c2ffa3b4a34f984de0c4a7bd4d3a84fd172af Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 31 Jan 2016 22:35:11 +0100 Subject: [PATCH 15/42] History work --- docs/moving.dox | 12 ++ include/GLFW/glfw3.h | 234 +++++++++++++++++++------------------ include/GLFW/glfw3native.h | 44 +++---- 3 files changed, 155 insertions(+), 135 deletions(-) diff --git a/docs/moving.dox b/docs/moving.dox index 49709d4b1..a222a3572 100644 --- a/docs/moving.dox +++ b/docs/moving.dox @@ -61,6 +61,9 @@ used from any thread and which must only be used from the main thread. `glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, `glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. +@par Removed types +`GLFWthreadfun` + @subsection moving_image Removal of image and texture loading @@ -467,6 +470,15 @@ defining `GLFW_INCLUDE_GLU` before the inclusion of the GLFW header. | `glfwGetDesktopMode` | @ref glfwGetVideoMode | Returns the current mode of a monitor | | `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons | + +@subsection moving_renamed_types Renamed types + +| GLFW 2 | GLFW 3 | Notes | +| ------------------- | --------------------- | | +| `GLFWmousewheelfun` | @ref GLFWscrollfun | | +| `GLFWmouseposfun` | @ref GLFWcursorposfun | | + + @subsection moving_renamed_tokens Renamed tokens | GLFW 2 | GLFW 3 | Notes | diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 2e78c98a2..6ca49fa2d 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -732,8 +732,8 @@ extern "C" { * @sa @ref context_glext * @sa glfwGetProcAddress * - * @since Added in GLFW 3.0. - * + * @since Added in version 3.0. + * @ingroup context */ typedef void (*GLFWglproc)(void); @@ -744,7 +744,7 @@ typedef void (*GLFWglproc)(void); * * @see @ref monitor_object * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -756,7 +756,7 @@ typedef struct GLFWmonitor GLFWmonitor; * * @see @ref window_object * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -768,7 +768,7 @@ typedef struct GLFWwindow GLFWwindow; * * @see @ref cursor_object * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup cursor */ @@ -784,7 +784,7 @@ typedef struct GLFWcursor GLFWcursor; * @sa @ref error_handling * @sa glfwSetErrorCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup init */ @@ -803,7 +803,7 @@ typedef void (* GLFWerrorfun)(int,const char*); * @sa @ref window_pos * @sa glfwSetWindowPosCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -820,7 +820,8 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); * @sa @ref window_size * @sa glfwSetWindowSizeCallback * - * @since Added in GLFW 3.0. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -835,7 +836,8 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); * @sa @ref window_close * @sa glfwSetWindowCloseCallback * - * @since Added in GLFW 3.0. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -850,7 +852,8 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); * @sa @ref window_refresh * @sa glfwSetWindowRefreshCallback * - * @since Added in GLFW 3.0. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -867,7 +870,7 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); * @sa @ref window_focus * @sa glfwSetWindowFocusCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -885,7 +888,7 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); * @sa @ref window_iconify * @sa glfwSetWindowIconifyCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -903,7 +906,7 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -923,7 +926,8 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); * @sa @ref input_mouse_button * @sa glfwSetMouseButtonCallback * - * @since Added in GLFW 3.0. + * @since Added in version 1.0. + * @glfw3 Added window handle and modifier mask parameters. * * @ingroup input */ @@ -940,7 +944,7 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); * @sa @ref cursor_pos * @sa glfwSetCursorPosCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. Replaces `GLFWmouseposfun`. * * @ingroup input */ @@ -957,7 +961,7 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); * @sa @ref cursor_enter * @sa glfwSetCursorEnterCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -974,7 +978,7 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); * @sa @ref scrolling * @sa glfwSetScrollCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. * * @ingroup input */ @@ -994,7 +998,8 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @sa @ref input_key * @sa glfwSetKeyCallback * - * @since Added in GLFW 3.0. + * @since Added in version 1.0. + * @glfw3 Added window handle, scancode and modifier mask parameters. * * @ingroup input */ @@ -1010,7 +1015,8 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); * @sa @ref input_char * @sa glfwSetCharCallback * - * @since Added in GLFW 3.0. + * @since Added in version 2.4. + * @glfw3 Added window handle parameter. * * @ingroup input */ @@ -1031,7 +1037,7 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * @sa @ref input_char * @sa glfwSetCharModsCallback * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -1048,7 +1054,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); * @sa @ref path_drop * @sa glfwSetDropCallback * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -1064,7 +1070,7 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); * @sa @ref monitor_event * @sa glfwSetMonitorCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1077,7 +1083,8 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); * @sa @ref monitor_modes * @sa glfwGetVideoMode glfwGetVideoModes * - * @since Added in GLFW 3.0. + * @since Added in version 1.0. + * @glfw3 Added refresh rate member. * * @ingroup monitor */ @@ -1110,7 +1117,7 @@ typedef struct GLFWvidmode * @sa @ref monitor_gamma * @sa glfwGetGammaRamp glfwSetGammaRamp * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1134,7 +1141,8 @@ typedef struct GLFWgammaramp * * @sa @ref cursor_custom * - * @since Added in GLFW 3.1. + * @since Added in version 2.1. + * @glfw3 Removed format and bytes-per-pixel members. */ typedef struct GLFWimage { @@ -1180,7 +1188,7 @@ typedef struct GLFWimage * @sa @ref intro_init * @sa glfwTerminate * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1210,7 +1218,7 @@ GLFWAPI int glfwInit(void); * @sa @ref intro_init * @sa glfwInit * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1236,7 +1244,7 @@ GLFWAPI void glfwTerminate(void); * @sa @ref intro_version * @sa glfwGetVersionString * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1266,7 +1274,7 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); * @sa @ref intro_version * @sa glfwGetVersion * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup init */ @@ -1298,7 +1306,7 @@ GLFWAPI const char* glfwGetVersionString(void); * * @sa @ref error_handling * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup init */ @@ -1325,7 +1333,7 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); * @sa @ref monitor_event * @sa glfwGetPrimaryMonitor * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1347,7 +1355,7 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); * @sa @ref monitor_monitors * @sa glfwGetMonitors * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1369,7 +1377,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1401,7 +1409,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1425,7 +1433,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1446,7 +1454,7 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * * @sa @ref monitor_event * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1475,7 +1483,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); * @sa @ref monitor_modes * @sa glfwGetVideoMode * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Changed to return an array of modes for a specific monitor. * * @ingroup monitor @@ -1501,7 +1509,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); * @sa @ref monitor_modes * @sa glfwGetVideoModes * - * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`. + * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. * * @ingroup monitor */ @@ -1520,7 +1528,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1543,7 +1551,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1570,7 +1578,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1586,7 +1594,7 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); * @sa @ref window_hints * @sa glfwWindowHint * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1607,7 +1615,7 @@ GLFWAPI void glfwDefaultWindowHints(void); * @sa @ref window_hints * @sa glfwDefaultWindowHints * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`. + * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. * * @ingroup window */ @@ -1720,7 +1728,7 @@ GLFWAPI void glfwWindowHint(int hint, int value); * @sa @ref window_creation * @sa glfwDestroyWindow * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`. + * @since Added in version 3.0. Replaces `glfwOpenWindow`. * * @ingroup window */ @@ -1746,7 +1754,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G * @sa @ref window_creation * @sa glfwCreateWindow * - * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`. + * @since Added in version 3.0. Replaces `glfwCloseWindow`. * * @ingroup window */ @@ -1764,7 +1772,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); * * @sa @ref window_close * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1784,7 +1792,7 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); * * @sa @ref window_close * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1805,7 +1813,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * * @sa @ref window_title * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window @@ -1831,7 +1839,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @sa @ref window_pos * @sa glfwSetWindowPos * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1858,7 +1866,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * @sa @ref window_pos * @sa glfwGetWindowPos * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window @@ -1885,7 +1893,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * @sa @ref window_size * @sa glfwSetWindowSize * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window @@ -1919,7 +1927,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); * @sa @ref window_sizelimits * @sa glfwSetWindowAspectRatio * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup window */ @@ -1955,7 +1963,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe * @sa @ref window_sizelimits * @sa glfwSetWindowSizeLimits * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup window */ @@ -1983,7 +1991,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * @sa @ref window_size * @sa glfwGetWindowSize * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window @@ -2010,7 +2018,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2044,7 +2052,7 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height) * * @sa @ref window_size * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup window */ @@ -2066,7 +2074,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * @sa @ref window_iconify * @sa glfwRestoreWindow * - * @since Added in GLFW 2.1. + * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window @@ -2088,7 +2096,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); * @sa @ref window_iconify * @sa glfwIconifyWindow * - * @since Added in GLFW 2.1. + * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window @@ -2108,7 +2116,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); * @sa @ref window_hide * @sa glfwHideWindow * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2127,7 +2135,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window); * @sa @ref window_hide * @sa glfwShowWindow * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2146,7 +2154,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * * @sa @ref window_monitor * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2175,7 +2183,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * * @sa @ref window_attribs * - * @since Added in GLFW 3.0. Replaces `glfwGetWindowParam` and + * @since Added in version 3.0. Replaces `glfwGetWindowParam` and * `glfwGetGLVersion`. * * @ingroup window @@ -2197,7 +2205,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @sa @ref window_userptr * @sa glfwGetWindowUserPointer * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2216,7 +2224,7 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); * @sa @ref window_userptr * @sa glfwSetWindowUserPointer * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2238,7 +2246,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * * @sa @ref window_pos * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2260,8 +2268,8 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * * @sa @ref window_size * - * @since Added in GLFW 1.0. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2291,8 +2299,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * * @sa @ref window_close * - * @since Added in GLFW 2.5. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2318,8 +2326,8 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * * @sa @ref window_refresh * - * @since Added in GLFW 2.5. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2345,7 +2353,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * * @sa @ref window_focus * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2366,7 +2374,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * * @sa @ref window_iconify * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2387,7 +2395,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * * @sa @ref window_fbsize * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2418,7 +2426,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * @sa @ref events * @sa glfwWaitEvents * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup window */ @@ -2459,7 +2467,7 @@ GLFWAPI void glfwPollEvents(void); * @sa @ref events * @sa glfwPollEvents * - * @since Added in GLFW 2.5. + * @since Added in version 2.5. * * @ingroup window */ @@ -2479,7 +2487,7 @@ GLFWAPI void glfwWaitEvents(void); * @sa @ref events * @sa glfwWaitEvents * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup window */ @@ -2499,7 +2507,7 @@ GLFWAPI void glfwPostEmptyEvent(void); * * @sa glfwSetInputMode * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -2544,7 +2552,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * * @sa glfwGetInputMode * - * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`. + * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. * * @ingroup input */ @@ -2569,7 +2577,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); * * @sa @ref input_key_name * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup input */ @@ -2605,7 +2613,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * * @sa @ref input_key * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input @@ -2631,7 +2639,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * * @sa @ref input_mouse_button * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input @@ -2667,7 +2675,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * @sa @ref cursor_pos * @sa glfwSetCursorPos * - * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`. + * @since Added in version 3.0. Replaces `glfwGetMousePos`. * * @ingroup input */ @@ -2705,7 +2713,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @sa @ref cursor_pos * @sa glfwGetCursorPos * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`. + * @since Added in version 3.0. Replaces `glfwSetMousePos`. * * @ingroup input */ @@ -2743,7 +2751,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @sa glfwDestroyCursor * @sa glfwCreateStandardCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2766,7 +2774,7 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) * @sa @ref cursor_object * @sa glfwCreateCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2787,7 +2795,7 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); * @sa @ref cursor_object * @sa glfwCreateCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2811,7 +2819,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); * * @sa @ref cursor_object * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2851,8 +2859,8 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * * @sa @ref input_key * - * @since Added in GLFW 1.0. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2887,8 +2895,8 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * * @sa @ref input_char * - * @since Added in GLFW 2.4. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 2.4. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2919,7 +2927,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * * @sa @ref input_char * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2946,8 +2954,8 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * * @sa @ref input_mouse_button * - * @since Added in GLFW 1.0. - * @glfw3 Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2970,7 +2978,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * * @sa @ref cursor_pos * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePosCallback`. + * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. * * @ingroup input */ @@ -2992,7 +3000,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor * * @sa @ref cursor_enter * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3017,7 +3025,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * * @sa @ref scrolling * - * @since Added in GLFW 3.0. Replaces `glfwSetMouseWheelCallback`. + * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. * * @ingroup input */ @@ -3043,7 +3051,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * * @sa @ref path_drop * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -3060,7 +3068,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); * * @sa @ref joystick * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickParam`. + * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. * * @ingroup input */ @@ -3085,7 +3093,7 @@ GLFWAPI int glfwJoystickPresent(int joy); * * @sa @ref joystick_axis * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`. + * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. * * @ingroup input */ @@ -3110,7 +3118,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); * * @sa @ref joystick_button * - * @since Added in GLFW 2.2. + * @since Added in version 2.2. * @glfw3 Changed to return a dynamic array. * * @ingroup input @@ -3136,7 +3144,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); * * @sa @ref joystick_name * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3158,7 +3166,7 @@ GLFWAPI const char* glfwGetJoystickName(int joy); * @sa @ref clipboard * @sa glfwGetClipboardString * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3185,7 +3193,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @sa @ref clipboard * @sa glfwSetClipboardString * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3209,7 +3217,7 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); * * @sa @ref time * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup input */ @@ -3231,7 +3239,7 @@ GLFWAPI double glfwGetTime(void); * * @sa @ref time * - * @since Added in GLFW 2.2. + * @since Added in version 2.2. * * @ingroup input */ @@ -3262,7 +3270,7 @@ GLFWAPI void glfwSetTime(double time); * @sa @ref context_current * @sa glfwGetCurrentContext * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup context */ @@ -3281,7 +3289,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); * @sa @ref context_current * @sa glfwMakeContextCurrent * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup context */ @@ -3307,7 +3315,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); * @sa @ref buffer_swap * @sa glfwSwapInterval * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window @@ -3349,7 +3357,7 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); * @sa @ref buffer_swap * @sa glfwSwapBuffers * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ @@ -3379,7 +3387,7 @@ GLFWAPI void glfwSwapInterval(int interval); * @sa @ref context_glext * @sa glfwGetProcAddress * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ @@ -3414,7 +3422,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension); * @sa @ref context_glext * @sa glfwExtensionSupported * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index db75eacd4..9fa955e94 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -130,7 +130,7 @@ extern "C" { * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -145,7 +145,7 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -159,7 +159,7 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -175,7 +175,7 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -191,7 +191,7 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -205,7 +205,7 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -221,7 +221,7 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -237,7 +237,7 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -251,7 +251,7 @@ GLFWAPI Display* glfwGetX11Display(void); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -265,7 +265,7 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -279,7 +279,7 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -295,7 +295,7 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -309,7 +309,7 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -325,7 +325,7 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -339,7 +339,7 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -353,7 +353,7 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -369,7 +369,7 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -383,7 +383,7 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -397,7 +397,7 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.2. + * @since Added in version 3.2. * * @ingroup native */ @@ -413,7 +413,7 @@ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -427,7 +427,7 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -441,7 +441,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); * @thread_safety This function may be called from any thread. Access is not * synchronized. * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ From 6466c9d4060448b39f0aeaa85e7480804cd1fec6 Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Tue, 2 Feb 2016 00:04:15 +0100 Subject: [PATCH 16/42] Fix CMake file install paths Fixes #460. Fixes #483. Fixes #606. --- CMakeLists.txt | 10 +++++----- README.md | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 024fbdca1..39e0b48ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,9 +368,9 @@ endforeach() include(CMakePackageConfigHelpers) if (UNIX) - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake/glfw3/") + set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/cmake/glfw3") else() - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/") + set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}") endif() configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" @@ -421,11 +421,11 @@ if (GLFW_INSTALL) install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" - DESTINATION lib${LIB_SUFFIX}/cmake/glfw) + DESTINATION "${GLFW_CONFIG_PATH}") - install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw) + install(EXPORT glfwTargets DESTINATION "${GLFW_CONFIG_PATH}") install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" - DESTINATION lib${LIB_SUFFIX}/pkgconfig) + DESTINATION "lib${LIB_SUFFIX}/pkgconfig") # Only generate this target if no higher-level project already has if (NOT TARGET uninstall) diff --git a/README.md b/README.md index 43c1abcad..a030c48f2 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ skills. - Martins Mozeiko - Tristam MacDonald - Hans Mackowiak + - Zbigniew Mandziejewicz - Kyle McDonald - David Medlock - Bryce Mehring From 23d34747f4cd28a892258ec6e72fc6657b9b7eec Mon Sep 17 00:00:00 2001 From: Nicholas Vitovitch Date: Tue, 2 Feb 2016 00:06:56 +0100 Subject: [PATCH 17/42] Rename export targets file to glfw3Targets.cmake --- CMakeLists.txt | 9 +++------ README.md | 1 + 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39e0b48ad..507a9b406 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -367,11 +367,7 @@ endforeach() #-------------------------------------------------------------------- include(CMakePackageConfigHelpers) -if (UNIX) - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/cmake/glfw3") -else() - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}") -endif() +set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3") configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" @@ -423,7 +419,8 @@ if (GLFW_INSTALL) "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" DESTINATION "${GLFW_CONFIG_PATH}") - install(EXPORT glfwTargets DESTINATION "${GLFW_CONFIG_PATH}") + install(EXPORT glfwTargets FILE glfw3Targets.cmake + DESTINATION "${GLFW_CONFIG_PATH}") install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" DESTINATION "lib${LIB_SUFFIX}/pkgconfig") diff --git a/README.md b/README.md index a030c48f2..f54922d65 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,7 @@ skills. - urraka - Jari Vetoniemi - Ricardo Vieira + - Nicholas Vitovitch - Simon Voordouw - Torsten Walluhn - Patrick Walton From a247f7d797c3bde19c51a21c28e46e540d277d22 Mon Sep 17 00:00:00 2001 From: Nicholas Vitovitch Date: Tue, 2 Feb 2016 04:45:30 +0100 Subject: [PATCH 18/42] Include imported targets into module config file --- src/glfw3Config.cmake.in | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/glfw3Config.cmake.in b/src/glfw3Config.cmake.in index d34df06f3..1fa200e27 100644 --- a/src/glfw3Config.cmake.in +++ b/src/glfw3Config.cmake.in @@ -1,15 +1 @@ -# - Config file for the glfw3 package -# It defines the following variables -# GLFW3_INCLUDE_DIR, the path where GLFW headers are located -# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located -# GLFW3_LIBRARY, library to link against to use GLFW - -set(GLFW3_VERSION "@GLFW_VERSION_FULL@") - -@PACKAGE_INIT@ - -set_and_check(GLFW3_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/include") -set_and_check(GLFW3_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@") - -find_library(GLFW3_LIBRARY "@GLFW_LIB_NAME@" HINTS ${GLFW3_LIBRARY_DIR}) - +include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake") From 8637612908d4d874ef52f057b8f1a539926b8fb3 Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Tue, 2 Feb 2016 00:52:55 +0100 Subject: [PATCH 19/42] Add GLFW_DLL to target interface --- examples/CMakeLists.txt | 1 - src/CMakeLists.txt | 1 + tests/CMakeLists.txt | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3b6e54ce3..7b40ecb90 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,7 +2,6 @@ link_libraries(glfw) if (BUILD_SHARED_LIBS) - add_definitions(-DGLFW_DLL) link_libraries("${MATH_LIBRARY}") else() link_libraries(${glfw_LIBRARIES}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 590a10f8e..7c7dd9738 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,6 +99,7 @@ if (BUILD_SHARED_LIBS) target_compile_options(glfw PRIVATE "-fvisibility=hidden") endif() + target_compile_definitions(glfw INTERFACE -DGLFW_DLL) target_link_libraries(glfw ${glfw_LIBRARIES}) endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index af211600b..f1bce371f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,6 @@ link_libraries(glfw) if (BUILD_SHARED_LIBS) - add_definitions(-DGLFW_DLL) link_libraries("${MATH_LIBRARY}") else() link_libraries(${glfw_LIBRARIES}) From 453631773ee7f678f0a2b19961a5f0e8125619ef Mon Sep 17 00:00:00 2001 From: Nicholas Vitovitch Date: Tue, 2 Feb 2016 00:41:20 +0100 Subject: [PATCH 20/42] Export transitive dependencies for static library --- CMakeLists.txt | 1 - docs/build.dox | 23 ++++++++++++++--------- examples/CMakeLists.txt | 2 -- src/CMakeLists.txt | 4 +++- tests/CMakeLists.txt | 2 -- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 507a9b406..244e51a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,7 +354,6 @@ endif() #-------------------------------------------------------------------- # Export GLFW library dependencies #-------------------------------------------------------------------- -set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW") foreach(arg ${glfw_PKG_DEPS}) set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}") endforeach() diff --git a/docs/build.dox b/docs/build.dox index d14cf799b..32e19adeb 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -158,6 +158,14 @@ will add the `glfw` target and the necessary cache variables to your project. add_subdirectory(path/to/glfw) @endcode +Once GLFW has been added to the project, link against it with the `glfw` target. +This adds all link-time dependencies of GLFW as it is currently configured and, +when applicable, the [GLFW_DLL](@ref build_macros) macro. + +@code{.cmake} +target_link_libraries(myapp glfw) +@endcode + To be able to include the GLFW header from your code, you need to tell the compiler where to find it. @@ -165,21 +173,18 @@ compiler where to find it. include_directories(path/to/glfw/include) @endcode -Once GLFW has been added to the project, the `GLFW_LIBRARIES` cache variable -contains all link-time dependencies of GLFW as it is currently configured. To -link against GLFW, link against them and the `glfw` target. +Note that it does not include GLU, as GLFW does not use it. If your application +needs GLU, you can find it by requiring the OpenGL package. @code{.cmake} -target_link_libraries(myapp glfw ${GLFW_LIBRARIES}) +find_package(OpenGL REQUIRED) @endcode -Note that `GLFW_LIBRARIES` does not include GLU, as GLFW does not use it. If -your application needs GLU, you can add it to the list of dependencies with the -`OPENGL_glu_LIBRARY` cache variable, which is implicitly created when the GLFW -CMake files look for OpenGL. +Once found, the GLU library path is stored in the `OPENGL_glu_LIBRARY` cache +variable. @code{.cmake} -target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY} ${GLFW_LIBRARIES}) +target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY}) @endcode diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b40ecb90..3f3f89830 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,8 +3,6 @@ link_libraries(glfw) if (BUILD_SHARED_LIBS) link_libraries("${MATH_LIBRARY}") -else() - link_libraries(${glfw_LIBRARIES}) endif() if (MSVC) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c7dd9738..2660dcac7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -100,7 +100,9 @@ if (BUILD_SHARED_LIBS) endif() target_compile_definitions(glfw INTERFACE -DGLFW_DLL) - target_link_libraries(glfw ${glfw_LIBRARIES}) + target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES}) +else() + target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES}) endif() if (MSVC) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f1bce371f..afa140fad 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,8 +3,6 @@ link_libraries(glfw) if (BUILD_SHARED_LIBS) link_libraries("${MATH_LIBRARY}") -else() - link_libraries(${glfw_LIBRARIES}) endif() if (MSVC) From 075140aefed2361f773d2cbadbbd639d092b4fa9 Mon Sep 17 00:00:00 2001 From: Marcus Geelnard Date: Tue, 2 Feb 2016 00:54:57 +0100 Subject: [PATCH 21/42] Add public header path to target interface Closes #697. --- docs/build.dox | 12 +++--------- examples/CMakeLists.txt | 3 +-- src/CMakeLists.txt | 3 +++ tests/CMakeLists.txt | 3 +-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/docs/build.dox b/docs/build.dox index 32e19adeb..6fe890dfa 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -159,20 +159,14 @@ add_subdirectory(path/to/glfw) @endcode Once GLFW has been added to the project, link against it with the `glfw` target. -This adds all link-time dependencies of GLFW as it is currently configured and, -when applicable, the [GLFW_DLL](@ref build_macros) macro. +This adds all link-time dependencies of GLFW as it is currently configured, +the include directory for the GLFW header and, when applicable, the +[GLFW_DLL](@ref build_macros) macro. @code{.cmake} target_link_libraries(myapp glfw) @endcode -To be able to include the GLFW header from your code, you need to tell the -compiler where to find it. - -@code{.cmake} -include_directories(path/to/glfw/include) -@endcode - Note that it does not include GLU, as GLFW does not use it. If your application needs GLU, you can find it by requiring the OpenGL package. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3f3f89830..7d8a41af2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -9,8 +9,7 @@ if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() -include_directories("${GLFW_SOURCE_DIR}/include" - "${GLFW_SOURCE_DIR}/deps") +include_directories("${GLFW_SOURCE_DIR}/deps") if (WIN32) set(ICON glfw.rc) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2660dcac7..f73daa2c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,6 +59,9 @@ set_target_properties(glfw PROPERTIES FOLDER "GLFW3") target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H) +target_include_directories(glfw PUBLIC + $ + $/include>) target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/src" "${GLFW_BINARY_DIR}/src" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index afa140fad..6488ef257 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,8 +9,7 @@ if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() -include_directories("${GLFW_SOURCE_DIR}/include" - "${GLFW_SOURCE_DIR}/deps") +include_directories("${GLFW_SOURCE_DIR}/deps") set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" "${GLFW_SOURCE_DIR}/deps/glad.c") From 7f7ad39e150320c53b3970e906c12f8bd31e1531 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 2 Feb 2016 04:50:50 +0100 Subject: [PATCH 22/42] CMake target installation fixes --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 244e51a9b..649ee5273 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,7 +371,6 @@ set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3") configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" - PATH_VARS CMAKE_INSTALL_PREFIX NO_CHECK_REQUIRED_COMPONENTS_MACRO) write_basic_package_version_file("${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" @@ -419,6 +418,7 @@ if (GLFW_INSTALL) DESTINATION "${GLFW_CONFIG_PATH}") install(EXPORT glfwTargets FILE glfw3Targets.cmake + EXPORT_LINK_INTERFACE_LIBRARIES DESTINATION "${GLFW_CONFIG_PATH}") install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" DESTINATION "lib${LIB_SUFFIX}/pkgconfig") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f73daa2c3..8f70e37e9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -96,7 +96,7 @@ if (BUILD_SHARED_LIBS) target_compile_options(glfw PRIVATE "-fno-common") set_target_properties(glfw PROPERTIES - INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") + INSTALL_NAME_DIR "lib${LIB_SUFFIX}") elseif (UNIX) # Hide symbols not explicitly tagged for export from the shared library target_compile_options(glfw PRIVATE "-fvisibility=hidden") From b63b992fd60ff359b5a457d4c82b4e55ddc31d8e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 2 Feb 2016 02:24:12 +0100 Subject: [PATCH 23/42] CMake documentation work --- docs/build.dox | 54 ++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/docs/build.dox b/docs/build.dox index 6fe890dfa..1554798b9 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -148,6 +148,10 @@ uses OpenGL and `glu32` if it uses GLU. @subsection build_link_cmake_source With CMake and GLFW source +This section is about using CMake to compile and link GLFW along with your +application. If you want to use an installed binary instead, see @ref +build_link_cmake_module. + With just a few changes to your `CMakeLists.txt` you can have the GLFW source tree built along with your application. @@ -174,56 +178,54 @@ needs GLU, you can find it by requiring the OpenGL package. find_package(OpenGL REQUIRED) @endcode -Once found, the GLU library path is stored in the `OPENGL_glu_LIBRARY` cache -variable. +If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the +`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used. @code{.cmake} -target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY}) +target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) +target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) @endcode -@subsection build_link_cmake_pkgconfig With CMake on Unix and installed GLFW binaries +@subsection build_link_cmake_module With CMake and installed GLFW binaries -CMake can import settings from pkg-config, which GLFW supports. When you -installed GLFW, the pkg-config file `glfw3.pc` was installed along with it. +This section is about using CMake to link GLFW after it has been built and +installed. If you want to build it along with your application instead, see +@ref build_link_cmake_source. -First you need to find the PkgConfig package. If this fails, you may need to -install the pkg-config package for your distribution. +With just a few changes to your `CMakeLists.txt`, you can locate the module and +target files generated when GLFW is installed. @code{.cmake} -find_package(PkgConfig REQUIRED) +find_package(glfw3 3.2 REQUIRED) @endcode -This creates the CMake commands to find pkg-config packages. Then you need to -find the GLFW package. +Once GLFW has been located, link against it with the `glfw` target. This adds +all link-time dependencies of GLFW as it is currently configured, the include +directory for the GLFW header and, when applicable, the +[GLFW_DLL](@ref build_macros) macro. @code{.cmake} -pkg_search_module(GLFW REQUIRED glfw3) +target_link_libraries(myapp glfw) @endcode -This creates the CMake variables you need to use GLFW. To be able to include -the GLFW header, you need to tell your compiler where it is. +Note that it does not include GLU, as GLFW does not use it. If your application +needs GLU, you can find it by requiring the OpenGL package. @code{.cmake} -include_directories(${GLFW_INCLUDE_DIRS}) +find_package(OpenGL REQUIRED) @endcode -You also need to link against the correct libraries. If you are using the -shared library version of GLFW, use the `GLFW_LIBRARIES` variable. +If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the +`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used. @code{.cmake} -target_link_libraries(simple ${GLFW_LIBRARIES}) -@endcode - -If you are using the static library version of GLFW, use the -`GLFW_STATIC_LIBRARIES` variable instead. - -@code{.cmake} -target_link_libraries(simple ${GLFW_STATIC_LIBRARIES}) +target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) +target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) @endcode -@subsection build_link_pkgconfig With pkg-config on OS X or other Unix +@subsection build_link_pkgconfig With makefiles and pkg-config on Unix GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/), and the `glfw3.pc` pkf-config file is generated when the GLFW library is built From f22edf13dc28a018bf0fbc0a15b378967d5372ce Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Tue, 2 Feb 2016 05:55:24 +0100 Subject: [PATCH 24/42] Simplify file generation paths --- CMakeLists.txt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 649ee5273..ce668274b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,25 +368,22 @@ include(CMakePackageConfigHelpers) set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3") -configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" - "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" +configure_package_config_file(src/glfw3Config.cmake.in + src/glfw3Config.cmake INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" NO_CHECK_REQUIRED_COMPONENTS_MACRO) -write_basic_package_version_file("${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" +write_basic_package_version_file(src/glfw3ConfigVersion.cmake VERSION ${GLFW_VERSION_FULL} COMPATIBILITY SameMajorVersion) if (GLFW_BUILD_DOCS) - configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" - "${GLFW_BINARY_DIR}/docs/Doxyfile" @ONLY) + configure_file(docs/Doxyfile.in docs/Doxyfile @ONLY) endif() -configure_file("${GLFW_SOURCE_DIR}/src/glfw_config.h.in" - "${GLFW_BINARY_DIR}/src/glfw_config.h" @ONLY) +configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY) -configure_file("${GLFW_SOURCE_DIR}/src/glfw3.pc.in" - "${GLFW_BINARY_DIR}/src/glfw3.pc" @ONLY) +configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY) #-------------------------------------------------------------------- # Add subdirectories @@ -425,8 +422,8 @@ if (GLFW_INSTALL) # Only generate this target if no higher-level project already has if (NOT TARGET uninstall) - configure_file("${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${GLFW_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) + configure_file(cmake_uninstall.cmake.in + cmake_uninstall.cmake IMMEDIATE @ONLY) add_custom_target(uninstall "${CMAKE_COMMAND}" -P From f21ac15c6c8ee27e468afbae0e13b2b91d29afe4 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 14 Apr 2015 23:47:17 +0200 Subject: [PATCH 25/42] Add initial Travis CI file --- .travis.yml | 19 +++++++++++++++++++ README.md | 2 ++ 2 files changed, 21 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..07e5d9a07 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: c +compiler: clang +before_install: + - sudo apt-add-repository ppa:irie/cmake -y + - sudo apt-get update -q + - sudo apt-get install cmake xorg-dev libglu1-mesa-dev +branches: + only: + - travis + - master +script: + - cmake . + - make +notifications: + email: + recipients: + - travis@glfw.org + on_success: never + on_failure: always diff --git a/README.md b/README.md index f54922d65..d070edcd0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # GLFW +[![Build Status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw) + ## Introduction GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES From 422044b778ed3ab79f4e22c7e71d3c34ed4beff1 Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Thu, 4 Feb 2016 13:23:54 +0100 Subject: [PATCH 26/42] Travis file fixes Move to container-based builds. Add BUILD_SHARED_LIBS to matrix. Enable OS X. --- .travis.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07e5d9a07..197cacd42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,25 @@ language: c compiler: clang -before_install: - - sudo apt-add-repository ppa:irie/cmake -y - - sudo apt-get update -q - - sudo apt-get install cmake xorg-dev libglu1-mesa-dev branches: only: - travis - master +os: + - linux + - osx +sudo: false +addons: + apt: + sources: + - kubuntu-backports + packages: + - cmake +env: + - BUILD_SHARED_LIBS=ON + - BUILD_SHARED_LIBS=OFF script: - - cmake . - - make + - cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} . + - cmake --build . notifications: email: recipients: From 9ffeae554b04e65e7718927b151b03d90f3e0839 Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Thu, 4 Feb 2016 14:05:47 +0100 Subject: [PATCH 27/42] Add Appveyor file --- .appveyor.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..e344470cb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,7 @@ +environment: + matrix: + - BUILD_SHARED_LIBS: ON + - BUILD_SHARED_LIBS: OFF +build_script: + - cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% . + - cmake --build . From a6bec2ebdc66427741cdedf75723077b7ea86eb2 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 4 Feb 2016 14:58:44 +0100 Subject: [PATCH 28/42] CI file fixes --- .appveyor.yml | 13 +++++++++++++ .travis.yml | 8 ++++---- README.md | 3 ++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index e344470cb..621c9ab7d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,7 +1,20 @@ +branches: + only: + - ci + - master +skip_tags: true environment: matrix: - BUILD_SHARED_LIBS: ON - BUILD_SHARED_LIBS: OFF +matrix: + fast_finish: true build_script: - cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% . - cmake --build . +notifications: + - provider: Email + to: + - ci@glfw.org + - on_build_status_failure: true + - on_build_status_success: false diff --git a/.travis.yml b/.travis.yml index 197cacd42..bd448dd9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: c compiler: clang branches: only: - - travis + - ci - master os: - linux @@ -21,8 +21,8 @@ script: - cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} . - cmake --build . notifications: - email: - recipients: - - travis@glfw.org + email: + recipients: + - ci@glfw.org on_success: never on_failure: always diff --git a/README.md b/README.md index d070edcd0..b9eb55767 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # GLFW -[![Build Status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw) +[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw) +[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw) ## Introduction From ebe88c386978477a84bd81191abcdaeaa4d6deed Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 4 Feb 2016 15:44:20 +0100 Subject: [PATCH 29/42] Add build directory for CI --- .appveyor.yml | 4 +++- .travis.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 621c9ab7d..1bb691ca5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,7 +10,9 @@ environment: matrix: fast_finish: true build_script: - - cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% . + - mkdir build + - cd build + - cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% .. - cmake --build . notifications: - provider: Email diff --git a/.travis.yml b/.travis.yml index bd448dd9c..ff1c6c352 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,9 @@ env: - BUILD_SHARED_LIBS=ON - BUILD_SHARED_LIBS=OFF script: - - cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} . + - mkdir build + - cd build + - cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} .. - cmake --build . notifications: email: From 69c5559e5344a519fc155cd87095532b85a3ef99 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 4 Feb 2016 15:55:54 +0100 Subject: [PATCH 30/42] Fix YAML syntax error --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 1bb691ca5..b09449e8b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -16,7 +16,7 @@ build_script: - cmake --build . notifications: - provider: Email - to: - - ci@glfw.org + to: + - ci@glfw.org - on_build_status_failure: true - on_build_status_success: false From d93d9fb7be5394fc9444aad7be7d08e39ad9a439 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 4 Feb 2016 16:06:31 +0100 Subject: [PATCH 31/42] Fix Appveyor notification setting names [ci skip] --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index b09449e8b..74a2f0aab 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -18,5 +18,5 @@ notifications: - provider: Email to: - ci@glfw.org - - on_build_status_failure: true - - on_build_status_success: false + - on_build_failure: true + - on_build_success: false From 58a83ca8adbfcfbb70c46ea1e461b51c8b9cc212 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 4 Feb 2016 20:34:22 +0100 Subject: [PATCH 32/42] Documentation work --- docs/quick.dox | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/quick.dox b/docs/quick.dox index 12c2db370..543932724 100644 --- a/docs/quick.dox +++ b/docs/quick.dox @@ -64,7 +64,9 @@ successful initialization, `GLFW_TRUE` is returned. If an error occurred, @code if (!glfwInit()) - exit(EXIT_FAILURE); +{ + // Initialization failed +} @endcode Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be just one and zero. @@ -112,22 +114,36 @@ glfwSetErrorCallback(error_callback); @subsection quick_create_window Creating a window and context -The window and its OpenGL context are created with a single call, which returns -a handle to the created combined window and context object. For example, this -creates a 640 by 480 windowed mode window with an OpenGL context: +The window and its OpenGL context are created with a single call to @ref +glfwCreateWindow, which returns a handle to the created combined window and +context object @code GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); -@endcode - -If window or context creation fails, `NULL` will be returned, so it is necessary -to check the return value. - -@code if (!window) { - glfwTerminate(); - exit(EXIT_FAILURE); + // Window or OpenGL context creation failed +} +@endcode + +This creates a 640 by 480 windowed mode window with an OpenGL context. If +window or OpenGL context creation fails, `NULL` will be returned. You should +always check the return value. While window creation rarely fails, context +creation depends on properly installed drivers and may fail even on machines +with the necessary hardware. + +By default, the OpenGL context GLFW creates may have any version. You can +require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum +version is not supported on the machine, context (and window) creation fails. + +@code +glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); +glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +if (!window) +{ + // Window or context creation failed } @endcode @@ -135,7 +151,7 @@ The window handle is passed to all window related functions and is provided to along to all window related callbacks, so they can tell which window received the event. -When a window is no longer needed, destroy it. +When a window and context is no longer needed, destroy it. @code glfwDestroyWindow(window); From f51cf8114821b9c25d28b5572469de3c18ef446a Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Fri, 5 Feb 2016 00:51:40 +0100 Subject: [PATCH 33/42] Add error sections to reference docs [ci skip] --- docs/Doxyfile.in | 1 + include/GLFW/glfw3.h | 223 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 218 insertions(+), 6 deletions(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index c27629ee9..8fecf1aa1 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -199,6 +199,7 @@ ALIASES = "thread_safety=@par Thread safety\n" \ "pointer_lifetime=@par Pointer lifetime\n" \ "analysis=@par Analysis\n" \ "reentrancy=@par Reentrancy\n" \ + "errors=@par Errors\n" \ "glfw3=@par\n__GLFW 3:__" \ "x11=__X11:__" \ "win32=__Windows:__" \ diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 6ca49fa2d..ede8a02b1 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1178,6 +1178,8 @@ typedef struct GLFWimage * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * * @remark @osx This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with a @@ -1206,6 +1208,8 @@ GLFWAPI int glfwInit(void); * call this function, as it is called by @ref glfwInit before it returns * failure. * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * * @remark This function may be called before @ref glfwInit. * * @warning The contexts of any remaining windows must not be current on any @@ -1230,13 +1234,14 @@ GLFWAPI void glfwTerminate(void); * library. It is intended for when you are using GLFW as a shared library and * want to ensure that you are using the minimum required version. * - * Any or all of the version arguments may be `NULL`. This function always - * succeeds. + * Any or all of the version arguments may be `NULL`. * * @param[out] major Where to store the major version number, or `NULL`. * @param[out] minor Where to store the minor version number, or `NULL`. * @param[out] rev Where to store the revision number, or `NULL`. * + * @errors None. + * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function may be called from any thread. @@ -1261,10 +1266,10 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); * @ref glfwGetVersion function already provides the version of the running * library binary. * - * This function always succeeds. - * * @return The GLFW version string. * + * @errors None. + * * @remark This function may be called before @ref glfwInit. * * @pointer_lifetime The returned string is static and compile-time generated. @@ -1300,6 +1305,8 @@ GLFWAPI const char* glfwGetVersionString(void); * callback. * @return The previously set callback, or `NULL` if no callback was set. * + * @errors None. + * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function must only be called from the main thread. @@ -1323,6 +1330,8 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); * @return An array of monitor handles, or `NULL` if no monitors were found or * if an [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * monitor configuration changes or the library is terminated. @@ -1347,6 +1356,8 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); * @return The primary monitor, or `NULL` if no monitors were found or if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @remark The primary monitor is always first in the array returned by @ref @@ -1373,6 +1384,9 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties @@ -1402,6 +1416,8 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * @param[out] heightMM Where to store the height, in millimetres, of the * monitor's display area, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @remark @win32 calculates the returned physical size from the * current resolution and system DPI instead of querying the monitor EDID data. * @@ -1425,6 +1441,8 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * @return The UTF-8 encoded name of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. @@ -1450,6 +1468,8 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_event @@ -1473,6 +1493,9 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); * @return An array of video modes, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected, this function is called again for that monitor or the library @@ -1500,6 +1523,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); * @return The current mode of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. @@ -1524,6 +1550,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma @@ -1542,6 +1571,9 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned structure and its arrays are allocated and * freed by GLFW. You should not free them yourself. They are valid until the * specified monitor is disconnected, this function is called again for that @@ -1566,6 +1598,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @remark Gamma ramp sizes other than 256 are not supported by all platforms * or graphics hardware. * @@ -1589,6 +1624,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); * This function resets all window hints to their * [default values](@ref window_hints_values). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints @@ -1610,6 +1647,9 @@ GLFWAPI void glfwDefaultWindowHints(void); * @param[in] hint The [window hint](@ref window_hints) to set. * @param[in] value The new value of the window hint. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints @@ -1680,6 +1720,11 @@ GLFWAPI void glfwWindowHint(int hint, int value); * @return The handle of the created window, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available. * @@ -1744,6 +1789,9 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G * * @param[in] window The window to destroy. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @note The context of the specified window must not be current on any other * thread when this function is called. * @@ -1767,6 +1815,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); * @param[in] window The window to query. * @return The value of the close flag. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -1787,6 +1837,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); * @param[in] window The window whose flag to change. * @param[in] value The new value. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -1806,6 +1858,9 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * @param[in] window The window whose title to change. * @param[in] title The UTF-8 encoded window title. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @remark @osx The window title will not be updated until the next time you * process events. * @@ -1834,6 +1889,9 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the client area, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos @@ -1861,6 +1919,9 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos @@ -1888,6 +1949,9 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * @param[out] height Where to store the height, in screen coordinates, of the * client area, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -1919,6 +1983,9 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); * @param[in] maxheight The maximum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * @@ -1955,6 +2022,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe * @param[in] denom The denominator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * @@ -1986,6 +2056,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * @param[in] width The desired width of the specified window. * @param[in] height The desired height of the specified window. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -2013,6 +2086,9 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); * @param[out] height Where to store the height, in pixels, of the framebuffer, * or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize @@ -2048,6 +2124,9 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height) * @param[out] bottom Where to store the size, in screen coordinates, of the * bottom edge of the window frame, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -2069,6 +2148,9 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * * @param[in] window The window to iconify. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -2091,6 +2173,9 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); * * @param[in] window The window to restore. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -2111,6 +2196,9 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); * * @param[in] window The window to make visible. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide @@ -2130,6 +2218,9 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window); * * @param[in] window The window to hide. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide @@ -2150,6 +2241,8 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * @return The monitor, or `NULL` if the window is in windowed mode or an error * occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor @@ -2171,6 +2264,9 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @return The value of the attribute, or zero if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @remark Framebuffer related hints are not window attributes. See @ref * window_attribs_fb for more information. * @@ -2199,6 +2295,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @param[in] window The window whose pointer to set. * @param[in] pointer The new value. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -2218,6 +2316,8 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); * * @param[in] window The window whose pointer to return. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -2242,6 +2342,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos @@ -2264,6 +2366,8 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -2292,6 +2396,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @remark @osx Selecting Quit from the application menu will trigger the close * callback for all windows. * @@ -2322,6 +2428,8 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_refresh @@ -2349,6 +2457,8 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus @@ -2370,6 +2480,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -2391,6 +2503,8 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize @@ -2419,6 +2533,9 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * * Event processing is not required for joystick input to work. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -2460,6 +2577,9 @@ GLFWAPI void glfwPollEvents(void); * * Event processing is not required for joystick input to work. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -2482,6 +2602,9 @@ GLFWAPI void glfwWaitEvents(void); * of threads in applications that do not create windows, use your threading * library of choice. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function may be called from any thread. * * @sa @ref events @@ -2503,6 +2626,9 @@ GLFWAPI void glfwPostEmptyEvent(void); * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * * @thread_safety This function must only be called from the main thread. * * @sa glfwSetInputMode @@ -2548,6 +2674,9 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * `GLFW_STICKY_MOUSE_BUTTONS`. * @param[in] value The new value of the specified input mode. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa glfwGetInputMode @@ -2569,6 +2698,9 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); * @param[in] scancode The scancode of the key to query. * @return The localized name of the key. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetKeyName, or until the library is terminated. @@ -2609,6 +2741,9 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * not a valid key for this function. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key @@ -2635,6 +2770,9 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * @param[in] button The desired [mouse button](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button @@ -2670,6 +2808,9 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * @param[out] ypos Where to store the cursor y-coordinate, relative to the to * top edge of the client area, or `NULL`. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos @@ -2704,6 +2845,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @param[in] ypos The desired y-coordinate, relative to the top edge of the * client area. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for * the window focus event to arrive. This means you may not be able to set the * cursor position directly after window creation. @@ -2736,10 +2880,12 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @param[in] image The desired cursor image. * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. - * * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The specified image data is copied before this function * returns. * @@ -2763,10 +2909,12 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) * a window with @ref glfwSetCursor. * * @param[in] shape One of the [standard shapes](@ref shapes). - * * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -2788,6 +2936,9 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); * * @param[in] cursor The cursor object to destroy. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -2815,6 +2966,9 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); * @param[in] cursor The cursor to set, or `NULL` to switch back to the default * arrow cursor. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object @@ -2855,6 +3009,8 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key @@ -2891,6 +3047,8 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char @@ -2923,6 +3081,8 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or an * error occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char @@ -2950,6 +3110,8 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button @@ -2974,6 +3136,8 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos @@ -2996,6 +3160,8 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_enter @@ -3021,6 +3187,8 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref scrolling @@ -3047,6 +3215,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop @@ -3064,6 +3234,9 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); * @param[in] joy The [joystick](@ref joysticks) to query. * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick @@ -3084,6 +3257,9 @@ GLFWAPI int glfwJoystickPresent(int joy); * array. This is set to zero if an error occurred. * @return An array of axis values, or `NULL` if the joystick is not present. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library @@ -3109,6 +3285,9 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); * array. This is set to zero if an error occurred. * @return An array of button states, or `NULL` if the joystick is not present. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library @@ -3135,6 +3314,9 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library @@ -3158,6 +3340,9 @@ GLFWAPI const char* glfwGetJoystickName(int joy); * @param[in] window The window that will own the clipboard contents. * @param[in] string A UTF-8 encoded string. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The specified string is copied before this function * returns. * @@ -3183,6 +3368,9 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library @@ -3212,6 +3400,8 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); * @return The current value, in seconds, or zero if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * @@ -3231,6 +3421,9 @@ GLFWAPI double glfwGetTime(void); * * @param[in] time The new value, in seconds. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * * @remark The upper limit of the timer is calculated as * floor((264 - 1) / 109) and is due to implementations * storing nanoseconds in 64 bits. The limit may be increased in the future. @@ -3265,6 +3458,9 @@ GLFWAPI void glfwSetTime(double time); * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * * @thread_safety This function may be called from any thread. * * @sa @ref context_current @@ -3284,6 +3480,8 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); * @return The window whose context is current, or `NULL` if no window's * context is current. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * * @thread_safety This function may be called from any thread. * * @sa @ref context_current @@ -3307,6 +3505,9 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); * * @param[in] window The window whose buffers to swap. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * * @remark __EGL:__ The context of the specified window must be current on the * calling thread. * @@ -3343,6 +3544,9 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); * @param[in] interval The minimum number of screen updates to wait for * until the buffers are swapped by @ref glfwSwapBuffers. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * * @remark This function is not called during context creation, leaving the * swap interval set to whatever is the default on that platform. This is done * because some swap interval extensions used by GLFW do not allow the swap @@ -3382,6 +3586,10 @@ GLFWAPI void glfwSwapInterval(int interval); * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` * otherwise. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref + * GLFW_PLATFORM_ERROR. + * * @thread_safety This function may be called from any thread. * * @sa @ref context_glext @@ -3407,6 +3615,9 @@ GLFWAPI int glfwExtensionSupported(const char* extension); * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * * @remark The address of a given function is not guaranteed to be the same * between contexts. * From ca21a5c7b40310bab420818c827c986865dbbd0d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sat, 2 Jan 2016 21:45:23 +0100 Subject: [PATCH 34/42] Correct GLES3 extension header paths --- include/GLFW/glfw3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index ede8a02b1..8c2fbd218 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -150,12 +150,12 @@ extern "C" { #elif defined(GLFW_INCLUDE_ES3) #include #if defined(GLFW_INCLUDE_GLEXT) - #include + #include #endif #elif defined(GLFW_INCLUDE_ES31) #include #if defined(GLFW_INCLUDE_GLEXT) - #include + #include #endif #elif !defined(GLFW_INCLUDE_NONE) #include From d6e0a4390ca46bee12b20d3d13e89ed74790cf14 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 9 Feb 2016 07:41:48 +0100 Subject: [PATCH 35/42] Documentation work --- include/GLFW/glfw3.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 8c2fbd218..55e292ccf 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1644,6 +1644,10 @@ GLFWAPI void glfwDefaultWindowHints(void); * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is * terminated. * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * * @param[in] hint The [window hint](@ref window_hints) to set. * @param[in] value The new value of the window hint. * From 49d228207f8322ed8aa9f820a1490c852a5cb2d7 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 8 Feb 2016 11:21:48 -0800 Subject: [PATCH 36/42] Fix crash when joystick name unavailable on OS X Fixes #694. Closes #701. --- README.md | 1 + src/cocoa_joystick.m | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b9eb55767..0d2e30f40 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ used by the tests and examples and are not required to build the library. when no windows existed - [Cocoa] Removed support for OS X 10.6 - [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned + - [Cocoa] Bugfix: Connecting a joystick that reports no name would segfault - [X11] Bugfix: Monitor connection and disconnection events were not reported - [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end - [X11] Bugfix: An XKB structure was leaked during `glfwInit` diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 0229ccece..5c584f6dc 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -287,10 +288,15 @@ static void matchCallback(void* context, CFStringRef name = IOHIDDeviceGetProperty(deviceRef, CFSTR(kIOHIDProductKey)); - CFStringGetCString(name, - joystick->name, - sizeof(joystick->name), - kCFStringEncodingUTF8); + if (name) + { + CFStringGetCString(name, + joystick->name, + sizeof(joystick->name), + kCFStringEncodingUTF8); + } + else + strncpy(joystick->name, "Unknown", sizeof(joystick->name)); joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL); joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); From 386b60396fbbd08d02f61fd8a32cc164fd38a7e7 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 10 Feb 2016 13:48:49 +0100 Subject: [PATCH 37/42] Documentation work [ci skip] --- include/GLFW/glfw3.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 55e292ccf..fc1a54425 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1260,13 +1260,14 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); * This function returns the compile-time generated * [version string](@ref intro_version_string) of the GLFW library binary. It * describes the version, platform, compiler and any platform-specific - * compile-time options. + * compile-time options. It should not be confused with the OpenGL or OpenGL + * ES version string, queried with `glGetString`. * * __Do not use the version string__ to parse the GLFW library version. The - * @ref glfwGetVersion function already provides the version of the running - * library binary. + * @ref glfwGetVersion function provides the version of the running library + * binary in numerical format. * - * @return The GLFW version string. + * @return The ASCII encoded GLFW version string. * * @errors None. * @@ -3256,6 +3257,10 @@ GLFWAPI int glfwJoystickPresent(int joy); * This function returns the values of all axes of the specified joystick. * Each element in the array is a value between -1.0 and 1.0. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of axis values in the returned * array. This is set to zero if an error occurred. @@ -3284,6 +3289,10 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); * This function returns the state of all buttons of the specified joystick. * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of button states in the returned * array. This is set to zero if an error occurred. @@ -3314,6 +3323,10 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); * The returned string is allocated and freed by GLFW. You should not free it * yourself. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. From f7228bb56294714e8cdb8b39be3b7c6967240c54 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 11 Feb 2016 16:41:39 +0100 Subject: [PATCH 38/42] Fix window class not being unregistered The helper window kept the window class from being unregistered. Fixes #704. --- src/win32_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index c26b93db9..57acdb3ae 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -387,6 +387,9 @@ int _glfwPlatformInit(void) void _glfwPlatformTerminate(void) { + if (_glfw.win32.helperWindow) + DestroyWindow(_glfw.win32.helperWindow); + _glfwUnregisterWindowClassWin32(); // Restore previous foreground lock timeout system setting @@ -405,9 +408,6 @@ void _glfwPlatformTerminate(void) _glfwTerminateJoysticksWin32(); _glfwTerminateThreadLocalStorageWin32(); - if (_glfw.win32.helperWindow) - DestroyWindow(_glfw.win32.helperWindow); - freeLibraries(); } From 1e452d5fcaa4fba8f7b28818d1cac517be956091 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 15 Feb 2016 08:22:32 +0100 Subject: [PATCH 39/42] Remove work performed by glad --- tests/glfwinfo.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 0a113745f..ee70be832 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -156,14 +156,6 @@ static void list_extensions(int api, int major, int minor) if (api == GLFW_OPENGL_API && major > 2) { - PFNGLGETSTRINGIPROC glGetStringi = - (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); - if (!glGetStringi) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - glGetIntegerv(GL_NUM_EXTENSIONS, &count); for (i = 0; i < count; i++) @@ -572,16 +564,6 @@ int main(int argc, char** argv) if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) { - PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC - glGetFramebufferAttachmentParameteriv = - (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) - glfwGetProcAddress("glGetFramebufferAttachmentParameteriv"); - if (!glGetFramebufferAttachmentParameteriv) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, From c2efe87cffcb6509363a8b9d540a8958367a9c29 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 15 Feb 2016 08:34:44 +0100 Subject: [PATCH 40/42] Improve glfwinfo extension listing --- tests/glfwinfo.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index ee70be832..e90372788 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -159,23 +159,27 @@ static void list_extensions(int api, int major, int minor) glGetIntegerv(GL_NUM_EXTENSIONS, &count); for (i = 0; i < count; i++) - puts((const char*) glGetStringi(GL_EXTENSIONS, i)); + printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i)); } else { extensions = glGetString(GL_EXTENSIONS); while (*extensions != '\0') { - if (*extensions == ' ') - putchar('\n'); - else - putchar(*extensions); + putchar(' '); - extensions++; + while (*extensions != '\0' && *extensions != ' ') + { + putchar(*extensions); + extensions++; + } + + while (*extensions == ' ') + extensions++; + + putchar('\n'); } } - - putchar('\n'); } static int valid_version(void) From 9b75bffc88939883d8ae77901b73182dda35e733 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Aug 2015 20:19:04 +0200 Subject: [PATCH 41/42] Add basic Vulkan support Added GLFW_INCLUDE_VULKAN. Added glfwVulkanSupported, glfwGetRequiredInstanceExtensions, glfwGetInstanceProcAddress, glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. Added port of LunarG SDK tri example. --- .gitignore | 1 + CMake/modules/FindVulkan.cmake | 23 + CMakeLists.txt | 1 + README.md | 16 +- deps/vulkan/vk_platform.h | 127 ++ deps/vulkan/vulkan.h | 3775 ++++++++++++++++++++++++++++++++ docs/Doxyfile.in | 4 +- docs/build.dox | 3 + docs/compat.dox | 39 + docs/context.dox | 5 + docs/main.dox | 8 +- docs/news.dox | 9 + docs/vulkan.dox | 185 ++ examples/CMakeLists.txt | 2 + include/GLFW/glfw3.h | 230 +- src/CMakeLists.txt | 2 +- src/cocoa_platform.h | 5 + src/cocoa_window.m | 21 + src/egl_context.h | 11 - src/glx_context.c | 1 - src/init.c | 4 + src/internal.h | 127 +- src/mir_platform.h | 19 + src/mir_window.c | 70 + src/vulkan.c | 287 +++ src/win32_platform.h | 18 + src/win32_window.c | 68 + src/wl_platform.h | 20 + src/wl_window.c | 70 + src/x11_init.c | 13 + src/x11_platform.h | 41 + src/x11_window.c | 168 +- tests/CMakeLists.txt | 7 + tests/glfwinfo.c | 254 ++- tests/vulkan.c | 2240 +++++++++++++++++++ 35 files changed, 7823 insertions(+), 51 deletions(-) create mode 100644 CMake/modules/FindVulkan.cmake create mode 100644 deps/vulkan/vk_platform.h create mode 100644 deps/vulkan/vulkan.h create mode 100644 docs/vulkan.dox create mode 100644 src/vulkan.c create mode 100644 tests/vulkan.c diff --git a/.gitignore b/.gitignore index 73f819d38..61ba29b93 100644 --- a/.gitignore +++ b/.gitignore @@ -71,5 +71,6 @@ tests/tearing tests/threads tests/title tests/version +tests/vulkan tests/windows diff --git a/CMake/modules/FindVulkan.cmake b/CMake/modules/FindVulkan.cmake new file mode 100644 index 000000000..c7190bcbd --- /dev/null +++ b/CMake/modules/FindVulkan.cmake @@ -0,0 +1,23 @@ +# Find Vulkan +# +# VULKAN_INCLUDE_DIR +# VULKAN_LIBRARY +# VULKAN_FOUND + +if (WIN32) + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS + "$ENV{VK_SDK_PATH}/Include") + find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS + "$ENV{VK_SDK_PATH}/Bin") +else() + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS + "$ENV{VULKAN_SDK}/include") + find_library(VULKAN_LIBRARY NAMES vulkan HINTS + "$ENV{VULKAN_SDK}/lib") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR) + +mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY) + diff --git a/CMakeLists.txt b/CMakeLists.txt index ce668274b..e6585a1c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ endif() set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") find_package(Threads REQUIRED) +find_package(Vulkan) if (GLFW_BUILD_DOCS) set(DOXYGEN_SKIP_DOT TRUE) diff --git a/README.md b/README.md index 0d2e30f40..9fe915965 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ ## Introduction -GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES -application development. It provides a simple, platform-independent API for -creating windows and contexts, reading input, handling events, etc. +GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and +Vulkan application development. It provides a simple, platform-independent API +for creating windows, contexts and surfaces, reading input, handling events, etc. Version 3.2 is _not yet described_. @@ -50,7 +50,7 @@ This will help both us and other people experiencing the same bug. GLFW itself needs only the headers and libraries for your window system. It does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or -client API (OpenGL, OpenGL ES) to enable support for them. +rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them. GLFW bundles a number of dependencies in the `deps/` directory. These are only used by the tests and examples and are not required to build the library. @@ -64,15 +64,22 @@ used by the tests and examples and are not required to build the library. - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in examples +The Vulkan example additionally requires the Vulkan SDK to be installed, or it +will not be included in the build. + ## Changelog + - Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`, + `glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and + `glfwCreateWindowSurface` for platform independent Vulkan support - Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting absolute and relative window size limits - Added `glfwGetKeyName` for querying the layout-specific name of printable keys - Added `GLFW_NO_API` for creating window without contexts - Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support + - Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header - Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values - Added `glfwGetGLXWindow` to query the `GLXWindow` of a window - Added icons to examples on Windows and OS X @@ -168,6 +175,7 @@ skills. - Osman Keskin - Cameron King - Peter Knut + - Christoph Kubisch - Eric Larson - Robin Leffmann - Glenn Lewis diff --git a/deps/vulkan/vk_platform.h b/deps/vulkan/vk_platform.h new file mode 100644 index 000000000..a53e725a9 --- /dev/null +++ b/deps/vulkan/vk_platform.h @@ -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 + +#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 + #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 +#endif + +#ifdef VK_USE_PLATFORM_MIR_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_WIN32_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_XCB_KHR +#include +#endif + +#endif // __VK_PLATFORM_H__ diff --git a/deps/vulkan/vulkan.h b/deps/vulkan/vulkan.h new file mode 100644 index 000000000..cd6a71ac1 --- /dev/null +++ b/deps/vulkan/vulkan.h @@ -0,0 +1,3775 @@ +#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)) + +// Vulkan API version supported by this file +#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 3) + +#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_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_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_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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, + VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + +typedef enum VkImageViewType { + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, + VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageViewType; + +typedef enum VkComponentSwizzle { + VK_COMPONENT_SWIZZLE_IDENTITY = 0, + VK_COMPONENT_SWIZZLE_ZERO = 1, + VK_COMPONENT_SWIZZLE_ONE = 2, + VK_COMPONENT_SWIZZLE_R = 3, + VK_COMPONENT_SWIZZLE_G = 4, + VK_COMPONENT_SWIZZLE_B = 5, + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, + VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF +} VkComponentSwizzle; + +typedef enum VkVertexInputRate { + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, + VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, + VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF +} VkVertexInputRate; + +typedef enum VkPrimitiveTopology { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, + VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF +} VkPrimitiveTopology; + +typedef enum VkPolygonMode { + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, + VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, + VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPolygonMode; + +typedef enum VkFrontFace { + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, + VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF +} VkFrontFace; + +typedef enum VkCompareOp { + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, + VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, + VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + +typedef enum VkStencilOp { + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, + VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + +typedef enum VkLogicOp { + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, + VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, + VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; + +typedef enum VkBlendFactor { + VK_BLEND_FACTOR_ZERO = 0, + VK_BLEND_FACTOR_ONE = 1, + VK_BLEND_FACTOR_SRC_COLOR = 2, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, + VK_BLEND_FACTOR_DST_COLOR = 4, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, + VK_BLEND_FACTOR_SRC_ALPHA = 6, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, + VK_BLEND_FACTOR_DST_ALPHA = 8, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, + VK_BLEND_FACTOR_CONSTANT_COLOR = 10, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, + VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, + VK_BLEND_FACTOR_SRC1_COLOR = 15, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, + VK_BLEND_FACTOR_SRC1_ALPHA = 17, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), + VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF +} VkBlendFactor; + +typedef enum VkBlendOp { + VK_BLEND_OP_ADD = 0, + VK_BLEND_OP_SUBTRACT = 1, + VK_BLEND_OP_REVERSE_SUBTRACT = 2, + VK_BLEND_OP_MIN = 3, + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, + VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, + VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), + VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF +} VkBlendOp; + +typedef enum VkDynamicState { + VK_DYNAMIC_STATE_VIEWPORT = 0, + VK_DYNAMIC_STATE_SCISSOR = 1, + VK_DYNAMIC_STATE_LINE_WIDTH = 2, + VK_DYNAMIC_STATE_DEPTH_BIAS = 3, + VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, + VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, + VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), + VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF +} VkDynamicState; + +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, + VK_FILTER_END_RANGE = VK_FILTER_LINEAR, + VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + +typedef enum VkSamplerAddressMode { + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +typedef enum VkBorderColor { + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, + VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, + VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF +} VkBorderColor; + +typedef enum VkDescriptorType { + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, + VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +typedef enum VkAttachmentLoadOp { + VK_ATTACHMENT_LOAD_OP_LOAD = 0, + VK_ATTACHMENT_LOAD_OP_CLEAR = 1, + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentLoadOp; + +typedef enum VkAttachmentStoreOp { + VK_ATTACHMENT_STORE_OP_STORE = 0, + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentStoreOp; + +typedef enum VkPipelineBindPoint { + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, + VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, + VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF +} VkPipelineBindPoint; + +typedef enum VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferLevel; + +typedef enum VkIndexType { + VK_INDEX_TYPE_UINT16 = 0, + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, + VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, + VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkIndexType; + +typedef enum VkSubpassContents { + VK_SUBPASS_CONTENTS_INLINE = 0, + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, + VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, + VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassContents; + +typedef VkFlags VkInstanceCreateFlags; + +typedef enum VkFormatFeatureFlagBits { + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, + VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, + VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, + VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, +} VkFormatFeatureFlagBits; +typedef VkFlags VkFormatFeatureFlags; + +typedef enum VkImageUsageFlagBits { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, +} VkImageUsageFlagBits; +typedef VkFlags VkImageUsageFlags; + +typedef enum VkImageCreateFlagBits { + VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, +} VkImageCreateFlagBits; +typedef VkFlags VkImageCreateFlags; + +typedef enum VkSampleCountFlagBits { + VK_SAMPLE_COUNT_1_BIT = 0x00000001, + VK_SAMPLE_COUNT_2_BIT = 0x00000002, + VK_SAMPLE_COUNT_4_BIT = 0x00000004, + VK_SAMPLE_COUNT_8_BIT = 0x00000008, + VK_SAMPLE_COUNT_16_BIT = 0x00000010, + VK_SAMPLE_COUNT_32_BIT = 0x00000020, + VK_SAMPLE_COUNT_64_BIT = 0x00000040, +} VkSampleCountFlagBits; +typedef VkFlags VkSampleCountFlags; + +typedef enum VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, +} VkQueueFlagBits; +typedef VkFlags VkQueueFlags; + +typedef enum VkMemoryPropertyFlagBits { + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, +} VkMemoryPropertyFlagBits; +typedef VkFlags VkMemoryPropertyFlags; + +typedef enum VkMemoryHeapFlagBits { + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, +} VkMemoryHeapFlagBits; +typedef VkFlags VkMemoryHeapFlags; +typedef VkFlags VkDeviceCreateFlags; +typedef VkFlags VkDeviceQueueCreateFlags; + +typedef enum VkPipelineStageFlagBits { + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, + VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, + VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, +} VkPipelineStageFlagBits; +typedef VkFlags VkPipelineStageFlags; +typedef VkFlags VkMemoryMapFlags; + +typedef enum VkImageAspectFlagBits { + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; + +typedef enum VkSparseImageFormatFlagBits { + VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, + VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, +} VkSparseImageFormatFlagBits; +typedef VkFlags VkSparseImageFormatFlags; + +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; + +typedef enum VkFenceCreateFlagBits { + VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, +} VkFenceCreateFlagBits; +typedef VkFlags VkFenceCreateFlags; +typedef VkFlags VkSemaphoreCreateFlags; +typedef VkFlags VkEventCreateFlags; +typedef VkFlags VkQueryPoolCreateFlags; + +typedef enum VkQueryPipelineStatisticFlagBits { + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, + VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, + VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, +} VkQueryPipelineStatisticFlagBits; +typedef VkFlags VkQueryPipelineStatisticFlags; + +typedef enum VkQueryResultFlagBits { + VK_QUERY_RESULT_64_BIT = 0x00000001, + VK_QUERY_RESULT_WAIT_BIT = 0x00000002, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, + VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, +} VkQueryResultFlagBits; +typedef VkFlags VkQueryResultFlags; + +typedef enum VkBufferCreateFlagBits { + VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, +} VkBufferCreateFlagBits; +typedef VkFlags VkBufferCreateFlags; + +typedef enum VkBufferUsageFlagBits { + VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, +} VkBufferUsageFlagBits; +typedef VkFlags VkBufferUsageFlags; +typedef VkFlags VkBufferViewCreateFlags; +typedef VkFlags VkImageViewCreateFlags; +typedef VkFlags VkShaderModuleCreateFlags; +typedef VkFlags VkPipelineCacheCreateFlags; + +typedef enum VkPipelineCreateFlagBits { + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, + VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, +} VkPipelineCreateFlagBits; +typedef VkFlags VkPipelineCreateFlags; +typedef VkFlags VkPipelineShaderStageCreateFlags; + +typedef enum VkShaderStageFlagBits { + VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, + VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, + VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, + VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x1F, + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, +} VkShaderStageFlagBits; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; + +typedef enum VkCullModeFlagBits { + VK_CULL_MODE_NONE = 0, + VK_CULL_MODE_FRONT_BIT = 0x00000001, + VK_CULL_MODE_BACK_BIT = 0x00000002, + VK_CULL_MODE_FRONT_AND_BACK = 0x3, +} VkCullModeFlagBits; +typedef VkFlags VkCullModeFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; + +typedef enum VkColorComponentFlagBits { + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; +typedef VkFlags VkPipelineDynamicStateCreateFlags; +typedef VkFlags VkPipelineLayoutCreateFlags; +typedef VkFlags VkShaderStageFlags; +typedef VkFlags VkSamplerCreateFlags; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; + +typedef enum VkDescriptorPoolCreateFlagBits { + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, +} VkDescriptorPoolCreateFlagBits; +typedef VkFlags VkDescriptorPoolCreateFlags; +typedef VkFlags VkDescriptorPoolResetFlags; +typedef VkFlags VkFramebufferCreateFlags; +typedef VkFlags VkRenderPassCreateFlags; + +typedef enum VkAttachmentDescriptionFlagBits { + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, +} VkAttachmentDescriptionFlagBits; +typedef VkFlags VkAttachmentDescriptionFlags; +typedef VkFlags VkSubpassDescriptionFlags; + +typedef enum VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; + +typedef enum VkDependencyFlagBits { + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, +} VkDependencyFlagBits; +typedef VkFlags VkDependencyFlags; + +typedef enum VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, +} VkCommandPoolCreateFlagBits; +typedef VkFlags VkCommandPoolCreateFlags; + +typedef enum VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, +} VkCommandPoolResetFlagBits; +typedef VkFlags VkCommandPoolResetFlags; + +typedef enum VkCommandBufferUsageFlagBits { + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, +} VkCommandBufferUsageFlagBits; +typedef VkFlags VkCommandBufferUsageFlags; + +typedef enum VkQueryControlFlagBits { + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, +} VkQueryControlFlagBits; +typedef VkFlags VkQueryControlFlags; + +typedef enum VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, +} VkCommandBufferResetFlagBits; +typedef VkFlags VkCommandBufferResetFlags; + +typedef enum VkStencilFaceFlagBits { + VK_STENCIL_FACE_FRONT_BIT = 0x00000001, + VK_STENCIL_FACE_BACK_BIT = 0x00000002, + VK_STENCIL_FRONT_AND_BACK = 0x3, +} VkStencilFaceFlagBits; +typedef VkFlags VkStencilFaceFlags; + +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 VkApplicationInfo { + VkStructureType sType; + const void* pNext; + const char* pApplicationName; + uint32_t applicationVersion; + const char* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkInstanceCreateInfo { + VkStructureType sType; + const void* pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef struct VkAllocationCallbacks { + void* pUserData; + PFN_vkAllocationFunction pfnAllocation; + PFN_vkReallocationFunction pfnReallocation; + PFN_vkFreeFunction pfnFree; + PFN_vkInternalAllocationNotification pfnInternalAllocation; + PFN_vkInternalFreeNotification pfnInternalFree; +} VkAllocationCallbacks; + +typedef struct VkPhysicalDeviceFeatures { + VkBool32 robustBufferAccess; + VkBool32 fullDrawIndexUint32; + VkBool32 imageCubeArray; + VkBool32 independentBlend; + VkBool32 geometryShader; + VkBool32 tessellationShader; + VkBool32 sampleRateShading; + VkBool32 dualSrcBlend; + VkBool32 logicOp; + VkBool32 multiDrawIndirect; + VkBool32 drawIndirectFirstInstance; + VkBool32 depthClamp; + VkBool32 depthBiasClamp; + VkBool32 fillModeNonSolid; + VkBool32 depthBounds; + VkBool32 wideLines; + VkBool32 largePoints; + VkBool32 alphaToOne; + VkBool32 multiViewport; + VkBool32 samplerAnisotropy; + VkBool32 textureCompressionETC2; + VkBool32 textureCompressionASTC_LDR; + VkBool32 textureCompressionBC; + VkBool32 occlusionQueryPrecise; + VkBool32 pipelineStatisticsQuery; + VkBool32 vertexPipelineStoresAndAtomics; + VkBool32 fragmentStoresAndAtomics; + VkBool32 shaderTessellationAndGeometryPointSize; + VkBool32 shaderImageGatherExtended; + VkBool32 shaderStorageImageExtendedFormats; + VkBool32 shaderStorageImageMultisample; + VkBool32 shaderStorageImageReadWithoutFormat; + VkBool32 shaderStorageImageWriteWithoutFormat; + VkBool32 shaderUniformBufferArrayDynamicIndexing; + VkBool32 shaderSampledImageArrayDynamicIndexing; + VkBool32 shaderStorageBufferArrayDynamicIndexing; + VkBool32 shaderStorageImageArrayDynamicIndexing; + VkBool32 shaderClipDistance; + VkBool32 shaderCullDistance; + VkBool32 shaderFloat64; + VkBool32 shaderInt64; + VkBool32 shaderInt16; + VkBool32 shaderResourceResidency; + VkBool32 shaderResourceMinLod; + VkBool32 sparseBinding; + VkBool32 sparseResidencyBuffer; + VkBool32 sparseResidencyImage2D; + VkBool32 sparseResidencyImage3D; + VkBool32 sparseResidency2Samples; + VkBool32 sparseResidency4Samples; + VkBool32 sparseResidency8Samples; + VkBool32 sparseResidency16Samples; + VkBool32 sparseResidencyAliased; + VkBool32 variableMultisampleRate; + VkBool32 inheritedQueries; +} VkPhysicalDeviceFeatures; + +typedef struct VkFormatProperties { + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkImageFormatProperties { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkPhysicalDeviceLimits { + uint32_t maxImageDimension1D; + uint32_t maxImageDimension2D; + uint32_t maxImageDimension3D; + uint32_t maxImageDimensionCube; + uint32_t maxImageArrayLayers; + uint32_t maxTexelBufferElements; + uint32_t maxUniformBufferRange; + uint32_t maxStorageBufferRange; + uint32_t maxPushConstantsSize; + uint32_t maxMemoryAllocationCount; + uint32_t maxSamplerAllocationCount; + VkDeviceSize bufferImageGranularity; + VkDeviceSize sparseAddressSpaceSize; + uint32_t maxBoundDescriptorSets; + uint32_t maxPerStageDescriptorSamplers; + uint32_t maxPerStageDescriptorUniformBuffers; + uint32_t maxPerStageDescriptorStorageBuffers; + uint32_t maxPerStageDescriptorSampledImages; + uint32_t maxPerStageDescriptorStorageImages; + uint32_t maxPerStageDescriptorInputAttachments; + uint32_t maxPerStageResources; + uint32_t maxDescriptorSetSamplers; + uint32_t maxDescriptorSetUniformBuffers; + uint32_t maxDescriptorSetUniformBuffersDynamic; + uint32_t maxDescriptorSetStorageBuffers; + uint32_t maxDescriptorSetStorageBuffersDynamic; + uint32_t maxDescriptorSetSampledImages; + uint32_t maxDescriptorSetStorageImages; + uint32_t maxDescriptorSetInputAttachments; + uint32_t maxVertexInputAttributes; + uint32_t maxVertexInputBindings; + uint32_t maxVertexInputAttributeOffset; + uint32_t maxVertexInputBindingStride; + uint32_t maxVertexOutputComponents; + uint32_t maxTessellationGenerationLevel; + uint32_t maxTessellationPatchSize; + uint32_t maxTessellationControlPerVertexInputComponents; + uint32_t maxTessellationControlPerVertexOutputComponents; + uint32_t maxTessellationControlPerPatchOutputComponents; + uint32_t maxTessellationControlTotalOutputComponents; + uint32_t maxTessellationEvaluationInputComponents; + uint32_t maxTessellationEvaluationOutputComponents; + uint32_t maxGeometryShaderInvocations; + uint32_t maxGeometryInputComponents; + uint32_t maxGeometryOutputComponents; + uint32_t maxGeometryOutputVertices; + uint32_t maxGeometryTotalOutputComponents; + uint32_t maxFragmentInputComponents; + uint32_t maxFragmentOutputAttachments; + uint32_t maxFragmentDualSrcAttachments; + uint32_t maxFragmentCombinedOutputResources; + uint32_t maxComputeSharedMemorySize; + uint32_t maxComputeWorkGroupCount[3]; + uint32_t maxComputeWorkGroupInvocations; + uint32_t maxComputeWorkGroupSize[3]; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; + uint32_t maxDrawIndexedIndexValue; + uint32_t maxDrawIndirectCount; + float maxSamplerLodBias; + float maxSamplerAnisotropy; + uint32_t maxViewports; + uint32_t maxViewportDimensions[2]; + float viewportBoundsRange[2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize minTexelBufferOffsetAlignment; + VkDeviceSize minUniformBufferOffsetAlignment; + VkDeviceSize minStorageBufferOffsetAlignment; + int32_t minTexelOffset; + uint32_t maxTexelOffset; + int32_t minTexelGatherOffset; + uint32_t maxTexelGatherOffset; + float minInterpolationOffset; + float maxInterpolationOffset; + uint32_t subPixelInterpolationOffsetBits; + uint32_t maxFramebufferWidth; + uint32_t maxFramebufferHeight; + uint32_t maxFramebufferLayers; + VkSampleCountFlags framebufferColorSampleCounts; + VkSampleCountFlags framebufferDepthSampleCounts; + VkSampleCountFlags framebufferStencilSampleCounts; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts; + uint32_t maxColorAttachments; + VkSampleCountFlags sampledImageColorSampleCounts; + VkSampleCountFlags sampledImageIntegerSampleCounts; + VkSampleCountFlags sampledImageDepthSampleCounts; + VkSampleCountFlags sampledImageStencilSampleCounts; + VkSampleCountFlags storageImageSampleCounts; + uint32_t maxSampleMaskWords; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; + uint32_t maxClipDistances; + uint32_t maxCullDistances; + uint32_t maxCombinedClipAndCullDistances; + uint32_t discreteQueuePriorities; + float pointSizeRange[2]; + float lineWidthRange[2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize optimalBufferCopyOffsetAlignment; + VkDeviceSize optimalBufferCopyRowPitchAlignment; + VkDeviceSize nonCoherentAtomSize; +} VkPhysicalDeviceLimits; + +typedef struct VkPhysicalDeviceSparseProperties { + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; +} VkPhysicalDeviceSparseProperties; + +typedef struct VkPhysicalDeviceProperties { + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties; + +typedef struct VkQueueFamilyProperties { + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties; + +typedef struct VkMemoryType { + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + +typedef struct VkMemoryHeap { + VkDeviceSize size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkPhysicalDeviceMemoryProperties { + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + +typedef struct VkDeviceQueueCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float* pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo; + +typedef struct VkExtensionProperties { + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; +} VkExtensionProperties; + +typedef struct VkLayerProperties { + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; + uint32_t implementationVersion; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkLayerProperties; + +typedef struct VkSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + const VkPipelineStageFlags* pWaitDstStageMask; + uint32_t commandBufferCount; + const VkCommandBuffer* pCommandBuffers; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkSubmitInfo; + +typedef struct VkMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + +typedef struct VkMappedMemoryRange { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMappedMemoryRange; + +typedef struct VkMemoryRequirements { + VkDeviceSize size; + VkDeviceSize alignment; + uint32_t memoryTypeBits; +} VkMemoryRequirements; + +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + +typedef struct VkSparseMemoryBind { + VkDeviceSize resourceOffset; + VkDeviceSize size; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseMemoryBind; + +typedef struct VkSparseBufferMemoryBindInfo { + VkBuffer buffer; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseBufferMemoryBindInfo; + +typedef struct VkSparseImageOpaqueMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseImageOpaqueMemoryBindInfo; + +typedef struct VkImageSubresource { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkSparseImageMemoryBind { + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseImageMemoryBind; + +typedef struct VkSparseImageMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseImageMemoryBind* pBinds; +} VkSparseImageMemoryBindInfo; + +typedef struct VkBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t bufferBindCount; + const VkSparseBufferMemoryBindInfo* pBufferBinds; + uint32_t imageOpaqueBindCount; + const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; + uint32_t imageBindCount; + const VkSparseImageMemoryBindInfo* pImageBinds; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkBindSparseInfo; + +typedef struct VkFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo; + +typedef struct VkSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo; + +typedef struct VkEventCreateInfo { + VkStructureType sType; + const void* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkQueryPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkQueryPoolCreateFlags flags; + VkQueryType queryType; + uint32_t queryCount; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkQueryPoolCreateInfo; + +typedef struct VkBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkDeviceSize size; + VkBufferUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkBufferCreateInfo; + +typedef struct VkBufferViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferViewCreateFlags flags; + VkBuffer buffer; + VkFormat format; + VkDeviceSize offset; + VkDeviceSize range; +} VkBufferViewCreateInfo; + +typedef struct VkImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + VkSampleCountFlagBits samples; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkImageLayout initialLayout; +} VkImageCreateInfo; + +typedef struct VkSubresourceLayout { + VkDeviceSize offset; + VkDeviceSize size; + VkDeviceSize rowPitch; + VkDeviceSize arrayPitch; + VkDeviceSize depthPitch; +} VkSubresourceLayout; + +typedef struct VkComponentMapping { + VkComponentSwizzle r; + VkComponentSwizzle g; + VkComponentSwizzle b; + VkComponentSwizzle a; +} VkComponentMapping; + +typedef struct VkImageSubresourceRange { + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageViewCreateFlags flags; + VkImage image; + VkImageViewType viewType; + VkFormat format; + VkComponentMapping components; + VkImageSubresourceRange subresourceRange; +} VkImageViewCreateInfo; + +typedef struct VkShaderModuleCreateInfo { + VkStructureType sType; + const void* pNext; + VkShaderModuleCreateFlags flags; + size_t codeSize; + const uint32_t* pCode; +} VkShaderModuleCreateInfo; + +typedef struct VkPipelineCacheCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCacheCreateFlags flags; + size_t initialDataSize; + const void* pInitialData; +} VkPipelineCacheCreateInfo; + +typedef struct VkSpecializationMapEntry { + uint32_t constantID; + uint32_t offset; + size_t size; +} VkSpecializationMapEntry; + +typedef struct VkSpecializationInfo { + uint32_t mapEntryCount; + const VkSpecializationMapEntry* pMapEntries; + size_t dataSize; + const void* pData; +} VkSpecializationInfo; + +typedef struct VkPipelineShaderStageCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineShaderStageCreateFlags flags; + VkShaderStageFlagBits stage; + VkShaderModule module; + const char* pName; + const VkSpecializationInfo* pSpecializationInfo; +} VkPipelineShaderStageCreateInfo; + +typedef struct VkVertexInputBindingDescription { + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkVertexInputAttributeDescription { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkPipelineVertexInputStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineVertexInputStateCreateFlags flags; + uint32_t vertexBindingDescriptionCount; + const VkVertexInputBindingDescription* pVertexBindingDescriptions; + uint32_t vertexAttributeDescriptionCount; + const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; +} VkPipelineVertexInputStateCreateInfo; + +typedef struct VkPipelineInputAssemblyStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +typedef struct VkPipelineTessellationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +typedef struct VkViewport { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +typedef struct VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkPipelineViewportStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport* pViewports; + uint32_t scissorCount; + const VkRect2D* pScissors; +} VkPipelineViewportStateCreateInfo; + +typedef struct VkPipelineRasterizationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateCreateFlags flags; + VkBool32 depthClampEnable; + VkBool32 rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + VkBool32 depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; +} VkPipelineRasterizationStateCreateInfo; + +typedef struct VkPipelineMultisampleStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineMultisampleStateCreateFlags flags; + VkSampleCountFlagBits rasterizationSamples; + VkBool32 sampleShadingEnable; + float minSampleShading; + const VkSampleMask* pSampleMask; + VkBool32 alphaToCoverageEnable; + VkBool32 alphaToOneEnable; +} VkPipelineMultisampleStateCreateInfo; + +typedef struct VkStencilOpState { + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkPipelineDepthStencilStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDepthStencilStateCreateFlags flags; + VkBool32 depthTestEnable; + VkBool32 depthWriteEnable; + VkCompareOp depthCompareOp; + VkBool32 depthBoundsTestEnable; + VkBool32 stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; +} VkPipelineDepthStencilStateCreateInfo; + +typedef struct VkPipelineColorBlendAttachmentState { + VkBool32 blendEnable; + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; + VkColorComponentFlags colorWriteMask; +} VkPipelineColorBlendAttachmentState; + +typedef struct VkPipelineColorBlendStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineColorBlendStateCreateFlags flags; + VkBool32 logicOpEnable; + VkLogicOp logicOp; + uint32_t attachmentCount; + const VkPipelineColorBlendAttachmentState* pAttachments; + float blendConstants[4]; +} VkPipelineColorBlendStateCreateInfo; + +typedef struct VkPipelineDynamicStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState* pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkGraphicsPipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; + const VkPipelineViewportStateCreateInfo* pViewportState; + const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkRenderPass renderPass; + uint32_t subpass; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkGraphicsPipelineCreateInfo; + +typedef struct VkComputePipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo stage; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + +typedef struct VkPushConstantRange { + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; +} VkPushConstantRange; + +typedef struct VkPipelineLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineLayoutCreateFlags flags; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; +} VkPipelineLayoutCreateInfo; + +typedef struct VkSamplerCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerCreateFlags flags; + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; +} VkSamplerCreateInfo; + +typedef struct VkDescriptorSetLayoutBinding { + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler* pImmutableSamplers; +} VkDescriptorSetLayoutBinding; + +typedef struct VkDescriptorSetLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding* pBindings; +} VkDescriptorSetLayoutCreateInfo; + +typedef struct VkDescriptorPoolSize { + VkDescriptorType type; + uint32_t descriptorCount; +} VkDescriptorPoolSize; + +typedef struct VkDescriptorPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPoolCreateFlags flags; + uint32_t maxSets; + uint32_t poolSizeCount; + const VkDescriptorPoolSize* pPoolSizes; +} VkDescriptorPoolCreateInfo; + +typedef struct VkDescriptorSetAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPool descriptorPool; + uint32_t descriptorSetCount; + const VkDescriptorSetLayout* pSetLayouts; +} VkDescriptorSetAllocateInfo; + +typedef struct VkDescriptorImageInfo { + VkSampler sampler; + VkImageView imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; + +typedef struct VkDescriptorBufferInfo { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize range; +} VkDescriptorBufferInfo; + +typedef struct VkWriteDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + const VkDescriptorImageInfo* pImageInfo; + const VkDescriptorBufferInfo* pBufferInfo; + const VkBufferView* pTexelBufferView; +} VkWriteDescriptorSet; + +typedef struct VkCopyDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; + +typedef struct VkFramebufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkFramebufferCreateFlags flags; + VkRenderPass renderPass; + uint32_t attachmentCount; + const VkImageView* pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + +typedef struct VkAttachmentDescription { + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription; + +typedef struct VkAttachmentReference { + uint32_t attachment; + VkImageLayout layout; +} VkAttachmentReference; + +typedef struct VkSubpassDescription { + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t inputAttachmentCount; + const VkAttachmentReference* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference* pColorAttachments; + const VkAttachmentReference* pResolveAttachments; + const VkAttachmentReference* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription; + +typedef struct VkSubpassDependency { + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + +typedef struct VkRenderPassCreateInfo { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency* pDependencies; +} VkRenderPassCreateInfo; + +typedef struct VkCommandPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo; + +typedef struct VkCommandBufferAllocateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo; + +typedef struct VkCommandBufferInheritanceInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + uint32_t subpass; + VkFramebuffer framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo; + +typedef struct VkCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + VkCommandBufferUsageFlags flags; + const VkCommandBufferInheritanceInfo* pInheritanceInfo; +} VkCommandBufferBeginInfo; + +typedef struct VkBufferCopy { + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy; + +typedef struct VkImageSubresourceLayers { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceLayers; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +typedef struct VkImageBlit { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkBufferImageCopy { + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef union VkClearColorValue { + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +typedef struct VkClearDepthStencilValue { + float depth; + uint32_t stencil; +} VkClearDepthStencilValue; + +typedef union VkClearValue { + VkClearColorValue color; + VkClearDepthStencilValue depthStencil; +} VkClearValue; + +typedef struct VkClearAttachment { + VkImageAspectFlags aspectMask; + uint32_t colorAttachment; + VkClearValue clearValue; +} VkClearAttachment; + +typedef struct VkClearRect { + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + +typedef struct VkImageResolve { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve; + +typedef struct VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkBufferMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier; + +typedef struct VkImageMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + VkRect2D renderArea; + uint32_t clearValueCount; + const VkClearValue* pClearValues; +} VkRenderPassBeginInfo; + +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkDrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); +typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); +typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); +typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); +typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); +typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); +typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); +typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); +typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); +typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); +typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); +typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); +typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); +typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); +typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( + VkInstance instance, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkImageFormatProperties* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties* pMemoryProperties); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( + VkInstance instance, + const char* pName); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( + VkDevice device, + const char* pName); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( + VkQueue queue); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( + VkDevice device); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( + VkDevice device, + const VkMemoryAllocateInfo* pAllocateInfo, + const VkAllocationCallbacks* pAllocator, + VkDeviceMemory* pMemory); + +VKAPI_ATTR void VKAPI_CALL vkFreeMemory( + VkDevice device, + VkDeviceMemory memory, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize offset, + VkDeviceSize size, + VkMemoryMapFlags flags, + void** ppData); + +VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( + VkDevice device, + VkDeviceMemory memory); + +VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize* pCommittedMemoryInBytes); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( + VkDevice device, + VkBuffer buffer, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( + VkDevice device, + VkImage image, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( + VkDevice device, + VkBuffer buffer, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( + VkDevice device, + VkImage image, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( + VkDevice device, + VkImage image, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkSampleCountFlagBits samples, + VkImageUsageFlags usage, + VkImageTiling tiling, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( + VkQueue queue, + uint32_t bindInfoCount, + const VkBindSparseInfo* pBindInfo, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( + VkDevice device, + const VkFenceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFence( + VkDevice device, + VkFence fence, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( + VkDevice device, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( + VkDevice device, + const VkSemaphoreCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSemaphore* pSemaphore); + +VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( + VkDevice device, + VkSemaphore semaphore, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( + VkDevice device, + const VkEventCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkEvent* pEvent); + +VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( + VkDevice device, + VkEvent event, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( + VkDevice device, + const VkQueryPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkQueryPool* pQueryPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( + VkDevice device, + VkQueryPool queryPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + void* pData, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( + VkDevice device, + const VkBufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBuffer* pBuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( + VkDevice device, + VkBuffer buffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( + VkDevice device, + const VkBufferViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBufferView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( + VkDevice device, + VkBufferView bufferView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( + VkDevice device, + const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImage( + VkDevice device, + VkImage image, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( + VkDevice device, + VkImage image, + const VkImageSubresource* pSubresource, + VkSubresourceLayout* pLayout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( + VkDevice device, + const VkImageViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImageView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( + VkDevice device, + VkImageView imageView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule); + +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( + VkDevice device, + VkShaderModule shaderModule, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( + VkDevice device, + const VkPipelineCacheCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineCache* pPipelineCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( + VkDevice device, + VkPipelineCache pipelineCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( + VkDevice device, + VkPipelineCache pipelineCache, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( + VkDevice device, + VkPipelineCache dstCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkComputePipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( + VkDevice device, + VkPipeline pipeline, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( + VkDevice device, + const VkPipelineLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineLayout* pPipelineLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( + VkDevice device, + VkPipelineLayout pipelineLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( + VkDevice device, + const VkSamplerCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSampler* pSampler); + +VKAPI_ATTR void VKAPI_CALL vkDestroySampler( + VkDevice device, + VkSampler sampler, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorSetLayout* pSetLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( + VkDevice device, + VkDescriptorSetLayout descriptorSetLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( + VkDevice device, + const VkDescriptorPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorPool* pDescriptorPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( + VkDevice device, + const VkDescriptorSetAllocateInfo* pAllocateInfo, + VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( + VkDevice device, + VkDescriptorPool descriptorPool, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( + VkDevice device, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet* pDescriptorCopies); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( + VkDevice device, + const VkFramebufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFramebuffer* pFramebuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( + VkDevice device, + VkFramebuffer framebuffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( + VkDevice device, + const VkRenderPassCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( + VkDevice device, + VkRenderPass renderPass, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( + VkDevice device, + VkRenderPass renderPass, + VkExtent2D* pGranularity); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( + VkDevice device, + const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCommandPool* pCommandPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( + VkDevice device, + VkCommandPool commandPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( + VkDevice device, + const VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( + VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo* pBeginInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( + VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( + VkCommandBuffer commandBuffer, + uint32_t firstScissor, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( + VkCommandBuffer commandBuffer, + float lineWidth); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( + VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, + float depthBiasClamp, + float depthBiasSlopeFactor); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( + VkCommandBuffer commandBuffer, + const float blendConstants[4]); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( + VkCommandBuffer commandBuffer, + float minDepthBounds, + float maxDepthBounds); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdDraw( + VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( + VkCommandBuffer commandBuffer, + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( + VkCommandBuffer commandBuffer, + uint32_t x, + uint32_t y, + uint32_t z); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit* pRegions, + VkFilter filter); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize dataSize, + const uint32_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment* pAttachments, + uint32_t rectCount, + const VkClearRect* pRects); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void* pValues); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( + VkCommandBuffer commandBuffer, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); +#endif + +#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" + + +typedef enum VkColorSpaceKHR { + VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLORSPACE_BEGIN_RANGE = VK_COLORSPACE_SRGB_NONLINEAR_KHR, + VK_COLORSPACE_END_RANGE = VK_COLORSPACE_SRGB_NONLINEAR_KHR, + VK_COLORSPACE_RANGE_SIZE = (VK_COLORSPACE_SRGB_NONLINEAR_KHR - VK_COLORSPACE_SRGB_NONLINEAR_KHR + 1), + VK_COLORSPACE_MAX_ENUM = 0x7FFFFFFF +} VkColorSpaceKHR; + +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_BEGIN_RANGE = VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_END_RANGE = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + VK_PRESENT_MODE_RANGE_SIZE = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), + VK_PRESENT_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPresentModeKHR; + + +typedef enum VkSurfaceTransformFlagBitsKHR { + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, +} VkSurfaceTransformFlagBitsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; + +typedef enum VkCompositeAlphaFlagBitsKHR { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, +} VkCompositeAlphaFlagBitsKHR; +typedef VkFlags VkCompositeAlphaFlagsKHR; + +typedef struct VkSurfaceCapabilitiesKHR { + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkSurfaceFormatKHR { + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + + +typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( + VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32* pSupported); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormatKHR* pSurfaceFormats); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); +#endif + +#define VK_KHR_swapchain 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) + +#define VK_KHR_SWAPCHAIN_SPEC_VERSION 67 +#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" + +typedef VkFlags VkSwapchainCreateFlagsKHR; + +typedef struct VkSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR oldSwapchain; +} VkSwapchainCreateInfoKHR; + +typedef struct VkPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR* pSwapchains; + const uint32_t* pImageIndices; + VkResult* pResults; +} VkPresentInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); +typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); +typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( + VkDevice device, + const VkSwapchainCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchain); + +VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( + VkDevice device, + VkSwapchainKHR swapchain, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pSwapchainImageCount, + VkImage* pSwapchainImages); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t timeout, + VkSemaphore semaphore, + VkFence fence, + uint32_t* pImageIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( + VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); +#endif + +#define VK_KHR_display 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) + +#define VK_KHR_DISPLAY_SPEC_VERSION 21 +#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" + + +typedef enum VkDisplayPlaneAlphaFlagBitsKHR { + VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, +} VkDisplayPlaneAlphaFlagBitsKHR; +typedef VkFlags VkDisplayModeCreateFlagsKHR; +typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; +typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; + +typedef struct VkDisplayPropertiesKHR { + VkDisplayKHR display; + const char* displayName; + VkExtent2D physicalDimensions; + VkExtent2D physicalResolution; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkBool32 planeReorderPossible; + VkBool32 persistentContent; +} VkDisplayPropertiesKHR; + +typedef struct VkDisplayModeParametersKHR { + VkExtent2D visibleRegion; + uint32_t refreshRate; +} VkDisplayModeParametersKHR; + +typedef struct VkDisplayModePropertiesKHR { + VkDisplayModeKHR displayMode; + VkDisplayModeParametersKHR parameters; +} VkDisplayModePropertiesKHR; + +typedef struct VkDisplayModeCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeCreateFlagsKHR flags; + VkDisplayModeParametersKHR parameters; +} VkDisplayModeCreateInfoKHR; + +typedef struct VkDisplayPlaneCapabilitiesKHR { + VkDisplayPlaneAlphaFlagsKHR supportedAlpha; + VkOffset2D minSrcPosition; + VkOffset2D maxSrcPosition; + VkExtent2D minSrcExtent; + VkExtent2D maxSrcExtent; + VkOffset2D minDstPosition; + VkOffset2D maxDstPosition; + VkExtent2D minDstExtent; + VkExtent2D maxDstExtent; +} VkDisplayPlaneCapabilitiesKHR; + +typedef struct VkDisplayPlanePropertiesKHR { + VkDisplayKHR currentDisplay; + uint32_t currentStackIndex; +} VkDisplayPlanePropertiesKHR; + +typedef struct VkDisplaySurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplaySurfaceCreateFlagsKHR flags; + VkDisplayModeKHR displayMode; + uint32_t planeIndex; + uint32_t planeStackIndex; + VkSurfaceTransformFlagBitsKHR transform; + float globalAlpha; + VkDisplayPlaneAlphaFlagBitsKHR alphaMode; + VkExtent2D imageExtent; +} VkDisplaySurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR*pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlanePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( + VkPhysicalDevice physicalDevice, + uint32_t planeIndex, + uint32_t* pDisplayCount, + VkDisplayKHR* pDisplays); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + const VkDisplayModeCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDisplayModeKHR* pMode); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayModeKHR mode, + uint32_t planeIndex, + VkDisplayPlaneCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( + VkInstance instance, + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#define VK_KHR_display_swapchain 1 +#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9 +#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" + +typedef struct VkDisplayPresentInfoKHR { + VkStructureType sType; + const void* pNext; + VkRect2D srcRect; + VkRect2D dstRect; + VkBool32 persistent; +} VkDisplayPresentInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchains); +#endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR +#define VK_KHR_xlib_surface 1 +#include + +#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); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( + VkInstance instance, + const VkXlibSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + Display* dpy, + VisualID visualID); +#endif +#endif /* VK_USE_PLATFORM_XLIB_KHR */ + +#ifdef VK_USE_PLATFORM_XCB_KHR +#define VK_KHR_xcb_surface 1 +#include + +#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); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( + VkInstance instance, + const VkXcbSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t* connection, + xcb_visualid_t visual_id); +#endif +#endif /* VK_USE_PLATFORM_XCB_KHR */ + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#define VK_KHR_wayland_surface 1 +#include + +#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); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( + VkInstance instance, + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct wl_display* display); +#endif +#endif /* VK_USE_PLATFORM_WAYLAND_KHR */ + +#ifdef VK_USE_PLATFORM_MIR_KHR +#define VK_KHR_mir_surface 1 +#include + +#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); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( + VkInstance instance, + const VkMirSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + MirConnection* connection); +#endif +#endif /* VK_USE_PLATFORM_MIR_KHR */ + +#ifdef VK_USE_PLATFORM_ANDROID_KHR +#define VK_KHR_android_surface 1 +#include + +#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); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( + VkInstance instance, + const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif +#endif /* VK_USE_PLATFORM_ANDROID_KHR */ + +#ifdef VK_USE_PLATFORM_WIN32_KHR +#define VK_KHR_win32_surface 1 +#include + +#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); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( + VkInstance instance, + const VkWin32SurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex); +#endif +#endif /* VK_USE_PLATFORM_WIN32_KHR */ + +#define VK_EXT_debug_report 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) + +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 1 +#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" + + +typedef enum VkDebugReportObjectTypeEXT { + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, + VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, + VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, + VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, + VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, + VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, + VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, + VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, + VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, + VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, + VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = 28, +} VkDebugReportObjectTypeEXT; + +typedef enum VkDebugReportErrorEXT { + VK_DEBUG_REPORT_ERROR_NONE_EXT = 0, + VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT = 1, +} VkDebugReportErrorEXT; + + +typedef enum VkDebugReportFlagBitsEXT { + VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, + VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, + VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, +} VkDebugReportFlagBitsEXT; +typedef VkFlags VkDebugReportFlagsEXT; + +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData); + + +typedef struct VkDebugReportCallbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportFlagsEXT flags; + PFN_vkDebugReportCallbackEXT pfnCallback; + void* pUserData; +} VkDebugReportCallbackCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugReportCallbackEXT* pCallback); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( + VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 8fecf1aa1..696cb2cf1 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -674,6 +674,7 @@ INPUT = @GLFW_INTERNAL_DOCS@ \ @GLFW_SOURCE_DIR@/docs/monitor.dox \ @GLFW_SOURCE_DIR@/docs/window.dox \ @GLFW_SOURCE_DIR@/docs/input.dox \ + @GLFW_SOURCE_DIR@/docs/vulkan.dox \ @GLFW_SOURCE_DIR@/docs/rift.dox \ @GLFW_SOURCE_DIR@/docs/compat.dox @@ -1590,7 +1591,8 @@ PREDEFINED = GLFWAPI= \ GLFW_EXPOSE_NATIVE_GLX \ GLFW_EXPOSE_NATIVE_COCOA \ GLFW_EXPOSE_NATIVE_NSGL \ - GLFW_EXPOSE_NATIVE_EGL + GLFW_EXPOSE_NATIVE_EGL \ + VK_VERSION_1_0 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/docs/build.dox b/docs/build.dox index 1554798b9..16cb35a4f 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -80,6 +80,9 @@ header instead of the regular OpenGL header. `GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` header instead of the regular OpenGL header. +`GLFW_INCLUDE_VULKAN` makes the GLFW header include the Vulkan `vulkan/vulkan.h` +header instead of the regular OpenGL header. + `GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API header. This is useful in combination with an extension loading library. diff --git a/docs/compat.dox b/docs/compat.dox index e7aa8d870..be1cf70d9 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -186,4 +186,43 @@ setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to a non-default value will cause @ref glfwCreateWindow to fail and the `GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. + +@section compat_vulkan Vulkan loader and API + +GLFW uses the standard system-wside Vulkan loader to access the Vulkan API. +This should be installed by graphics drivers and Vulkan SDKs. If this is not +available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other +Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error. + + +@section compat_wsi Vulkan WSI extensions + +The Vulkan WSI extensions are used to create Vulkan surfaces for GLFW windows on +all supported platforms. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create +surfaces on Microsoft Windows. If any of these extensions are not available, +@ref glfwGetRequiredInstanceExtensions will return an empty list and window +surface creation will fail. + +GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or +`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface` +or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create +surfaces on Wayland. If any of these extensions are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_mir_surface` extensions to create +surfaces on Mir. If any of these extensions are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW does not support any extensions for window surface creation on OS X, +meaning@ref glfwGetRequiredInstanceExtensions will return an empty list and +window surface creation will fail. + */ diff --git a/docs/context.dox b/docs/context.dox index 715455362..57aed221a 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -26,6 +26,11 @@ as the context handle. To test the creation of various kinds of contexts and see their properties, run the `glfwinfo` test program. +@note Vulkan does not have a context and the Vulkan instance is created via the +Vulkan API itself. If you will be using Vulkan to render to a window, disable +context creation by setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to +`GLFW_NO_API`. For more information, see the @ref vulkan. + @subsection context_hints Context creation hints diff --git a/docs/main.dox b/docs/main.dox index 11404810e..9b59822e5 100644 --- a/docs/main.dox +++ b/docs/main.dox @@ -4,9 +4,9 @@ @section main_intro Introduction -__GLFW__ is a free, Open Source, multi-platform library for creating windows -with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy -to integrate into existing applications and does not lay claim to the main loop. +GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and +Vulkan application development. It provides a simple, platform-independent API +for creating windows, contexts and surfaces, reading input, handling events, etc. See @ref news_32 for release highlights or the [version history](http://www.glfw.org/changelog.html) for details. @@ -32,6 +32,8 @@ about specific functions. There is a section on @ref guarantees_limitations for pointer lifetimes, reentrancy, thread safety, event order and backward and forward compatibility. +The @ref vulkan guide fills in the gaps for how to use Vulkan with GLFW. + The @ref rift fills in the gaps for how to use LibOVR with GLFW. The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the diff --git a/docs/news.dox b/docs/news.dox index 93026658b..0ccb4c89d 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -17,6 +17,15 @@ GLFW now supports querying the localized name of printable keys with @ref glfwGetKeyName, either by key token or by scancode. +@subsection news_32_vulkan Support for Vulkan + +GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported, +@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref +glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface. +Vulkan header inclusion can be selected with +[GLFW_INCLUDE_VULKAN](@ref build_macros). + + @section news_31 New features in 3.1 These are the release highlights. For a full list of changes see the diff --git a/docs/vulkan.dox b/docs/vulkan.dox new file mode 100644 index 000000000..7cd25abc2 --- /dev/null +++ b/docs/vulkan.dox @@ -0,0 +1,185 @@ +/*! + +@page vulkan Vulkan guide + +@tableofcontents + +This guide is intended to fill the gaps between the Vulkan documentation and the +rest of the GLFW documentation and is not a replacement for either. + +To develop for Vulkan you should install an SDK for your platform, for example +the [LunarG Vulkan SDK](http://lunarg.com/vulkan-sdk/). Apart from the headers +and libraries, it also provides the validation layers necessary for development. + +GLFW itself does not need a Vulkan SDK to enable support for Vulkan. However, +any Vulkan-specific test and example programs are built only if the CMake files +find the LunarG SDK. + + +@section vulkan_include Including the Vulkan and GLFW header files + +To include the Vulkan header, define `GLFW_INCLUDE_VULKAN` before including the +GLFW header. + +@code +#define GLFW_INCLUDE_VULKAN +#include +@endcode + +If you want to include the Vulkan header from a custom location or use your own +custom Vulkan header then you need to include them before the GLFW header. + +@code +#include +#include +@endcode + +Unless a Vulkan header is included, either by the GLFW header or above it, any +GLFW functions that use Vulkan types will not be declared. + +The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part +of GLFW to work. + + +@section vulkan_support Querying for Vulkan support + +If you are loading the Vulkan loader dynamically instead of linking directly +against it, you can check for the availability of a loader with @ref +glfwVulkanSupported. + +@code +if (glfwVulkanSupported()) +{ + // Vulkan is available, at least for compute +} +@endcode + +This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is +performed by @ref glfwInit. + +If no loader was found, calling any other Vulkan related GLFW function will +generate a @ref GLFW_API_UNAVAILABLE error. + + +@subsection vulkan_proc Querying Vulkan function pointers + +To load any Vulkan core or extension function from the found loader, call @ref +glfwGetInstanceProcAddress. + +@code +PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice) + glfwGetInstanceProcAddress(instance, "vkCreateDevice"); +@endcode + +This is equivalent to calling `vkGetInstanceProcAddr`. If that fails, the +function falls back to a platform-specific query of the Vulkan loader (i.e. +`dlsym` or `GetProcAddress`). If that also fails, the function returns `NULL`. +For more information about `vkGetInstanceProcAddr`, see the Vulkan +documentation. + +Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions +of Vulkan function. This function can be retrieved from an instance with @ref +glfwGetInstanceProcAddress. + +@code +PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) + glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); +@endcode + +Device-specific functions may execute a little bit faster, due to not having to +dispatch internally based on the device passed to them. For more information +about `vkGetDeviceProcAddr`, see the Vulkan documentation. + + +@section vulkan_ext Querying required Vulkan extensions + +To do anything useful with Vulkan you need to create an instance. If you want +to use Vulkan to render to a window, you must enable the instance extensions +GLFW requires to create Vulkan surfaces. + +To query the instance extensions required, call @ref +glfwGetRequiredInstanceExtensions. + +@code +int count; +const char** extensions = glfwGetRequiredInstanceExtensions(&count); +@endcode + +These extensions must all be enabled when creating instances that are going to +be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref +glfwCreateWindowSurface. The set of extensions will vary depending on platform +and may also vary depending on graphics drivers and other factors. + +If it fails it will return `NULL` and Vulkan window surface creation will not be +possible. You may still use Vulkan for off-screen rendering and compute work. + +The returned array will always contain `VK_KHR_surface`, so if you don't +require any additional extensions you can pass this list directly to the +`VkInstanceCreateInfo` struct. + +@code +VkInstanceCreateInfo ici; + +memset(&ici, 0, sizeof(ici)); +ici.enabledExtensionCount = count; +ici.ppEnabledExtensionNames = extensions; +... +@endcode + +Additional extensions may be required by future versions of GLFW. You should +check whether any extensions you wish to enable are already in the returned +array, as it is an error to specify an extension more than once in the +`VkInstanceCreateInfo` struct. + + +@section vulkan_present Querying for Vulkan presentation support + +Not every Vulkan queue family of every device can present images to surfaces. +To check whether a specific queue family of a physical device supports image +presentation without first having to create a window and surface, call @ref +glfwGetPhysicalDevicePresentationSupport. + +@code +if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index)) +{ + // Queue family supports image presentation +} +@endcode + +The `VK_KHR_surface` extension also provides the +`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on +an existing Vulkan surface. + + +@section vulkan_window Creating the window + +Unless you will be using OpenGL or OpenGL ES in addition to Vulkan, there is no +need to create a context for that window. You can disable context creation by +setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`. + +@code +glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); +@endcode + +See @ref context_less for more information. + + +@section vulkan_surface Creating a Vulkan window surface + +You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension) +for a GLFW window with @ref glfwCreateWindowSurface. + +@code +VkSurfaceKHR surface; +VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface); +if (err) +{ + // Window surface creation failed +} +@endcode + +It is your responsibility to destroy the surface. GLFW does not destroy it for +you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it. + +*/ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7d8a41af2..138a78166 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,6 +1,8 @@ link_libraries(glfw) +include_directories(${glfw_INCLUDE_DIRS}) + if (BUILD_SHARED_LIBS) link_libraries("${MATH_LIBRARY}") endif() diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index fc1a54425..71aac1713 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -51,6 +51,11 @@ extern "C" { * This is the reference documentation for context related functions. For more * information, see the @ref context. */ +/*! @defgroup vulkan Vulkan support + * + * This is the reference documentation for Vulkan related functions. For more + * information, see the @ref vulkan. + */ /*! @defgroup init Initialization, version and errors * * This is the reference documentation for initialization and termination of @@ -157,6 +162,8 @@ extern "C" { #if defined(GLFW_INCLUDE_GLEXT) #include #endif + #elif defined(GLFW_INCLUDE_VULKAN) + #include #elif !defined(GLFW_INCLUDE_NONE) #include #if defined(GLFW_INCLUDE_GLEXT) @@ -539,15 +546,12 @@ extern "C" { * to our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_OUT_OF_MEMORY 0x00010005 -/*! @brief GLFW could not find support for the requested client API on the - * system. +/*! @brief GLFW could not find support for the requested API on the system. * - * GLFW could not find support for the requested client API on the system. If - * emitted by functions other than @ref glfwCreateWindow, no supported client - * API was found. + * GLFW could not find support for the requested API on the system. * * @analysis The installed graphics driver does not support the requested - * client API, or does not support it via the chosen context creation backend. + * API, or does not support it via the chosen context creation backend. * Below are a few examples. * * @par @@ -555,7 +559,7 @@ extern "C" { * supports OpenGL ES via EGL, while Nvidia and Intel only support it via * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary - * driver. + * driver. Older graphics drivers do not support Vulkan. */ #define GLFW_API_UNAVAILABLE 0x00010006 /*! @brief The requested OpenGL or OpenGL ES version is not available. @@ -738,6 +742,20 @@ extern "C" { */ typedef void (*GLFWglproc)(void); +/*! @brief Vulkan API function pointer type. + * + * Generic function pointer used for returning Vulkan API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref vulkan_proc + * @sa glfwGetInstanceProcAddress + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +typedef void (*GLFWvkproc)(void); + /*! @brief Opaque monitor object. * * Opaque monitor object. @@ -3656,6 +3674,204 @@ GLFWAPI int glfwExtensionSupported(const char* extension); */ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); +/*! @brief Returns whether the Vulkan loader has been found. + * + * This function returns whether the Vulkan loader has been found. This check + * is performed by @ref glfwInit. + * + * The availability of a Vulkan loader does not by itself guarantee that window + * surface creation or even device creation is possible. Call @ref + * glfwGetRequiredInstanceExtensions to check whether the extensions necessary + * for Vulkan surface creation are available and @ref + * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of + * a physical device supports image presentation. + * + * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_support + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwVulkanSupported(void); + +/*! @brief Returns the Vulkan instance extensions required by GLFW. + * + * This function returns an array of names of Vulkan instance extensions required + * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the + * list will always contains `VK_KHR_surface`, so if you don't require any + * additional extensions you can pass this list directly to the + * `VkInstanceCreateInfo` struct. + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * If Vulkan is available but no set of extensions allowing window surface + * creation was found, this function returns `NULL`. You may still use Vulkan + * for off-screen rendering and compute work. + * + * @param[out] count Where to store the number of extensions in the returned + * array. This is set to zero if an error occurred. + * @return An array of ASCII encoded extension names, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @remarks Additional extensions may be required by future versions of GLFW. + * You should check if any extensions you wish to enable are already in the + * returned array, as it is an error to specify an extension more than once in + * the `VkInstanceCreateInfo` struct. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_ext + * @sa glfwCreateWindowSurface + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI const char** glfwGetRequiredInstanceExtensions(int* count); + +#if defined(VK_VERSION_1_0) + +/*! @brief Returns the address of the specified Vulkan instance function. + * + * This function returns the address of the specified Vulkan core or extension + * function for the specified instance. If instance is set to `NULL` it can + * return any function exported from the Vulkan loader, including at least the + * following functions: + * + * - `vkEnumerateInstanceExtensionProperties` + * - `vkEnumerateInstanceLayerProperties` + * - `vkCreateInstance` + * - `vkGetInstanceProcAddr` + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * This function is equivalent to calling `vkGetInstanceProcAddr` with + * a platform-specific query of the Vulkan loader as a fallback. + * + * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve + * functions related to instance creation. + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @pointer_lifetime The returned function pointer is valid until the library + * is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_proc + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); + +/*! @brief Returns whether the specified queue family can present images. + * + * This function returns whether the specified queue family of the specified + * physical device supports presentation to the platform GLFW was built for. + * + * If Vulkan or the required window surface creation instance extensions are + * not available on the machine, or if the specified instance was not created + * with the required extensions, this function returns `GLFW_FALSE` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available and @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * @param[in] instance The instance that the physical device belongs to. + * @param[in] device The physical device that the queue family belongs to. + * @param[in] queuefamily The index of the queue family to query. + * @return `GLFW_TRUE` if the queue family supports presentation, or + * `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_present + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @brief Creates a Vulkan surface for the specified window. + * + * This function creates a Vulkan surface for the specified window. + * + * If the Vulkan loader was not found at initialization, this function returns + * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE + * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was + * found. + * + * If the required window surface creation instance extensions are not + * available or if the specified instance was not created with these extensions + * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * The window surface must be destroyed before the specified Vulkan instance. + * It is the responsibility of the caller to destroy the window surface. GLFW + * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the + * surface. + * + * @param[in] instance The Vulkan instance to create the surface in. + * @param[in] window The window to create the surface for. + * @param[in] allocator The allocator to use, or `NULL` to use the default + * allocator. + * @param[out] surface Where to store the handle of the surface. This is set + * to `VK_NULL_HANDLE` if an error occurred. + * @return `VK_SUCCESS` if successful, or a Vulkan error code if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remarks If an error occurs before the creation call is made, GLFW returns + * the Vulkan error code most appropriate for the error. Appropriate use of + * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should + * elminiate almost all occurences of these errors. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_surface + * @sa glfwGetRequiredInstanceExtensions + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +#endif /*VK_VERSION_1_0*/ + /************************************************************************* * Global definition cleanup diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f70e37e9..d44f873c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ set(common_HEADERS internal.h "${GLFW_BINARY_DIR}/src/glfw_config.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") -set(common_SOURCES context.c init.c input.c monitor.c window.c) +set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c) if (_GLFW_COCOA) set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 14b93b125..a2025e1da 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -28,6 +28,7 @@ #define _glfw3_cocoa_platform_h_ #include +#include #if defined(__OBJC__) #import @@ -47,6 +48,10 @@ typedef void* id; #error "The Cocoa backend depends on NSGL platform support" #endif +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) +#define _glfw_dlclose(handle) dlclose(handle) +#define _glfw_dlsym(handle, name) dlsym(handle, name) + #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 29a8334c8..fb03419ba 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1322,6 +1322,27 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) return _glfw.ns.clipboardString; } +char** _glfwPlatformGetRequiredInstanceExtensions(int* count) +{ + *count = 0; + return NULL; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + unsigned int queuefamily) +{ + return GLFW_FALSE; +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + return VK_ERROR_EXTENSION_NOT_PRESENT; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/egl_context.h b/src/egl_context.h index 7f4d4f7a5..c73e1e02a 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -28,17 +28,6 @@ #ifndef _glfw3_egl_context_h_ #define _glfw3_egl_context_h_ -#if defined(_GLFW_WIN32) - #define _glfw_dlopen(name) LoadLibraryA(name) - #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) - #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) -#else - #include - #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) - #define _glfw_dlclose(handle) dlclose(handle) - #define _glfw_dlsym(handle, name) dlsym(handle, name) -#endif - #if defined(_GLFW_USE_EGLPLATFORM_H) #include #elif defined(_GLFW_WIN32) diff --git a/src/glx_context.c b/src/glx_context.c index 8e8ccfd11..84c0c7015 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -30,7 +30,6 @@ #include #include #include -#include #ifndef GLXBadProfileARB #define GLXBadProfileARB 13 diff --git a/src/init.c b/src/init.c index 811fccec1..f245c7c14 100644 --- a/src/init.c +++ b/src/init.c @@ -130,6 +130,8 @@ GLFWAPI int glfwInit(void) return GLFW_FALSE; } + _glfwInitVulkan(); + _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); _glfwInitialized = GLFW_TRUE; @@ -161,6 +163,8 @@ GLFWAPI void glfwTerminate(void) _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); } + _glfwTerminateVulkan(); + _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); _glfw.monitors = NULL; _glfw.monitorCount = 0; diff --git a/src/internal.h b/src/internal.h index 206b7e50f..a1664baef 100644 --- a/src/internal.h +++ b/src/internal.h @@ -47,6 +47,26 @@ #define GLFW_INCLUDE_NONE #include "../include/GLFW/glfw3.h" +#include + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef unsigned __int64 GLFWuint64; +#else + #include +typedef uint64_t GLFWuint64; +#endif + +typedef int GLFWbool; + +typedef struct _GLFWwndconfig _GLFWwndconfig; +typedef struct _GLFWctxconfig _GLFWctxconfig; +typedef struct _GLFWfbconfig _GLFWfbconfig; +typedef struct _GLFWcontext _GLFWcontext; +typedef struct _GLFWwindow _GLFWwindow; +typedef struct _GLFWlibrary _GLFWlibrary; +typedef struct _GLFWmonitor _GLFWmonitor; +typedef struct _GLFWcursor _GLFWcursor; + #define GL_VERSION 0x1f02 #define GL_NONE 0 #define GL_COLOR_BUFFER_BIT 0x00004000 @@ -76,16 +96,66 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); -typedef struct _GLFWwndconfig _GLFWwndconfig; -typedef struct _GLFWctxconfig _GLFWctxconfig; -typedef struct _GLFWfbconfig _GLFWfbconfig; -typedef struct _GLFWcontext _GLFWcontext; -typedef struct _GLFWwindow _GLFWwindow; -typedef struct _GLFWlibrary _GLFWlibrary; -typedef struct _GLFWmonitor _GLFWmonitor; -typedef struct _GLFWcursor _GLFWcursor; +#define VK_NULL_HANDLE 0 -typedef int GLFWbool; +typedef GLFWuint64 VkInstance; +typedef GLFWuint64 VkPhysicalDevice; +typedef GLFWuint64 VkSurfaceKHR; +typedef unsigned int VkFlags; +typedef unsigned int VkBool32; + +typedef enum VkStructureType +{ + 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_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkStructureType; + +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_SUBOPTIMAL_KHR = 1000001003, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_RESULT_MAX_ENUM = 0x7FFFFFFF +} VkResult; + +typedef struct VkAllocationCallbacks VkAllocationCallbacks; + +typedef struct VkExtensionProperties +{ + char extensionName[256]; + unsigned int specVersion; +} VkExtensionProperties; + +typedef void (APIENTRY * PFN_vkVoidFunction)(void); +typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); +typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,unsigned int*,VkExtensionProperties*); + +#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties +#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr #if defined(_GLFW_COCOA) #include "cocoa_platform.h" @@ -363,6 +433,21 @@ struct _GLFWlibrary _GLFWmonitor** monitors; int monitorCount; + struct { + GLFWbool available; + void* handle; + char** extensions; + int extensionCount; + PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + GLFWbool KHR_surface; + GLFWbool KHR_win32_surface; + GLFWbool KHR_xlib_surface; + GLFWbool KHR_xcb_surface; + GLFWbool KHR_wayland_surface; + GLFWbool KHR_mir_surface; + } vk; + struct { GLFWmonitorfun monitor; } callbacks; @@ -686,6 +771,18 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); */ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); +/*! @ingroup platform + */ +char** _glfwPlatformGetRequiredInstanceExtensions(int* count); + +/*! @ingroup platform + */ +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, unsigned int queuefamily); + +/*! @ingroup platform + */ +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + //======================================================================== // Event API functions @@ -920,4 +1017,16 @@ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); */ GLFWbool _glfwIsPrintable(int key); +/*! @ingroup utility + */ +void _glfwInitVulkan(void); + +/*! @ingroup utility + */ +void _glfwTerminateVulkan(void); + +/*! @ingroup utility + */ +const char* _glfwGetVulkanResultString(VkResult result); + #endif // _glfw3_internal_h_ diff --git a/src/mir_platform.h b/src/mir_platform.h index 7f31857dc..5d328c208 100644 --- a/src/mir_platform.h +++ b/src/mir_platform.h @@ -29,9 +29,24 @@ #include #include +#include #include +typedef VkFlags VkMirSurfaceCreateFlagsKHR; + +typedef struct VkMirSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkMirSurfaceCreateFlagsKHR flags; + MirConnection* connection; + MirSurface* mirSurface; +} VkMirSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*); + #include "posix_tls.h" #include "posix_time.h" #include "linux_joystick.h" @@ -43,6 +58,10 @@ #error "The Mir backend depends on EGL platform support" #endif +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) +#define _glfw_dlclose(handle) dlclose(handle) +#define _glfw_dlsym(handle, name) dlsym(handle, name) + #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display) diff --git a/src/mir_window.c b/src/mir_window.c index 05d362d20..88875f976 100644 --- a/src/mir_window.c +++ b/src/mir_window.c @@ -706,6 +706,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) return NULL; } +char** _glfwPlatformGetRequiredInstanceExtensions(int* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_mir_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_mir_surface"); + + *count = 2; + return extensions; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + unsigned int queuefamily) +{ + PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR = + (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR"); + if (!vkGetPhysicalDeviceMirPresentationSupportKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Mir: Vulkan instance missing VK_KHR_mir_surface extension"); + return GLFW_FALSE; + } + + return vkGetPhysicalDeviceMirPresentationSupportKHR(device, + queuefamily, + _glfw.mir.connection); +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + VkResult err; + VkMirSurfaceCreateInfoKHR sci; + PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR; + + vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR"); + if (!vkCreateMirSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Mir: Vulkan instance missing VK_KHR_mir_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR; + sci.display = _glfw.mir.connection; + sci.surface = window->mir.surface; + + err = vkCreateMirSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/vulkan.c b/src/vulkan.c new file mode 100644 index 000000000..b7b67fe57 --- /dev/null +++ b/src/vulkan.c @@ -0,0 +1,287 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// 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 "internal.h" + +#include +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInitVulkan(void) +{ + VkResult err; + VkExtensionProperties* ep; + unsigned int i, count; +#if defined(_GLFW_WIN32) + const char* name = "vulkan-1.dll"; +#else + const char* name = "libvulkan.so.1"; +#endif + + _glfw.vk.handle = _glfw_dlopen(name); + if (!_glfw.vk.handle) + return; + + _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) + _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); + if (!_glfw.vk.GetInstanceProcAddr) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Vulkan: Loader does not export vkGetInstanceProcAddr"); + return; + } + + _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) + vkGetInstanceProcAddr(0, "vkEnumerateInstanceExtensionProperties"); + if (!_glfw.vk.EnumerateInstanceExtensionProperties) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); + return; + } + + err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Vulkan: Failed to query instance extension count: %s", + _glfwGetVulkanResultString(err)); + return; + } + + ep = calloc(count, sizeof(VkExtensionProperties)); + + err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Vulkan: Failed to query instance extensions: %s", + _glfwGetVulkanResultString(err)); + + free(ep); + return; + } + + for (i = 0; i < count; i++) + { + if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) + _glfw.vk.KHR_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) + _glfw.vk.KHR_win32_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) + _glfw.vk.KHR_xlib_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) + _glfw.vk.KHR_xcb_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) + _glfw.vk.KHR_wayland_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0) + _glfw.vk.KHR_mir_surface = GLFW_TRUE; + } + + free(ep); + + _glfw.vk.available = GLFW_TRUE; + + if (!_glfw.vk.KHR_surface) + return; + + _glfw.vk.extensions = + _glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount); +} + +void _glfwTerminateVulkan(void) +{ + int i; + + for (i = 0; i < _glfw.vk.extensionCount; i++) + free(_glfw.vk.extensions[i]); + free(_glfw.vk.extensions); + + if (_glfw.vk.handle) + _glfw_dlclose(_glfw.vk.handle); +} + +const char* _glfwGetVulkanResultString(VkResult result) +{ + switch (result) + { + case VK_SUCCESS: + return "Success"; + case VK_NOT_READY: + return "A fence or query has not yet completed"; + case VK_TIMEOUT: + return "A wait operation has not completed in the specified time"; + case VK_EVENT_SET: + return "An event is signaled"; + case VK_EVENT_RESET: + return "An event is unsignaled"; + case VK_INCOMPLETE: + return "A return array was too small for the result"; + case VK_ERROR_OUT_OF_HOST_MEMORY: + return "A host memory allocation has failed"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + return "A device memory allocation has failed"; + case VK_ERROR_INITIALIZATION_FAILED: + return "Initialization of an object could not be completed for implementation-specific reasons"; + case VK_ERROR_DEVICE_LOST: + return "The logical or physical device has been lost"; + case VK_ERROR_MEMORY_MAP_FAILED: + return "Mapping of a memory object has failed"; + case VK_ERROR_LAYER_NOT_PRESENT: + return "A requested layer is not present or could not be loaded"; + case VK_ERROR_EXTENSION_NOT_PRESENT: + return "A requested extension is not supported"; + case VK_ERROR_FEATURE_NOT_PRESENT: + return "A requested feature is not supported"; + case VK_ERROR_INCOMPATIBLE_DRIVER: + return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible"; + case VK_ERROR_TOO_MANY_OBJECTS: + return "Too many objects of the type have already been created"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: + return "A requested format is not supported on this device"; + case VK_ERROR_SURFACE_LOST_KHR: + return "A surface is no longer available"; + case VK_SUBOPTIMAL_KHR: + return "A swapchain no longer matches the surface properties exactly, but can still be used"; + case VK_ERROR_OUT_OF_DATE_KHR: + return "A surface has changed in such a way that it is no longer compatible with the swapchain"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: + return "The display used by a swapchain does not use the same presentable image layout"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: + return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API"; + case VK_ERROR_VALIDATION_FAILED_EXT: + return "A validation layer found an error"; + default: + return "ERROR: UNKNOWN VULKAN ERROR TOKEN"; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI int glfwVulkanSupported(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + return _glfw.vk.available; +} + +GLFWAPI const char** glfwGetRequiredInstanceExtensions(int* count) +{ + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!_glfw.vk.available) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); + return NULL; + } + + *count = _glfw.vk.extensionCount; + return (const char**) _glfw.vk.extensions; +} + +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, + const char* procname) +{ + GLFWvkproc proc; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!_glfw.vk.available) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); + return NULL; + } + + proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); + if (!proc) + proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname); + + return proc; +} + +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + + if (!_glfw.vk.available) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); + return GLFW_FALSE; + } + + if (!_glfw.vk.extensions) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Vulkan: Window surface creation extensions not found"); + return GLFW_FALSE; + } + + return _glfwPlatformGetPhysicalDevicePresentationSupport(instance, + device, + queuefamily); +} + +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, + GLFWwindow* handle, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window); + + assert(surface); + *surface = VK_NULL_HANDLE; + + _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); + + if (!_glfw.vk.available) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (!_glfw.vk.extensions) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Vulkan: Window surface creation extensions not found"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface); +} + diff --git a/src/win32_platform.h b/src/win32_platform.h index 427663897..9c9983a84 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -140,6 +140,20 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID); typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); #define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness +typedef VkFlags VkWin32SurfaceCreateFlagsKHR; + +typedef struct VkWin32SurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkWin32SurfaceCreateFlagsKHR flags; + HINSTANCE hinstance; + HWND hwnd; +} VkWin32SurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t); + #include "win32_joystick.h" #if defined(_GLFW_WGL) @@ -154,6 +168,10 @@ typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); #define _GLFW_WNDCLASSNAME L"GLFW30" +#define _glfw_dlopen(name) LoadLibraryA(name) +#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) +#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) + #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time diff --git a/src/win32_window.c b/src/win32_window.c index 5f9295f2c..0de246db7 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1403,6 +1403,74 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) return _glfw.win32.clipboardString; } +char** _glfwPlatformGetRequiredInstanceExtensions(int* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_win32_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_win32_surface"); + + *count = 2; + return extensions; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + unsigned int queuefamily) +{ + PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = + (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); + if (!vkGetPhysicalDeviceWin32PresentationSupportKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Win32: Vulkan instance missing VK_KHR_win32_surface extension"); + return GLFW_FALSE; + } + + return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily); +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + VkResult err; + VkWin32SurfaceCreateInfoKHR sci; + PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; + + vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR"); + if (!vkCreateWin32SurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Win32: Vulkan instance missing VK_KHR_win32_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + sci.hinstance = GetModuleHandle(NULL); + sci.hwnd = window->win32.handle; + + err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/wl_platform.h b/src/wl_platform.h index 2bfdbb4ca..56ce16311 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -29,6 +29,21 @@ #include #include +#include + +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; + +typedef struct VkWaylandSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkWaylandSurfaceCreateFlagsKHR flags; + struct wl_display* display; + struct wl_surface* surface; +} VkWaylandSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); #include "posix_tls.h" #include "posix_time.h" @@ -41,6 +56,10 @@ #error "The Wayland backend depends on EGL platform support" #endif +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) +#define _glfw_dlclose(handle) dlclose(handle) +#define _glfw_dlsym(handle, name) dlsym(handle, name) + #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display) @@ -75,6 +94,7 @@ typedef struct _GLFWwindowWayland _GLFWmonitor** monitors; int monitorsCount; int monitorsSize; + } _GLFWwindowWayland; diff --git a/src/wl_window.c b/src/wl_window.c index 3a75daa42..75aa912e4 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -699,6 +699,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) return NULL; } +char** _glfwPlatformGetRequiredInstanceExtensions(int* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_wayland_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_wayland_surface"); + + *count = 2; + return extensions; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + unsigned int queuefamily) +{ + PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR = + (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"); + if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension"); + return VK_NULL_HANDLE; + } + + return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device, + queuefamily, + _glfw.wl.display); +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + VkResult err; + VkWaylandSurfaceCreateInfoKHR sci; + PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR; + + vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR"); + if (!vkCreateWaylandSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + sci.display = _glfw.wl.display; + sci.surface = window->wl.surface; + + err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/x11_init.c b/src/x11_init.c index c890a3261..e17a7170c 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -581,6 +581,13 @@ static GLFWbool initExtensions(void) } } + _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so", RTLD_LAZY | RTLD_GLOBAL); + if (_glfw.x11.x11xcb.handle) + { + _glfw.x11.x11xcb.XGetXCBConnection = (XGETXCBCONNECTION_T) + dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); + } + // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. @@ -789,6 +796,12 @@ int _glfwPlatformInit(void) void _glfwPlatformTerminate(void) { + if (_glfw.x11.x11xcb.handle) + { + dlclose(_glfw.x11.x11xcb.handle); + _glfw.x11.x11xcb.handle = NULL; + } + if (_glfw.x11.cursor) { XFreeCursor(_glfw.x11.display, _glfw.x11.cursor); diff --git a/src/x11_platform.h b/src/x11_platform.h index 34bfe053e..65aba0ed8 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,37 @@ #include #endif +typedef XID xcb_window_t; +typedef XID xcb_visualid_t; +typedef struct xcb_connection_t xcb_connection_t; +typedef xcb_connection_t* (* XGETXCBCONNECTION_T)(Display*); + +typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; + +typedef struct VkXlibSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display* dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + +typedef struct VkXcbSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkXcbSurfaceCreateFlagsKHR flags; + xcb_connection_t* connection; + xcb_window_t window; +} VkXcbSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID); +typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); + #include "posix_tls.h" #include "posix_time.h" #include "linux_joystick.h" @@ -71,6 +103,10 @@ #error "No supported context creation API selected" #endif +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) +#define _glfw_dlclose(handle) dlclose(handle) +#define _glfw_dlsym(handle, name) dlsym(handle, name) + #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 @@ -207,6 +243,11 @@ typedef struct _GLFWlibraryX11 int minor; } xinerama; + struct { + void* handle; + XGETXCBCONNECTION_T XGetXCBConnection; + } x11xcb; + #if defined(_GLFW_HAS_XINPUT) struct { GLFWbool available; diff --git a/src/x11_window.c b/src/x11_window.c index ba32169bd..8ffd81c57 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1470,13 +1470,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, Visual* visual; int depth; + if (ctxconfig->api == GLFW_NO_API) + { + visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen); + depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen); + } + else + { #if defined(_GLFW_GLX) - if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) - return GLFW_FALSE; + if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) + return GLFW_FALSE; #elif defined(_GLFW_EGL) - if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) - return GLFW_FALSE; + if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) + return GLFW_FALSE; #endif + } if (!createWindow(window, wndconfig, visual, depth)) return GLFW_FALSE; @@ -2109,6 +2117,158 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) return _glfw.x11.clipboardString; } +char** _glfwPlatformGetRequiredInstanceExtensions(int* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_xlib_surface) + { + if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle) + return NULL; + } + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + + if (_glfw.vk.KHR_xlib_surface) + extensions[1] = strdup("VK_KHR_xlib_surface"); + else + extensions[1] = strdup("VK_KHR_xcb_surface"); + + *count = 2; + return extensions; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + unsigned int queuefamily) +{ + VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display, + _glfw.x11.screen)); + + if (_glfw.vk.KHR_xlib_surface) + { + PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR = + (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR"); + if (!vkGetPhysicalDeviceXlibPresentationSupportKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Vulkan instance missing VK_KHR_xlib_surface extension"); + return GLFW_FALSE; + } + + return vkGetPhysicalDeviceXlibPresentationSupportKHR(device, + queuefamily, + _glfw.x11.display, + visualID); + } + else + { + PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR = + (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR"); + if (!vkGetPhysicalDeviceXcbPresentationSupportKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Vulkan instance missing VK_KHR_xcb_surface extension"); + return GLFW_FALSE; + } + + xcb_connection_t* connection = + _glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display); + if (!connection) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to retrieve XCB connection"); + return GLFW_FALSE; + } + + return vkGetPhysicalDeviceXcbPresentationSupportKHR(device, + queuefamily, + connection, + visualID); + } +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + if (_glfw.vk.KHR_xlib_surface) + { + VkResult err; + VkXlibSurfaceCreateInfoKHR sci; + PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR; + + vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR"); + if (!vkCreateXlibSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Vulkan instance missing VK_KHR_xlib_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + sci.dpy = _glfw.x11.display; + sci.window = window->x11.handle; + + err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to create Vulkan X11 surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; + } + else + { + VkResult err; + VkXcbSurfaceCreateInfoKHR sci; + PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR; + + xcb_connection_t* connection = + _glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display); + if (!connection) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to retrieve XCB connection"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR"); + if (!vkCreateXcbSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Vulkan instance missing VK_KHR_xcb_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + sci.connection = connection; + sci.window = window->x11.handle; + + err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to create Vulkan XCB surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; + } +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6488ef257..adf3004f6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -43,6 +43,13 @@ set(WINDOWS_BINARIES empty sharing tearing threads title windows) set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo iconify joysticks monitors reopen cursor) +if (VULKAN_FOUND) + add_executable(vulkan WIN32 vulkan.c ${ICON}) + target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}") + target_link_libraries(vulkan "${VULKAN_LIBRARY}") + list(APPEND WINDOWS_BINARIES vulkan) +endif() + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES FOLDER "GLFW3/Tests") diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index e90372788..fce3885f2 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -24,6 +24,7 @@ //======================================================================== #include +#include #include #include @@ -61,7 +62,8 @@ static void usage(void) printf(" -d, --debug request a debug context\n"); printf(" -f, --forward require a forward-compatible context\n"); printf(" -h, --help show this help\n"); - printf(" -l, --list-extensions list all client API extensions\n"); + printf(" -l, --list-extensions list all Vulkan and client API extensions\n"); + printf(" --list-layers list all Vulkan layers\n"); printf(" -m, --major=MAJOR the major number of the required " "client API version\n"); printf(" -n, --minor=MINOR the minor number of the required " @@ -96,6 +98,22 @@ static void error_callback(int error, const char* description) fprintf(stderr, "Error: %s\n", description); } +static const char* get_device_type_name(VkPhysicalDeviceType type) +{ + if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER) + return "other"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + return "integrated GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return "discrete GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) + return "virtual GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_CPU) + return "CPU"; + + return "unknown"; +} + static const char* get_api_name(int api) { if (api == GLFW_OPENGL_API) @@ -146,13 +164,13 @@ static const char* get_strategy_name_glfw(int strategy) return "unknown"; } -static void list_extensions(int api, int major, int minor) +static void list_context_extensions(int api, int major, int minor) { int i; GLint count; const GLubyte* extensions; - printf("%s context supported extensions:\n", get_api_name(api)); + printf("%s context extensions:\n", get_api_name(api)); if (api == GLFW_OPENGL_API && major > 2) { @@ -182,6 +200,124 @@ static void list_extensions(int api, int major, int minor) } } +static void list_vulkan_instance_extensions(void) +{ + uint32_t i, ep_count = 0; + VkExtensionProperties* ep; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = + (PFN_vkEnumerateInstanceExtensionProperties) + glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceExtensionProperties"); + + printf("Vulkan instance extensions:\n"); + + if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS) + return; + + ep = calloc(ep_count, sizeof(VkExtensionProperties)); + + if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS) + { + free(ep); + return; + } + + for (i = 0; i < ep_count; i++) + printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); + + free(ep); +} + +static void list_vulkan_instance_layers(void) +{ + uint32_t i, lp_count = 0; + VkLayerProperties* lp; + PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = + (PFN_vkEnumerateInstanceLayerProperties) + glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceLayerProperties"); + + printf("Vulkan instance layers:\n"); + + if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS) + return; + + lp = calloc(lp_count, sizeof(VkLayerProperties)); + + if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS) + { + free(lp); + return; + } + + for (i = 0; i < lp_count; i++) + { + printf(" %s (v%u) \"%s\"\n", + lp[i].layerName, + lp[i].specVersion >> 22, + lp[i].description); + } + + free(lp); +} + +static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device) +{ + uint32_t i, ep_count; + VkExtensionProperties* ep; + PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = + (PFN_vkEnumerateDeviceExtensionProperties) + glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceExtensionProperties"); + + printf("Vulkan device extensions:\n"); + + if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS) + return; + + ep = calloc(ep_count, sizeof(VkExtensionProperties)); + + if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS) + { + free(ep); + return; + } + + for (i = 0; i < ep_count; i++) + printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); + + free(ep); +} + +static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device) +{ + uint32_t i, lp_count; + VkLayerProperties* lp; + PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties = + (PFN_vkEnumerateDeviceLayerProperties) + glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceLayerProperties"); + + printf("Vulkan device layers:\n"); + + if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS) + return; + + lp = calloc(lp_count, sizeof(VkLayerProperties)); + + if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS) + { + free(lp); + return; + } + + for (i = 0; i < lp_count; i++) + { + printf(" %s (v%u) \"%s\"\n", + lp[i].layerName, + lp[i].specVersion >> 22, + lp[i].description); + } + + free(lp); +} + static int valid_version(void) { int major, minor, revision; @@ -216,10 +352,10 @@ int main(int argc, char** argv) { int ch, api, major, minor, revision, profile; GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; - int list = GLFW_FALSE; + int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE; GLFWwindow* window; - enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, + enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS, MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS, @@ -232,6 +368,7 @@ int main(int argc, char** argv) { "forward", 0, NULL, FORWARD }, { "help", 0, NULL, HELP }, { "list-extensions", 0, NULL, EXTENSIONS }, + { "list-layers", 0, NULL, LAYERS }, { "major", 1, NULL, MAJOR }, { "minor", 1, NULL, MINOR }, { "profile", 1, NULL, PROFILE }, @@ -314,7 +451,10 @@ int main(int argc, char** argv) exit(EXIT_SUCCESS); case 'l': case EXTENSIONS: - list = GLFW_TRUE; + list_extensions = GLFW_TRUE; + break; + case LAYERS: + list_layers = GLFW_TRUE; break; case 'm': case MAJOR: @@ -564,7 +704,7 @@ int main(int argc, char** argv) glGetString(GL_SHADING_LANGUAGE_VERSION)); } - printf("Framebuffer:\n"); + printf("%s framebuffer:\n", get_api_name(api)); if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) { @@ -632,9 +772,103 @@ int main(int argc, char** argv) accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); } - // Report client API extensions - if (list) - list_extensions(api, major, minor); + if (list_extensions) + list_context_extensions(api, major, minor); + + printf("Vulkan loader: %s\n", + glfwVulkanSupported() ? "available" : "missing"); + + if (glfwVulkanSupported()) + { + uint32_t i, re_count, pd_count; + const char** re; + VkApplicationInfo ai = {0}; + VkInstanceCreateInfo ici = {0}; + VkInstance instance; + VkPhysicalDevice* pd; + PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance) + glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); + PFN_vkDestroyInstance vkDestroyInstance; + PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; + + re = glfwGetRequiredInstanceExtensions((int*) &re_count); + + printf("Vulkan required instance extensions:"); + for (i = 0; i < re_count; i++) + printf(" %s", re[i]); + putchar('\n'); + + if (list_extensions) + { + list_vulkan_instance_extensions(); + } + + if (list_layers) + list_vulkan_instance_layers(); + + ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + ai.pApplicationName = "glfwinfo"; + ai.applicationVersion = GLFW_VERSION_MAJOR; + ai.pEngineName = "GLFW"; + ai.engineVersion = GLFW_VERSION_MAJOR; + ai.apiVersion = VK_API_VERSION; + + ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + ici.pApplicationInfo = &ai; + ici.enabledExtensionCount = re_count; + ici.ppEnabledExtensionNames = re; + + if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + vkDestroyInstance = (PFN_vkDestroyInstance) + glfwGetInstanceProcAddress(instance, "vkDestroyInstance"); + vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) + glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices"); + vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) + glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties"); + + if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS) + { + vkDestroyInstance(instance, NULL); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + pd = calloc(pd_count, sizeof(VkPhysicalDevice)); + + if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS) + { + free(pd); + vkDestroyInstance(instance, NULL); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + for (i = 0; i < pd_count; i++) + { + VkPhysicalDeviceProperties pdp; + + vkGetPhysicalDeviceProperties(pd[i], &pdp); + + printf("Vulkan %s device: \"%s\"\n", + get_device_type_name(pdp.deviceType), + pdp.deviceName); + + if (list_extensions) + list_vulkan_device_extensions(instance, pd[i]); + + if (list_layers) + list_vulkan_device_layers(instance, pd[i]); + } + + free(pd); + vkDestroyInstance(instance, NULL); + } glfwTerminate(); exit(EXIT_SUCCESS); diff --git a/tests/vulkan.c b/tests/vulkan.c new file mode 100644 index 000000000..ee45b8912 --- /dev/null +++ b/tests/vulkan.c @@ -0,0 +1,2240 @@ +/* + * Copyright (c) 2015-2016 The Khronos Group Inc. + * Copyright (c) 2015-2016 Valve Corporation + * Copyright (c) 2015-2016 LunarG, 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(s) 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. + * + * Author: Chia-I Wu + * Author: Cody Northrop + * Author: Courtney Goeltzenleuchter + * Author: Ian Elliott + * Author: Jon Ashburn + * Author: Piers Daniell + */ +/* + * Draw a textured triangle with depth testing. This is written against Intel + * ICD. It does not do state transition nor object memory binding like it + * should. It also does no error checking. + */ + +#ifndef _MSC_VER +#define _ISOC11_SOURCE /* for aligned_alloc() */ +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#define DEMO_TEXTURE_COUNT 1 +#define VERTEX_BUFFER_BIND_ID 0 +#define APP_SHORT_NAME "vulkan" +#define APP_LONG_NAME "The Vulkan Triangle Demo Program" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#if defined(NDEBUG) && defined(__GNUC__) +#define U_ASSERT_ONLY __attribute__((unused)) +#else +#define U_ASSERT_ONLY +#endif + +#define ERR_EXIT(err_msg, err_class) \ + do { \ + printf(err_msg); \ + fflush(stdout); \ + exit(1); \ + } while (0) + +#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ + { \ + demo->fp##entrypoint = \ + (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \ + if (demo->fp##entrypoint == NULL) { \ + ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, \ + "vkGetInstanceProcAddr Failure"); \ + } \ + } + +#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ + { \ + demo->fp##entrypoint = \ + (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint); \ + if (demo->fp##entrypoint == NULL) { \ + ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint, \ + "vkGetDeviceProcAddr Failure"); \ + } \ + } + +static const char fragShaderCode[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, + 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, + 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, + 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x75, 0x46, 0x72, 0x61, + 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; + +static const char vertShaderCode[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, + 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, + 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, + 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, + 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x56, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x44, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; + +struct texture_object { + VkSampler sampler; + + VkImage image; + VkImageLayout imageLayout; + + VkDeviceMemory mem; + VkImageView view; + int32_t tex_width, tex_height; +}; + +VKAPI_ATTR VkBool32 VKAPI_CALL +dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, + uint64_t srcObject, size_t location, int32_t msgCode, + const char *pLayerPrefix, const char *pMsg, void *pUserData) { + char *message = (char *)malloc(strlen(pMsg) + 100); + + assert(message); + + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, + pMsg); + } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, + pMsg); + } else { + return false; + } + + printf("%s\n", message); + fflush(stdout); + free(message); + + /* + * false indicates that layer should not bail-out of an + * API call that had validation failures. This may mean that the + * app dies inside the driver due to invalid parameter(s). + * That's what would happen without validation layers, so we'll + * keep that behavior here. + */ + return false; +} + +typedef struct _SwapchainBuffers { + VkImage image; + VkCommandBuffer cmd; + VkImageView view; +} SwapchainBuffers; + +struct demo { + GLFWwindow* window; + VkSurfaceKHR surface; + bool use_staging_buffer; + + VkAllocationCallbacks allocator; + + VkInstance inst; + VkPhysicalDevice gpu; + VkDevice device; + VkQueue queue; + VkPhysicalDeviceProperties gpu_props; + VkQueueFamilyProperties *queue_props; + uint32_t graphics_queue_node_index; + + uint32_t enabled_extension_count; + uint32_t enabled_layer_count; + const char *extension_names[64]; + char *device_validation_layers[64]; + + int width, height; + VkFormat format; + VkColorSpaceKHR color_space; + + PFN_vkGetPhysicalDeviceSurfaceSupportKHR + fpGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR + fpGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR + fpGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR + fpGetPhysicalDeviceSurfacePresentModesKHR; + PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR; + PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR; + PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR; + PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR; + PFN_vkQueuePresentKHR fpQueuePresentKHR; + uint32_t swapchainImageCount; + VkSwapchainKHR swapchain; + SwapchainBuffers *buffers; + + VkCommandPool cmd_pool; + + struct { + VkFormat format; + + VkImage image; + VkDeviceMemory mem; + VkImageView view; + } depth; + + struct texture_object textures[DEMO_TEXTURE_COUNT]; + + struct { + VkBuffer buf; + VkDeviceMemory mem; + + VkPipelineVertexInputStateCreateInfo vi; + VkVertexInputBindingDescription vi_bindings[1]; + VkVertexInputAttributeDescription vi_attrs[2]; + } vertices; + + VkCommandBuffer setup_cmd; // Command Buffer for initialization commands + VkCommandBuffer draw_cmd; // Command Buffer for drawing commands + VkPipelineLayout pipeline_layout; + VkDescriptorSetLayout desc_layout; + VkPipelineCache pipelineCache; + VkRenderPass render_pass; + VkPipeline pipeline; + + VkShaderModule vert_shader_module; + VkShaderModule frag_shader_module; + + VkDescriptorPool desc_pool; + VkDescriptorSet desc_set; + + VkFramebuffer *framebuffers; + + VkPhysicalDeviceMemoryProperties memory_properties; + + bool validate; + PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback; + PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback; + VkDebugReportCallbackEXT msg_callback; + + float depthStencil; + float depthIncrement; + + uint32_t current_buffer; + uint32_t queue_count; +}; + +// Forward declaration: +static void demo_resize(struct demo *demo); + +static bool memory_type_from_properties(struct demo *demo, uint32_t typeBits, + VkFlags requirements_mask, + uint32_t *typeIndex) { + uint32_t i; + + // Search memtypes to find first index with those properties + for (i = 0; i < 32; i++) { + if ((typeBits & 1) == 1) { + // Type is available, does it match user properties? + if ((demo->memory_properties.memoryTypes[i].propertyFlags & + requirements_mask) == requirements_mask) { + *typeIndex = i; + return true; + } + } + typeBits >>= 1; + } + // No memory types matched, return failure + return false; +} + +static void demo_flush_init_cmd(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + if (demo->setup_cmd == VK_NULL_HANDLE) + return; + + err = vkEndCommandBuffer(demo->setup_cmd); + assert(!err); + + const VkCommandBuffer cmd_bufs[] = {demo->setup_cmd}; + VkFence nullFence = {VK_NULL_HANDLE}; + VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = NULL, + .waitSemaphoreCount = 0, + .pWaitSemaphores = NULL, + .pWaitDstStageMask = NULL, + .commandBufferCount = 1, + .pCommandBuffers = cmd_bufs, + .signalSemaphoreCount = 0, + .pSignalSemaphores = NULL}; + + err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence); + assert(!err); + + err = vkQueueWaitIdle(demo->queue); + assert(!err); + + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, cmd_bufs); + demo->setup_cmd = VK_NULL_HANDLE; +} + +static void demo_set_image_layout(struct demo *demo, VkImage image, + VkImageAspectFlags aspectMask, + VkImageLayout old_image_layout, + VkImageLayout new_image_layout) { + VkResult U_ASSERT_ONLY err; + + if (demo->setup_cmd == VK_NULL_HANDLE) { + const VkCommandBufferAllocateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = demo->cmd_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + + err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->setup_cmd); + assert(!err); + + VkCommandBufferInheritanceInfo cmd_buf_hinfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + .pNext = NULL, + .renderPass = VK_NULL_HANDLE, + .subpass = 0, + .framebuffer = VK_NULL_HANDLE, + .occlusionQueryEnable = VK_FALSE, + .queryFlags = 0, + .pipelineStatistics = 0, + }; + VkCommandBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = 0, + .pInheritanceInfo = &cmd_buf_hinfo, + }; + err = vkBeginCommandBuffer(demo->setup_cmd, &cmd_buf_info); + assert(!err); + } + + VkImageMemoryBarrier image_memory_barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = 0, + .dstAccessMask = 0, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .image = image, + .subresourceRange = {aspectMask, 0, 1, 0, 1}}; + + if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + /* Make sure anything that was copying from this image has completed */ + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { + image_memory_barrier.dstAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { + image_memory_barrier.dstAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + /* Make sure any Copy or CPU writes to image are flushed */ + image_memory_barrier.dstAccessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + } + + VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier; + + VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + vkCmdPipelineBarrier(demo->setup_cmd, src_stages, dest_stages, 0, 0, NULL, + 0, NULL, 1, pmemory_barrier); +} + +static void demo_draw_build_cmd(struct demo *demo) { + const VkCommandBufferInheritanceInfo cmd_buf_hinfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + .pNext = NULL, + .renderPass = VK_NULL_HANDLE, + .subpass = 0, + .framebuffer = VK_NULL_HANDLE, + .occlusionQueryEnable = VK_FALSE, + .queryFlags = 0, + .pipelineStatistics = 0, + }; + const VkCommandBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = 0, + .pInheritanceInfo = &cmd_buf_hinfo, + }; + const VkClearValue clear_values[2] = { + [0] = {.color.float32 = {0.2f, 0.2f, 0.2f, 0.2f}}, + [1] = {.depthStencil = {demo->depthStencil, 0}}, + }; + const VkRenderPassBeginInfo rp_begin = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = NULL, + .renderPass = demo->render_pass, + .framebuffer = demo->framebuffers[demo->current_buffer], + .renderArea.offset.x = 0, + .renderArea.offset.y = 0, + .renderArea.extent.width = demo->width, + .renderArea.extent.height = demo->height, + .clearValueCount = 2, + .pClearValues = clear_values, + }; + VkResult U_ASSERT_ONLY err; + + err = vkBeginCommandBuffer(demo->draw_cmd, &cmd_buf_info); + assert(!err); + + vkCmdBeginRenderPass(demo->draw_cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + demo->pipeline); + vkCmdBindDescriptorSets(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + demo->pipeline_layout, 0, 1, &demo->desc_set, 0, + NULL); + + VkViewport viewport; + memset(&viewport, 0, sizeof(viewport)); + viewport.height = (float)demo->height; + viewport.width = (float)demo->width; + viewport.minDepth = (float)0.0f; + viewport.maxDepth = (float)1.0f; + vkCmdSetViewport(demo->draw_cmd, 0, 1, &viewport); + + VkRect2D scissor; + memset(&scissor, 0, sizeof(scissor)); + scissor.extent.width = demo->width; + scissor.extent.height = demo->height; + scissor.offset.x = 0; + scissor.offset.y = 0; + vkCmdSetScissor(demo->draw_cmd, 0, 1, &scissor); + + VkDeviceSize offsets[1] = {0}; + vkCmdBindVertexBuffers(demo->draw_cmd, VERTEX_BUFFER_BIND_ID, 1, + &demo->vertices.buf, offsets); + + vkCmdDraw(demo->draw_cmd, 3, 1, 0, 0); + vkCmdEndRenderPass(demo->draw_cmd); + + VkImageMemoryBarrier prePresentBarrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + prePresentBarrier.image = demo->buffers[demo->current_buffer].image; + VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier; + vkCmdPipelineBarrier(demo->draw_cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, + NULL, 1, pmemory_barrier); + + err = vkEndCommandBuffer(demo->draw_cmd); + assert(!err); +} + +static void demo_draw(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + VkSemaphore presentCompleteSemaphore; + VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + }; + + err = vkCreateSemaphore(demo->device, &presentCompleteSemaphoreCreateInfo, + NULL, &presentCompleteSemaphore); + assert(!err); + + // Get the index of the next available swapchain image: + err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX, + presentCompleteSemaphore, + (VkFence)0, // TODO: Show use of fence + &demo->current_buffer); + if (err == VK_ERROR_OUT_OF_DATE_KHR) { + // demo->swapchain is out of date (e.g. the window was resized) and + // must be recreated: + demo_resize(demo); + demo_draw(demo); + vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL); + return; + } else if (err == VK_SUBOPTIMAL_KHR) { + // demo->swapchain is not as optimal as it could be, but the platform's + // presentation engine will still present the image correctly. + } else { + assert(!err); + } + + // Assume the command buffer has been run on current_buffer before so + // we need to set the image layout back to COLOR_ATTACHMENT_OPTIMAL + demo_set_image_layout(demo, demo->buffers[demo->current_buffer].image, + VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + demo_flush_init_cmd(demo); + + // Wait for the present complete semaphore to be signaled to ensure + // that the image won't be rendered to until the presentation + // engine has fully released ownership to the application, and it is + // okay to render to the image. + + // FIXME/TODO: DEAL WITH VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + demo_draw_build_cmd(demo); + VkFence nullFence = VK_NULL_HANDLE; + VkPipelineStageFlags pipe_stage_flags = + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = NULL, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &presentCompleteSemaphore, + .pWaitDstStageMask = &pipe_stage_flags, + .commandBufferCount = 1, + .pCommandBuffers = &demo->draw_cmd, + .signalSemaphoreCount = 0, + .pSignalSemaphores = NULL}; + + err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence); + assert(!err); + + VkPresentInfoKHR present = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = NULL, + .swapchainCount = 1, + .pSwapchains = &demo->swapchain, + .pImageIndices = &demo->current_buffer, + }; + + // TBD/TODO: SHOULD THE "present" PARAMETER BE "const" IN THE HEADER? + err = demo->fpQueuePresentKHR(demo->queue, &present); + if (err == VK_ERROR_OUT_OF_DATE_KHR) { + // demo->swapchain is out of date (e.g. the window was resized) and + // must be recreated: + demo_resize(demo); + } else if (err == VK_SUBOPTIMAL_KHR) { + // demo->swapchain is not as optimal as it could be, but the platform's + // presentation engine will still present the image correctly. + } else { + assert(!err); + } + + err = vkQueueWaitIdle(demo->queue); + assert(err == VK_SUCCESS); + + vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL); +} + +static void demo_prepare_buffers(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + VkSwapchainKHR oldSwapchain = demo->swapchain; + + // Check the surface capabilities and formats + VkSurfaceCapabilitiesKHR surfCapabilities; + err = demo->fpGetPhysicalDeviceSurfaceCapabilitiesKHR( + demo->gpu, demo->surface, &surfCapabilities); + assert(!err); + + uint32_t presentModeCount; + err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR( + demo->gpu, demo->surface, &presentModeCount, NULL); + assert(!err); + VkPresentModeKHR *presentModes = + (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR)); + assert(presentModes); + err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR( + demo->gpu, demo->surface, &presentModeCount, presentModes); + assert(!err); + + VkExtent2D swapchainExtent; + // width and height are either both -1, or both not -1. + if (surfCapabilities.currentExtent.width == (uint32_t)-1) { + // If the surface size is undefined, the size is set to + // the size of the images requested. + swapchainExtent.width = demo->width; + swapchainExtent.height = demo->height; + } else { + // If the surface size is defined, the swap chain size must match + swapchainExtent = surfCapabilities.currentExtent; + demo->width = surfCapabilities.currentExtent.width; + demo->height = surfCapabilities.currentExtent.height; + } + + VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; + + // Determine the number of VkImage's to use in the swap chain (we desire to + // own only 1 image at a time, besides the images being displayed and + // queued for display): + uint32_t desiredNumberOfSwapchainImages = + surfCapabilities.minImageCount + 1; + if ((surfCapabilities.maxImageCount > 0) && + (desiredNumberOfSwapchainImages > surfCapabilities.maxImageCount)) { + // Application must settle for fewer images than desired: + desiredNumberOfSwapchainImages = surfCapabilities.maxImageCount; + } + + VkSurfaceTransformFlagsKHR preTransform; + if (surfCapabilities.supportedTransforms & + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + } else { + preTransform = surfCapabilities.currentTransform; + } + + const VkSwapchainCreateInfoKHR swapchain = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = NULL, + .surface = demo->surface, + .minImageCount = desiredNumberOfSwapchainImages, + .imageFormat = demo->format, + .imageColorSpace = demo->color_space, + .imageExtent = + { + .width = swapchainExtent.width, .height = swapchainExtent.height, + }, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .preTransform = preTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .imageArrayLayers = 1, + .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = NULL, + .presentMode = swapchainPresentMode, + .oldSwapchain = oldSwapchain, + .clipped = true, + }; + uint32_t i; + + err = demo->fpCreateSwapchainKHR(demo->device, &swapchain, NULL, + &demo->swapchain); + assert(!err); + + // If we just re-created an existing swapchain, we should destroy the old + // swapchain at this point. + // Note: destroying the swapchain also cleans up all its associated + // presentable images once the platform is done with them. + if (oldSwapchain != VK_NULL_HANDLE) { + demo->fpDestroySwapchainKHR(demo->device, oldSwapchain, NULL); + } + + err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain, + &demo->swapchainImageCount, NULL); + assert(!err); + + VkImage *swapchainImages = + (VkImage *)malloc(demo->swapchainImageCount * sizeof(VkImage)); + assert(swapchainImages); + err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain, + &demo->swapchainImageCount, + swapchainImages); + assert(!err); + + demo->buffers = (SwapchainBuffers *)malloc(sizeof(SwapchainBuffers) * + demo->swapchainImageCount); + assert(demo->buffers); + + for (i = 0; i < demo->swapchainImageCount; i++) { + VkImageViewCreateInfo color_attachment_view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .format = demo->format, + .components = + { + .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .flags = 0, + }; + + demo->buffers[i].image = swapchainImages[i]; + + // Render loop will expect image to have been used before and in + // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + // layout and will change to COLOR_ATTACHMENT_OPTIMAL, so init the image + // to that state + demo_set_image_layout( + demo, demo->buffers[i].image, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + + color_attachment_view.image = demo->buffers[i].image; + + err = vkCreateImageView(demo->device, &color_attachment_view, NULL, + &demo->buffers[i].view); + assert(!err); + } + + demo->current_buffer = 0; + + if (NULL != presentModes) { + free(presentModes); + } +} + +static void demo_prepare_depth(struct demo *demo) { + const VkFormat depth_format = VK_FORMAT_D16_UNORM; + const VkImageCreateInfo image = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = depth_format, + .extent = {demo->width, demo->height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + VkImageViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .format = depth_format, + .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}, + .flags = 0, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + }; + + VkMemoryRequirements mem_reqs; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + + demo->depth.format = depth_format; + + /* create image */ + err = vkCreateImage(demo->device, &image, NULL, &demo->depth.image); + assert(!err); + + /* get memory requirements for this object */ + vkGetImageMemoryRequirements(demo->device, demo->depth.image, &mem_reqs); + + /* select memory size and type */ + mem_alloc.allocationSize = mem_reqs.size; + pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + 0, /* No requirements */ + &mem_alloc.memoryTypeIndex); + assert(pass); + + /* allocate memory */ + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->depth.mem); + assert(!err); + + /* bind memory */ + err = + vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0); + assert(!err); + + demo_set_image_layout(demo, demo->depth.image, VK_IMAGE_ASPECT_DEPTH_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + /* create image view */ + view.image = demo->depth.image; + err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view); + assert(!err); +} + +static void +demo_prepare_texture_image(struct demo *demo, const uint32_t *tex_colors, + struct texture_object *tex_obj, VkImageTiling tiling, + VkImageUsageFlags usage, VkFlags required_props) { + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + const int32_t tex_width = 2; + const int32_t tex_height = 2; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + + tex_obj->tex_width = tex_width; + tex_obj->tex_height = tex_height; + + const VkImageCreateInfo image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = tex_format, + .extent = {tex_width, tex_height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = tiling, + .usage = usage, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + + VkMemoryRequirements mem_reqs; + + err = + vkCreateImage(demo->device, &image_create_info, NULL, &tex_obj->image); + assert(!err); + + vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs); + + mem_alloc.allocationSize = mem_reqs.size; + pass = + memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + required_props, &mem_alloc.memoryTypeIndex); + assert(pass); + + /* allocate memory */ + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &tex_obj->mem); + assert(!err); + + /* bind memory */ + err = vkBindImageMemory(demo->device, tex_obj->image, tex_obj->mem, 0); + assert(!err); + + if (required_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + const VkImageSubresource subres = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .arrayLayer = 0, + }; + VkSubresourceLayout layout; + void *data; + int32_t x, y; + + vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres, + &layout); + + err = vkMapMemory(demo->device, tex_obj->mem, 0, + mem_alloc.allocationSize, 0, &data); + assert(!err); + + for (y = 0; y < tex_height; y++) { + uint32_t *row = (uint32_t *)((char *)data + layout.rowPitch * y); + for (x = 0; x < tex_width; x++) + row[x] = tex_colors[(x & 1) ^ (y & 1)]; + } + + vkUnmapMemory(demo->device, tex_obj->mem); + } + + tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + demo_set_image_layout(demo, tex_obj->image, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, tex_obj->imageLayout); + /* setting the image layout does not reference the actual memory so no need + * to add a mem ref */ +} + +static void demo_destroy_texture_image(struct demo *demo, + struct texture_object *tex_obj) { + /* clean up staging resources */ + vkDestroyImage(demo->device, tex_obj->image, NULL); + vkFreeMemory(demo->device, tex_obj->mem, NULL); +} + +static void demo_prepare_textures(struct demo *demo) { + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + VkFormatProperties props; + const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = { + {0xffff0000, 0xff00ff00}, + }; + uint32_t i; + VkResult U_ASSERT_ONLY err; + + vkGetPhysicalDeviceFormatProperties(demo->gpu, tex_format, &props); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + if ((props.linearTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && + !demo->use_staging_buffer) { + /* Device can texture using linear textures */ + demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + } else if (props.optimalTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { + /* Must use staging buffer to copy linear texture to optimized */ + struct texture_object staging_texture; + + memset(&staging_texture, 0, sizeof(staging_texture)); + demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + demo_prepare_texture_image( + demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_OPTIMAL, + (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + demo_set_image_layout(demo, staging_texture.image, + VK_IMAGE_ASPECT_COLOR_BIT, + staging_texture.imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + demo_set_image_layout(demo, demo->textures[i].image, + VK_IMAGE_ASPECT_COLOR_BIT, + demo->textures[i].imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkImageCopy copy_region = { + .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + .srcOffset = {0, 0, 0}, + .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + .dstOffset = {0, 0, 0}, + .extent = {staging_texture.tex_width, + staging_texture.tex_height, 1}, + }; + vkCmdCopyImage( + demo->setup_cmd, staging_texture.image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, demo->textures[i].image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); + + demo_set_image_layout(demo, demo->textures[i].image, + VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + demo->textures[i].imageLayout); + + demo_flush_init_cmd(demo); + + demo_destroy_texture_image(demo, &staging_texture); + } else { + /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */ + assert(!"No support for B8G8R8A8_UNORM as texture image format"); + } + + const VkSamplerCreateInfo sampler = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = NULL, + .magFilter = VK_FILTER_NEAREST, + .minFilter = VK_FILTER_NEAREST, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .mipLodBias = 0.0f, + .anisotropyEnable = VK_FALSE, + .maxAnisotropy = 1, + .compareOp = VK_COMPARE_OP_NEVER, + .minLod = 0.0f, + .maxLod = 0.0f, + .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + .unnormalizedCoordinates = VK_FALSE, + }; + VkImageViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = tex_format, + .components = + { + VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + .flags = 0, + }; + + /* create sampler */ + err = vkCreateSampler(demo->device, &sampler, NULL, + &demo->textures[i].sampler); + assert(!err); + + /* create image view */ + view.image = demo->textures[i].image; + err = vkCreateImageView(demo->device, &view, NULL, + &demo->textures[i].view); + assert(!err); + } +} + +static void demo_prepare_vertices(struct demo *demo) { + // clang-format off + const float vb[3][5] = { + /* position texcoord */ + { -1.0f, -1.0f, 0.25f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.25f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f }, + }; + // clang-format on + const VkBufferCreateInfo buf_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = NULL, + .size = sizeof(vb), + .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + VkMemoryRequirements mem_reqs; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + void *data; + + memset(&demo->vertices, 0, sizeof(demo->vertices)); + + err = vkCreateBuffer(demo->device, &buf_info, NULL, &demo->vertices.buf); + assert(!err); + + vkGetBufferMemoryRequirements(demo->device, demo->vertices.buf, &mem_reqs); + assert(!err); + + mem_alloc.allocationSize = mem_reqs.size; + pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &mem_alloc.memoryTypeIndex); + assert(pass); + + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->vertices.mem); + assert(!err); + + err = vkMapMemory(demo->device, demo->vertices.mem, 0, + mem_alloc.allocationSize, 0, &data); + assert(!err); + + memcpy(data, vb, sizeof(vb)); + + vkUnmapMemory(demo->device, demo->vertices.mem); + + err = vkBindBufferMemory(demo->device, demo->vertices.buf, + demo->vertices.mem, 0); + assert(!err); + + demo->vertices.vi.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + demo->vertices.vi.pNext = NULL; + demo->vertices.vi.vertexBindingDescriptionCount = 1; + demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; + demo->vertices.vi.vertexAttributeDescriptionCount = 2; + demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs; + + demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_bindings[0].stride = sizeof(vb[0]); + demo->vertices.vi_bindings[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[0].location = 0; + demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT; + demo->vertices.vi_attrs[0].offset = 0; + + demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[1].location = 1; + demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT; + demo->vertices.vi_attrs[1].offset = sizeof(float) * 3; +} + +static void demo_prepare_descriptor_layout(struct demo *demo) { + const VkDescriptorSetLayoutBinding layout_binding = { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = DEMO_TEXTURE_COUNT, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL, + }; + const VkDescriptorSetLayoutCreateInfo descriptor_layout = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = NULL, + .bindingCount = 1, + .pBindings = &layout_binding, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateDescriptorSetLayout(demo->device, &descriptor_layout, NULL, + &demo->desc_layout); + assert(!err); + + const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = NULL, + .setLayoutCount = 1, + .pSetLayouts = &demo->desc_layout, + }; + + err = vkCreatePipelineLayout(demo->device, &pPipelineLayoutCreateInfo, NULL, + &demo->pipeline_layout); + assert(!err); +} + +static void demo_prepare_render_pass(struct demo *demo) { + const VkAttachmentDescription attachments[2] = { + [0] = + { + .format = demo->format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }, + [1] = + { + .format = demo->depth.format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }, + }; + const VkAttachmentReference color_reference = { + .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + const VkAttachmentReference depth_reference = { + .attachment = 1, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }; + const VkSubpassDescription subpass = { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .flags = 0, + .inputAttachmentCount = 0, + .pInputAttachments = NULL, + .colorAttachmentCount = 1, + .pColorAttachments = &color_reference, + .pResolveAttachments = NULL, + .pDepthStencilAttachment = &depth_reference, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, + }; + const VkRenderPassCreateInfo rp_info = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .pNext = NULL, + .attachmentCount = 2, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpass, + .dependencyCount = 0, + .pDependencies = NULL, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateRenderPass(demo->device, &rp_info, NULL, &demo->render_pass); + assert(!err); +} + +static VkShaderModule +demo_prepare_shader_module(struct demo *demo, const void *code, size_t size) { + VkShaderModuleCreateInfo moduleCreateInfo; + VkShaderModule module; + VkResult U_ASSERT_ONLY err; + + moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleCreateInfo.pNext = NULL; + + moduleCreateInfo.codeSize = size; + moduleCreateInfo.pCode = code; + moduleCreateInfo.flags = 0; + err = vkCreateShaderModule(demo->device, &moduleCreateInfo, NULL, &module); + assert(!err); + + return module; +} + +static VkShaderModule demo_prepare_vs(struct demo *demo) { + size_t size = sizeof(vertShaderCode); + + demo->vert_shader_module = + demo_prepare_shader_module(demo, vertShaderCode, size); + + return demo->vert_shader_module; +} + +static VkShaderModule demo_prepare_fs(struct demo *demo) { + size_t size = sizeof(fragShaderCode); + + demo->frag_shader_module = + demo_prepare_shader_module(demo, fragShaderCode, size); + + return demo->frag_shader_module; +} + +static void demo_prepare_pipeline(struct demo *demo) { + VkGraphicsPipelineCreateInfo pipeline; + VkPipelineCacheCreateInfo pipelineCache; + + VkPipelineVertexInputStateCreateInfo vi; + VkPipelineInputAssemblyStateCreateInfo ia; + VkPipelineRasterizationStateCreateInfo rs; + VkPipelineColorBlendStateCreateInfo cb; + VkPipelineDepthStencilStateCreateInfo ds; + VkPipelineViewportStateCreateInfo vp; + VkPipelineMultisampleStateCreateInfo ms; + VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; + VkPipelineDynamicStateCreateInfo dynamicState; + + VkResult U_ASSERT_ONLY err; + + memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); + memset(&dynamicState, 0, sizeof dynamicState); + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.pDynamicStates = dynamicStateEnables; + + memset(&pipeline, 0, sizeof(pipeline)); + pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline.layout = demo->pipeline_layout; + + vi = demo->vertices.vi; + + memset(&ia, 0, sizeof(ia)); + ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + memset(&rs, 0, sizeof(rs)); + rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rs.polygonMode = VK_POLYGON_MODE_FILL; + rs.cullMode = VK_CULL_MODE_BACK_BIT; + rs.frontFace = VK_FRONT_FACE_CLOCKWISE; + rs.depthClampEnable = VK_FALSE; + rs.rasterizerDiscardEnable = VK_FALSE; + rs.depthBiasEnable = VK_FALSE; + + memset(&cb, 0, sizeof(cb)); + cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + VkPipelineColorBlendAttachmentState att_state[1]; + memset(att_state, 0, sizeof(att_state)); + att_state[0].colorWriteMask = 0xf; + att_state[0].blendEnable = VK_FALSE; + cb.attachmentCount = 1; + cb.pAttachments = att_state; + + memset(&vp, 0, sizeof(vp)); + vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + vp.viewportCount = 1; + dynamicStateEnables[dynamicState.dynamicStateCount++] = + VK_DYNAMIC_STATE_VIEWPORT; + vp.scissorCount = 1; + dynamicStateEnables[dynamicState.dynamicStateCount++] = + VK_DYNAMIC_STATE_SCISSOR; + + memset(&ds, 0, sizeof(ds)); + ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + ds.depthTestEnable = VK_TRUE; + ds.depthWriteEnable = VK_TRUE; + ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + ds.depthBoundsTestEnable = VK_FALSE; + ds.back.failOp = VK_STENCIL_OP_KEEP; + ds.back.passOp = VK_STENCIL_OP_KEEP; + ds.back.compareOp = VK_COMPARE_OP_ALWAYS; + ds.stencilTestEnable = VK_FALSE; + ds.front = ds.back; + + memset(&ms, 0, sizeof(ms)); + ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms.pSampleMask = NULL; + ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + // Two stages: vs and fs + pipeline.stageCount = 2; + VkPipelineShaderStageCreateInfo shaderStages[2]; + memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); + + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shaderStages[0].module = demo_prepare_vs(demo); + shaderStages[0].pName = "main"; + + shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shaderStages[1].module = demo_prepare_fs(demo); + shaderStages[1].pName = "main"; + + pipeline.pVertexInputState = &vi; + pipeline.pInputAssemblyState = &ia; + pipeline.pRasterizationState = &rs; + pipeline.pColorBlendState = &cb; + pipeline.pMultisampleState = &ms; + pipeline.pViewportState = &vp; + pipeline.pDepthStencilState = &ds; + pipeline.pStages = shaderStages; + pipeline.renderPass = demo->render_pass; + pipeline.pDynamicState = &dynamicState; + + memset(&pipelineCache, 0, sizeof(pipelineCache)); + pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + + err = vkCreatePipelineCache(demo->device, &pipelineCache, NULL, + &demo->pipelineCache); + assert(!err); + err = vkCreateGraphicsPipelines(demo->device, demo->pipelineCache, 1, + &pipeline, NULL, &demo->pipeline); + assert(!err); + + vkDestroyPipelineCache(demo->device, demo->pipelineCache, NULL); + + vkDestroyShaderModule(demo->device, demo->frag_shader_module, NULL); + vkDestroyShaderModule(demo->device, demo->vert_shader_module, NULL); +} + +static void demo_prepare_descriptor_pool(struct demo *demo) { + const VkDescriptorPoolSize type_count = { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = DEMO_TEXTURE_COUNT, + }; + const VkDescriptorPoolCreateInfo descriptor_pool = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = NULL, + .maxSets = 1, + .poolSizeCount = 1, + .pPoolSizes = &type_count, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateDescriptorPool(demo->device, &descriptor_pool, NULL, + &demo->desc_pool); + assert(!err); +} + +static void demo_prepare_descriptor_set(struct demo *demo) { + VkDescriptorImageInfo tex_descs[DEMO_TEXTURE_COUNT]; + VkWriteDescriptorSet write; + VkResult U_ASSERT_ONLY err; + uint32_t i; + + VkDescriptorSetAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = NULL, + .descriptorPool = demo->desc_pool, + .descriptorSetCount = 1, + .pSetLayouts = &demo->desc_layout}; + err = vkAllocateDescriptorSets(demo->device, &alloc_info, &demo->desc_set); + assert(!err); + + memset(&tex_descs, 0, sizeof(tex_descs)); + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + tex_descs[i].sampler = demo->textures[i].sampler; + tex_descs[i].imageView = demo->textures[i].view; + tex_descs[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + } + + memset(&write, 0, sizeof(write)); + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstSet = demo->desc_set; + write.descriptorCount = DEMO_TEXTURE_COUNT; + write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write.pImageInfo = tex_descs; + + vkUpdateDescriptorSets(demo->device, 1, &write, 0, NULL); +} + +static void demo_prepare_framebuffers(struct demo *demo) { + VkImageView attachments[2]; + attachments[1] = demo->depth.view; + + const VkFramebufferCreateInfo fb_info = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = NULL, + .renderPass = demo->render_pass, + .attachmentCount = 2, + .pAttachments = attachments, + .width = demo->width, + .height = demo->height, + .layers = 1, + }; + VkResult U_ASSERT_ONLY err; + uint32_t i; + + demo->framebuffers = (VkFramebuffer *)malloc(demo->swapchainImageCount * + sizeof(VkFramebuffer)); + assert(demo->framebuffers); + + for (i = 0; i < demo->swapchainImageCount; i++) { + attachments[0] = demo->buffers[i].view; + err = vkCreateFramebuffer(demo->device, &fb_info, NULL, + &demo->framebuffers[i]); + assert(!err); + } +} + +static void demo_prepare(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + const VkCommandPoolCreateInfo cmd_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = NULL, + .queueFamilyIndex = demo->graphics_queue_node_index, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + }; + err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL, + &demo->cmd_pool); + assert(!err); + + const VkCommandBufferAllocateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = demo->cmd_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->draw_cmd); + assert(!err); + + demo_prepare_buffers(demo); + demo_prepare_depth(demo); + demo_prepare_textures(demo); + demo_prepare_vertices(demo); + demo_prepare_descriptor_layout(demo); + demo_prepare_render_pass(demo); + demo_prepare_pipeline(demo); + + demo_prepare_descriptor_pool(demo); + demo_prepare_descriptor_set(demo); + + demo_prepare_framebuffers(demo); +} + +static void demo_error_callback(int error, const char* description) { + printf("GLFW error: %s\n", description); + fflush(stdout); +} + +static void demo_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static void demo_refresh_callback(GLFWwindow* window) { + struct demo* demo = glfwGetWindowUserPointer(window); + demo_draw(demo); +} + +static void demo_resize_callback(GLFWwindow* window, int width, int height) { + struct demo* demo = glfwGetWindowUserPointer(window); + demo->width = width; + demo->height = height; + demo_resize(demo); +} + +static void demo_run(struct demo *demo) { + while (!glfwWindowShouldClose(demo->window)) { + glfwPollEvents(); + + demo_draw(demo); + + if (demo->depthStencil > 0.99f) + demo->depthIncrement = -0.001f; + if (demo->depthStencil < 0.8f) + demo->depthIncrement = 0.001f; + + demo->depthStencil += demo->depthIncrement; + + // Wait for work to finish before updating MVP. + vkDeviceWaitIdle(demo->device); + } +} + +static void demo_create_window(struct demo *demo) { + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + demo->window = glfwCreateWindow(demo->width, + demo->height, + APP_LONG_NAME, + NULL, + NULL); + if (!demo->window) { + // It didn't work, so try to give a useful error: + printf("Cannot create a window in which to draw!\n"); + fflush(stdout); + exit(1); + } + + glfwSetWindowUserPointer(demo->window, demo); + glfwSetWindowRefreshCallback(demo->window, demo_refresh_callback); + glfwSetFramebufferSizeCallback(demo->window, demo_resize_callback); + glfwSetKeyCallback(demo->window, demo_key_callback); +} + +/* + * Return 1 (true) if all layer names specified in check_names + * can be found in given layer properties. + */ +static VkBool32 demo_check_layers(uint32_t check_count, char **check_names, + uint32_t layer_count, + VkLayerProperties *layers) { + uint32_t i, j; + for (i = 0; i < check_count; i++) { + VkBool32 found = 0; + for (j = 0; j < layer_count; j++) { + if (!strcmp(check_names[i], layers[j].layerName)) { + found = 1; + break; + } + } + if (!found) { + fprintf(stderr, "Cannot find layer: %s\n", check_names[i]); + return 0; + } + } + return 1; +} + +VKAPI_ATTR void *VKAPI_CALL myrealloc(void *pUserData, void *pOriginal, + size_t size, size_t alignment, + VkSystemAllocationScope allocationScope) { + return realloc(pOriginal, size); +} + +VKAPI_ATTR void *VKAPI_CALL myalloc(void *pUserData, size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope) { +#ifdef _MSC_VER + return _aligned_malloc(size, alignment); +#else + return aligned_alloc(alignment, size); +#endif +} + +VKAPI_ATTR void VKAPI_CALL myfree(void *pUserData, void *pMemory) { +#ifdef _MSC_VER + _aligned_free(pMemory); +#else + free(pMemory); +#endif +} + +static void demo_init_vk(struct demo *demo) { + VkResult err; + uint32_t required_extension_count; + const char** required_extensions; + uint32_t i; + uint32_t instance_extension_count = 0; + uint32_t instance_layer_count = 0; + uint32_t device_validation_layer_count = 0; + demo->enabled_extension_count = 0; + demo->enabled_layer_count = 0; + + char *instance_validation_layers[] = { + "VK_LAYER_LUNARG_mem_tracker", + "VK_LAYER_GOOGLE_unique_objects", + }; + + demo->device_validation_layers[0] = "VK_LAYER_LUNARG_mem_tracker"; + demo->device_validation_layers[1] = "VK_LAYER_GOOGLE_unique_objects"; + device_validation_layer_count = 2; + + /* Look for validation layers */ + VkBool32 validation_found = 0; + err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL); + assert(!err); + + if (instance_layer_count > 0) { + VkLayerProperties *instance_layers = + malloc(sizeof(VkLayerProperties) * instance_layer_count); + err = vkEnumerateInstanceLayerProperties(&instance_layer_count, + instance_layers); + assert(!err); + + if (demo->validate) { + validation_found = demo_check_layers( + ARRAY_SIZE(instance_validation_layers), + instance_validation_layers, instance_layer_count, + instance_layers); + demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers); + } + + free(instance_layers); + } + + if (demo->validate && !validation_found) { + ERR_EXIT("vkEnumerateInstanceLayerProperties failed to find" + "required validation layer.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + /* Look for instance extensions */ + required_extensions = glfwGetRequiredInstanceExtensions((int*) &required_extension_count); + if (!required_extensions) { + ERR_EXIT("glfwGetRequiredInstanceExtensions failed to find the " + "platform surface extensions.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + for (i = 0; i < required_extension_count; i++) { + demo->extension_names[demo->enabled_extension_count++] = required_extensions[i]; + assert(demo->enabled_extension_count < 64); + } + + err = vkEnumerateInstanceExtensionProperties( + NULL, &instance_extension_count, NULL); + assert(!err); + + if (instance_extension_count > 0) { + VkExtensionProperties *instance_extensions = + malloc(sizeof(VkExtensionProperties) * instance_extension_count); + err = vkEnumerateInstanceExtensionProperties( + NULL, &instance_extension_count, instance_extensions); + assert(!err); + for (i = 0; i < instance_extension_count; i++) { + if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, + instance_extensions[i].extensionName)) { + if (demo->validate) { + demo->extension_names[demo->enabled_extension_count++] = + VK_EXT_DEBUG_REPORT_EXTENSION_NAME; + } + } + assert(demo->enabled_extension_count < 64); + } + + free(instance_extensions); + } + + const VkApplicationInfo app = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = NULL, + .pApplicationName = APP_SHORT_NAME, + .applicationVersion = 0, + .pEngineName = APP_SHORT_NAME, + .engineVersion = 0, + .apiVersion = VK_API_VERSION, + }; + VkInstanceCreateInfo inst_info = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = NULL, + .pApplicationInfo = &app, + .enabledLayerCount = demo->enabled_layer_count, + .ppEnabledLayerNames = (const char *const *)instance_validation_layers, + .enabledExtensionCount = demo->enabled_extension_count, + .ppEnabledExtensionNames = (const char *const *)demo->extension_names, + }; + + uint32_t gpu_count; + + demo->allocator.pfnAllocation = myalloc; + demo->allocator.pfnFree = myfree; + demo->allocator.pfnReallocation = myrealloc; + + err = vkCreateInstance(&inst_info, &demo->allocator, &demo->inst); + if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { + ERR_EXIT("Cannot find a compatible Vulkan installable client driver " + "(ICD).\n\nPlease look at the Getting Started guide for " + "additional information.\n", + "vkCreateInstance Failure"); + } else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) { + ERR_EXIT("Cannot find a specified extension library" + ".\nMake sure your layers path is set appropriately\n", + "vkCreateInstance Failure"); + } else if (err) { + ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan " + "installable client driver (ICD) installed?\nPlease look at " + "the Getting Started guide for additional information.\n", + "vkCreateInstance Failure"); + } + + /* Make initial call to query gpu_count, then second call for gpu info*/ + err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); + assert(!err && gpu_count > 0); + + if (gpu_count > 0) { + VkPhysicalDevice *physical_devices = + malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, + physical_devices); + assert(!err); + /* For tri demo we just grab the first physical device */ + demo->gpu = physical_devices[0]; + free(physical_devices); + } else { + ERR_EXIT("vkEnumeratePhysicalDevices reported zero accessible devices." + "\n\nDo you have a compatible Vulkan installable client" + " driver (ICD) installed?\nPlease look at the Getting Started" + " guide for additional information.\n", + "vkEnumeratePhysicalDevices Failure"); + } + + /* Look for validation layers */ + validation_found = 0; + demo->enabled_layer_count = 0; + uint32_t device_layer_count = 0; + err = + vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, NULL); + assert(!err); + + if (device_layer_count > 0) { + VkLayerProperties *device_layers = + malloc(sizeof(VkLayerProperties) * device_layer_count); + err = vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, + device_layers); + assert(!err); + + if (demo->validate) { + validation_found = demo_check_layers(device_validation_layer_count, + demo->device_validation_layers, + device_layer_count, + device_layers); + demo->enabled_layer_count = device_validation_layer_count; + } + + free(device_layers); + } + + if (demo->validate && !validation_found) { + ERR_EXIT("vkEnumerateDeviceLayerProperties failed to find " + "a required validation layer.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateDevice Failure"); + } + + /* Look for device extensions */ + uint32_t device_extension_count = 0; + VkBool32 swapchainExtFound = 0; + demo->enabled_extension_count = 0; + + err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL, + &device_extension_count, NULL); + assert(!err); + + if (device_extension_count > 0) { + VkExtensionProperties *device_extensions = + malloc(sizeof(VkExtensionProperties) * device_extension_count); + err = vkEnumerateDeviceExtensionProperties( + demo->gpu, NULL, &device_extension_count, device_extensions); + assert(!err); + + for (i = 0; i < device_extension_count; i++) { + if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, + device_extensions[i].extensionName)) { + swapchainExtFound = 1; + demo->extension_names[demo->enabled_extension_count++] = + VK_KHR_SWAPCHAIN_EXTENSION_NAME; + } + assert(demo->enabled_extension_count < 64); + } + + free(device_extensions); + } + + if (!swapchainExtFound) { + ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find " + "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME + " extension.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + if (demo->validate) { + demo->CreateDebugReportCallback = + (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr( + demo->inst, "vkCreateDebugReportCallbackEXT"); + if (!demo->CreateDebugReportCallback) { + ERR_EXIT( + "GetProcAddr: Unable to find vkCreateDebugReportCallbackEXT\n", + "vkGetProcAddr Failure"); + } + VkDebugReportCallbackCreateInfoEXT dbgCreateInfo; + dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + dbgCreateInfo.flags = + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + dbgCreateInfo.pfnCallback = dbgFunc; + dbgCreateInfo.pUserData = NULL; + dbgCreateInfo.pNext = NULL; + err = demo->CreateDebugReportCallback(demo->inst, &dbgCreateInfo, NULL, + &demo->msg_callback); + switch (err) { + case VK_SUCCESS: + break; + case VK_ERROR_OUT_OF_HOST_MEMORY: + ERR_EXIT("CreateDebugReportCallback: out of host memory\n", + "CreateDebugReportCallback Failure"); + break; + default: + ERR_EXIT("CreateDebugReportCallback: unknown failure\n", + "CreateDebugReportCallback Failure"); + break; + } + } + + // Having these GIPA queries of device extension entry points both + // BEFORE and AFTER vkCreateDevice is a good test for the loader + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceCapabilitiesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceFormatsKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfacePresentModesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceSupportKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, CreateSwapchainKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, DestroySwapchainKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetSwapchainImagesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, AcquireNextImageKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, QueuePresentKHR); + + vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props); + + // Query with NULL data to get count + vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count, + NULL); + + demo->queue_props = (VkQueueFamilyProperties *)malloc( + demo->queue_count * sizeof(VkQueueFamilyProperties)); + vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count, + demo->queue_props); + assert(demo->queue_count >= 1); + + // Graphics queue and MemMgr queue can be separate. + // TODO: Add support for separate queues, including synchronization, + // and appropriate tracking for QueueSubmit +} + +static void demo_init_device(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + float queue_priorities[1] = {0.0}; + const VkDeviceQueueCreateInfo queue = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .pNext = NULL, + .queueFamilyIndex = demo->graphics_queue_node_index, + .queueCount = 1, + .pQueuePriorities = queue_priorities}; + + VkDeviceCreateInfo device = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = NULL, + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &queue, + .enabledLayerCount = demo->enabled_layer_count, + .ppEnabledLayerNames = + (const char *const *)((demo->validate) + ? demo->device_validation_layers + : NULL), + .enabledExtensionCount = demo->enabled_extension_count, + .ppEnabledExtensionNames = (const char *const *)demo->extension_names, + }; + + err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device); + assert(!err); +} + +static void demo_init_vk_swapchain(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + uint32_t i; + + // Create a WSI surface for the window: + glfwCreateWindowSurface(demo->inst, demo->window, NULL, &demo->surface); + + // Iterate over each queue to learn whether it supports presenting: + VkBool32 *supportsPresent = + (VkBool32 *)malloc(demo->queue_count * sizeof(VkBool32)); + for (i = 0; i < demo->queue_count; i++) { + demo->fpGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface, + &supportsPresent[i]); + } + + // Search for a graphics and a present queue in the array of queue + // families, try to find one that supports both + uint32_t graphicsQueueNodeIndex = UINT32_MAX; + uint32_t presentQueueNodeIndex = UINT32_MAX; + for (i = 0; i < demo->queue_count; i++) { + if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) { + if (graphicsQueueNodeIndex == UINT32_MAX) { + graphicsQueueNodeIndex = i; + } + + if (supportsPresent[i] == VK_TRUE) { + graphicsQueueNodeIndex = i; + presentQueueNodeIndex = i; + break; + } + } + } + if (presentQueueNodeIndex == UINT32_MAX) { + // If didn't find a queue that supports both graphics and present, then + // find a separate present queue. + for (i = 0; i < demo->queue_count; ++i) { + if (supportsPresent[i] == VK_TRUE) { + presentQueueNodeIndex = i; + break; + } + } + } + free(supportsPresent); + + // Generate error if could not find both a graphics and a present queue + if (graphicsQueueNodeIndex == UINT32_MAX || + presentQueueNodeIndex == UINT32_MAX) { + ERR_EXIT("Could not find a graphics and a present queue\n", + "Swapchain Initialization Failure"); + } + + // TODO: Add support for separate queues, including presentation, + // synchronization, and appropriate tracking for QueueSubmit. + // NOTE: While it is possible for an application to use a separate graphics + // and a present queues, this demo program assumes it is only using + // one: + if (graphicsQueueNodeIndex != presentQueueNodeIndex) { + ERR_EXIT("Could not find a common graphics and a present queue\n", + "Swapchain Initialization Failure"); + } + + demo->graphics_queue_node_index = graphicsQueueNodeIndex; + + demo_init_device(demo); + + vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, 0, + &demo->queue); + + // Get the list of VkFormat's that are supported: + uint32_t formatCount; + err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, + &formatCount, NULL); + assert(!err); + VkSurfaceFormatKHR *surfFormats = + (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); + err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, + &formatCount, surfFormats); + assert(!err); + // If the format list includes just one entry of VK_FORMAT_UNDEFINED, + // the surface has no preferred format. Otherwise, at least one + // supported format will be returned. + if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) { + demo->format = VK_FORMAT_B8G8R8A8_UNORM; + } else { + assert(formatCount >= 1); + demo->format = surfFormats[0].format; + } + demo->color_space = surfFormats[0].colorSpace; + + // Get Memory information and properties + vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); +} + +static void demo_init_connection(struct demo *demo) { + glfwSetErrorCallback(demo_error_callback); + + if (!glfwInit()) { + printf("Cannot initialize GLFW.\nExiting ...\n"); + fflush(stdout); + exit(1); + } + + if (!glfwVulkanSupported()) { + printf("Cannot find a compatible Vulkan installable client driver " + "(ICD).\nExiting ...\n"); + fflush(stdout); + exit(1); + } +} + +static void demo_init(struct demo *demo, const int argc, const char *argv[]) +{ + int i; + + memset(demo, 0, sizeof(*demo)); + + for (i = 0; i < argc; i++) { + if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0) + demo->use_staging_buffer = true; + } + + demo_init_connection(demo); + demo_init_vk(demo); + + demo->width = 300; + demo->height = 300; + demo->depthStencil = 1.0; + demo->depthIncrement = -0.01f; +} + +static void demo_cleanup(struct demo *demo) { + uint32_t i; + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL); + } + free(demo->framebuffers); + vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL); + + if (demo->setup_cmd) { + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd); + } + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd); + vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL); + + vkDestroyPipeline(demo->device, demo->pipeline, NULL); + vkDestroyRenderPass(demo->device, demo->render_pass, NULL); + vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL); + + vkDestroyBuffer(demo->device, demo->vertices.buf, NULL); + vkFreeMemory(demo->device, demo->vertices.mem, NULL); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + vkDestroyImageView(demo->device, demo->textures[i].view, NULL); + vkDestroyImage(demo->device, demo->textures[i].image, NULL); + vkFreeMemory(demo->device, demo->textures[i].mem, NULL); + vkDestroySampler(demo->device, demo->textures[i].sampler, NULL); + } + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyImageView(demo->device, demo->buffers[i].view, NULL); + } + + vkDestroyImageView(demo->device, demo->depth.view, NULL); + vkDestroyImage(demo->device, demo->depth.image, NULL); + vkFreeMemory(demo->device, demo->depth.mem, NULL); + + demo->fpDestroySwapchainKHR(demo->device, demo->swapchain, NULL); + free(demo->buffers); + + vkDestroyDevice(demo->device, NULL); + vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); + vkDestroyInstance(demo->inst, &demo->allocator); + + free(demo->queue_props); + + glfwDestroyWindow(demo->window); + glfwTerminate(); +} + +static void demo_resize(struct demo *demo) { + uint32_t i; + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL); + } + free(demo->framebuffers); + vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL); + + if (demo->setup_cmd) { + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd); + } + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd); + vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL); + + vkDestroyPipeline(demo->device, demo->pipeline, NULL); + vkDestroyRenderPass(demo->device, demo->render_pass, NULL); + vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL); + + vkDestroyBuffer(demo->device, demo->vertices.buf, NULL); + vkFreeMemory(demo->device, demo->vertices.mem, NULL); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + vkDestroyImageView(demo->device, demo->textures[i].view, NULL); + vkDestroyImage(demo->device, demo->textures[i].image, NULL); + vkFreeMemory(demo->device, demo->textures[i].mem, NULL); + vkDestroySampler(demo->device, demo->textures[i].sampler, NULL); + } + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyImageView(demo->device, demo->buffers[i].view, NULL); + } + + vkDestroyImageView(demo->device, demo->depth.view, NULL); + vkDestroyImage(demo->device, demo->depth.image, NULL); + vkFreeMemory(demo->device, demo->depth.mem, NULL); + + free(demo->buffers); + + // Second, re-perform the demo_prepare() function, which will re-create the + // swapchain: + demo_prepare(demo); +} + +int main(const int argc, const char *argv[]) { + struct demo demo; + + demo_init(&demo, argc, argv); + demo_create_window(&demo); + demo_init_vk_swapchain(&demo); + + demo_prepare(&demo); + demo_run(&demo); + + demo_cleanup(&demo); + + return 0; +} + From 440466524ea6585b0f84cc42ddb38f202a142389 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 16 Feb 2016 15:48:29 +0100 Subject: [PATCH 42/42] Add use of GET_DEVICE_PROC_ADDR in Vulkan test --- tests/vulkan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/vulkan.c b/tests/vulkan.c index ee45b8912..21dd0137a 100644 --- a/tests/vulkan.c +++ b/tests/vulkan.c @@ -1995,6 +1995,12 @@ static void demo_init_device(struct demo *demo) { err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device); assert(!err); + + GET_DEVICE_PROC_ADDR(demo->device, CreateSwapchainKHR); + GET_DEVICE_PROC_ADDR(demo->device, DestroySwapchainKHR); + GET_DEVICE_PROC_ADDR(demo->device, GetSwapchainImagesKHR); + GET_DEVICE_PROC_ADDR(demo->device, AcquireNextImageKHR); + GET_DEVICE_PROC_ADDR(demo->device, QueuePresentKHR); } static void demo_init_vk_swapchain(struct demo *demo) {