From 62af66f14a57bfb73c387f7c618aac0fad2bb695 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 18 Mar 2026 11:13:33 -0400 Subject: [PATCH 001/407] x11: More XInput2 #define cleanups Fixes building on very old XInput2 versions (pre-2012) without smooth scrolling and multitouch. --- src/video/x11/SDL_x11xinput2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 5cf75901f2..69b7e21546 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -34,11 +34,11 @@ #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 static bool xinput2_initialized; +static bool xinput2_grabbed_touch_raised; +static int xinput2_active_touch_count; #if defined(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_SCROLLINFO) || defined(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH) static bool xinput2_scrolling_supported; static bool xinput2_multitouch_supported; -static bool xinput2_grabbed_touch_raised; -static int xinput2_active_touch_count; #endif #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_GESTURE static bool xinput2_gesture_supported; @@ -951,6 +951,7 @@ static bool HasDeviceID(Uint32 deviceID, const Uint32 *list, int count) return false; } +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH static void AddDeviceID64(Uint64 deviceID, Uint64 **list, int *count) { int new_count = (*count + 1); @@ -964,6 +965,7 @@ static void AddDeviceID64(Uint64 deviceID, Uint64 **list, int *count) *count = new_count; *list = new_list; } +#endif static bool HasDeviceID64(Uint64 deviceID, const Uint64 *list, int count) { From ff543723c4a09235eac7d30ebda21bde4beda8ca Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev Date: Mon, 16 Mar 2026 02:19:59 +0100 Subject: [PATCH 002/407] Fix SDL_HINT_OPENGL_ES_DRIVER interaction with SDL_HINT_OPENGL_LIBRARY for x11 and windows If SDL_HINT_OPENGL_ES_DRIVER is enabled and a GLES context is requested, don't try to load the WGL/GLX library. Doing so may fail, because SDL_HINT_OPENGL_LIBRARY may have been set to a custom libGLESv2 (e.g. ANGLE). This effectively restores the SDL2 behavior. Other video drivers shouldn't be affected, because they always use EGL for GLES. Incidentally, this patch also fixes a missing GL_GetEGLSurface callback in the X11 fallback path. --- src/video/windows/SDL_windowsopengl.c | 38 +++++++++++++++++-------- src/video/x11/SDL_x11opengl.c | 41 +++++++++++++++++---------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index 5e3b79c196..b87f90e6b4 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -106,10 +106,35 @@ typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC, #define SetPixelFormat _this->gl_data->wglSetPixelFormat #endif +static bool WIN_GL_LoadLibrary_EGLFallback(SDL_VideoDevice *_this, const char *path) +{ +#ifdef SDL_VIDEO_OPENGL_EGL + WIN_GL_UnloadLibrary(_this); + _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; + _this->GL_GetProcAddress = WIN_GLES_GetProcAddress; + _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; + _this->GL_CreateContext = WIN_GLES_CreateContext; + _this->GL_MakeCurrent = WIN_GLES_MakeCurrent; + _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; + _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; + _this->GL_SwapWindow = WIN_GLES_SwapWindow; + _this->GL_DestroyContext = WIN_GLES_DestroyContext; + _this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; + return WIN_GLES_LoadLibrary(_this, path); +#else + return SDL_SetError("SDL not configured with EGL support"); +#endif +} + bool WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) { void *handle; + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) && + SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, false)) { + return WIN_GL_LoadLibrary_EGLFallback(_this, path); + } + if (path == NULL) { path = SDL_GetHint(SDL_HINT_OPENGL_LIBRARY); } @@ -740,19 +765,8 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window) if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) { #ifdef SDL_VIDEO_OPENGL_EGL // Switch to EGL based functions - WIN_GL_UnloadLibrary(_this); - _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; - _this->GL_GetProcAddress = WIN_GLES_GetProcAddress; - _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; - _this->GL_CreateContext = WIN_GLES_CreateContext; - _this->GL_MakeCurrent = WIN_GLES_MakeCurrent; - _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; - _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; - _this->GL_SwapWindow = WIN_GLES_SwapWindow; - _this->GL_DestroyContext = WIN_GLES_DestroyContext; - _this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; - if (!WIN_GLES_LoadLibrary(_this, NULL)) { + if (!WIN_GL_LoadLibrary_EGLFallback(_this, NULL)) { return NULL; } diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 07e895d46c..9724913c73 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -163,6 +163,26 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, static void X11_GL_InitExtensions(SDL_VideoDevice *_this); +static bool X11_GL_LoadLibrary_EGLFallback(SDL_VideoDevice *_this, const char *path) +{ +#ifdef SDL_VIDEO_OPENGL_EGL + X11_GL_UnloadLibrary(_this); + _this->GL_LoadLibrary = X11_GLES_LoadLibrary; + _this->GL_GetProcAddress = X11_GLES_GetProcAddress; + _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; + _this->GL_CreateContext = X11_GLES_CreateContext; + _this->GL_MakeCurrent = X11_GLES_MakeCurrent; + _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; + _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; + _this->GL_SwapWindow = X11_GLES_SwapWindow; + _this->GL_DestroyContext = X11_GLES_DestroyContext; + _this->GL_GetEGLSurface = X11_GLES_GetEGLSurface; + return X11_GLES_LoadLibrary(_this, path); +#else + return SDL_SetError("SDL not configured with EGL support"); +#endif +} + bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) { Display *display; @@ -172,6 +192,11 @@ bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) return SDL_SetError("OpenGL context already created"); } + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) && + SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, false)) { + return X11_GL_LoadLibrary_EGLFallback(_this, path); + } + // Load the OpenGL library if (path == NULL) { path = SDL_GetHint(SDL_HINT_OPENGL_LIBRARY); @@ -254,21 +279,7 @@ bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, false)) && X11_GL_UseEGL(_this)) { -#ifdef SDL_VIDEO_OPENGL_EGL - X11_GL_UnloadLibrary(_this); - _this->GL_LoadLibrary = X11_GLES_LoadLibrary; - _this->GL_GetProcAddress = X11_GLES_GetProcAddress; - _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; - _this->GL_CreateContext = X11_GLES_CreateContext; - _this->GL_MakeCurrent = X11_GLES_MakeCurrent; - _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; - _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; - _this->GL_SwapWindow = X11_GLES_SwapWindow; - _this->GL_DestroyContext = X11_GLES_DestroyContext; - return X11_GLES_LoadLibrary(_this, NULL); -#else - return SDL_SetError("SDL not configured with EGL support"); -#endif + return X11_GL_LoadLibrary_EGLFallback(_this, NULL); } return true; From 55fa5e033676b6a41328427b56612115ef1ed6da Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Mon, 16 Mar 2026 18:08:43 +0100 Subject: [PATCH 003/407] SDL_dynapi.c: Unload other SDL library if initializing the jumptable fails --- src/dynapi/SDL_dynapi.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index e88b24f191..803936b06a 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -448,17 +448,27 @@ Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) } #endif +// The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR +#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) +static HMODULE lib = NULL; +#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) +static void *lib = NULL; +#else +#error Please define your platform. +#endif + // Obviously we can't use SDL_LoadObject() to load SDL. :) // Also obviously, we never close the loaded library. #if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) { - HMODULE lib = LoadLibraryA(fname); + lib = LoadLibraryA(fname); void *result = NULL; if (lib) { result = (void *) GetProcAddress(lib, sym); if (!result) { FreeLibrary(lib); + lib = NULL; } } return result; @@ -468,19 +478,17 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) #include static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) { - void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); + lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); void *result = NULL; if (lib) { result = dlsym(lib, sym); if (!result) { dlclose(lib); + lib = NULL; } } return result; } - -#else -#error Please define your platform. #endif static void dynapi_warn(const char *msg) @@ -548,6 +556,16 @@ static void SDL_InitDynamicAPILocked(void) if (entry) { if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) { dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL."); + + // unload the other SDL library +#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) + FreeLibrary(lib); + lib = NULL; +#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) + dlclose(lib); + lib = NULL; +#endif + // Just fill in the function pointers from this library, later. } else { use_internal = false; // We overrode SDL! Don't use the internal version! From 6b060435e3dba660270154d977bd5dae20e7814b Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Tue, 17 Mar 2026 21:45:42 -0700 Subject: [PATCH 004/407] egl: Handle error when binding EGL API in context creation --- src/video/SDL_egl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 6a3a4d85c4..73db8f6f07 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -1115,7 +1115,10 @@ SDL_GLContext SDL_EGL_CreateContext(SDL_VideoDevice *_this, EGLSurface egl_surfa } else { _this->egl_data->apitype = EGL_OPENGL_API; } - _this->egl_data->eglBindAPI(_this->egl_data->apitype); + if (!_this->egl_data->eglBindAPI(_this->egl_data->apitype)) { + SDL_SetError("Could not bind EGL API"); + return NULL; + } egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display, _this->egl_data->egl_config, From b0cf8262279417c96a2e65e7f6dd60247f02d43a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 18 Mar 2026 13:12:56 -0400 Subject: [PATCH 005/407] dynapi: Minor cleanups to library loading code. --- src/dynapi/SDL_dynapi.c | 61 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index 803936b06a..a0135dca42 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -448,27 +448,28 @@ Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) } #endif -// The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR -#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) -static HMODULE lib = NULL; -#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) -static void *lib = NULL; -#else -#error Please define your platform. -#endif // Obviously we can't use SDL_LoadObject() to load SDL. :) -// Also obviously, we never close the loaded library. +// Also obviously, we never close the loaded library, once we accept it. #if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) +static HMODULE sdlapi_lib = NULL; // The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR + +static SDL_INLINE void unload_sdlapi_library(void) +{ + if (sdlapi_lib) { + FreeLibrary(sdlapi_lib); + sdlapi_lib = NULL; + } +} + static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) { - lib = LoadLibraryA(fname); + sdlapi_lib = LoadLibraryA(fname); void *result = NULL; - if (lib) { - result = (void *) GetProcAddress(lib, sym); + if (sdlapi_lib) { + result = (void *) GetProcAddress(sdlapi_lib, sym); if (!result) { - FreeLibrary(lib); - lib = NULL; + unload_sdlapi_library(); } } return result; @@ -476,19 +477,31 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) #elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) #include +static void *sdlapi_lib = NULL; // The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR + +static SDL_INLINE void unload_sdlapi_library(void) +{ + if (sdlapi_lib) { + dlclose(sdlapi_lib); + sdlapi_lib = NULL; + } +} + static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) { - lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); + sdlapi_lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); void *result = NULL; - if (lib) { - result = dlsym(lib, sym); + if (sdlapi_lib) { + result = dlsym(sdlapi_lib, sym); if (!result) { - dlclose(lib); - lib = NULL; + unload_sdlapi_library(); } } return result; } + +#else +#error Please define your platform. #endif static void dynapi_warn(const char *msg) @@ -557,14 +570,8 @@ static void SDL_InitDynamicAPILocked(void) if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) { dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL."); - // unload the other SDL library -#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) - FreeLibrary(lib); - lib = NULL; -#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) - dlclose(lib); - lib = NULL; -#endif + // unload the failed SDL library + unload_sdlapi_library(); // Just fill in the function pointers from this library, later. } else { From 291d1b6491992cdad2bb94c9b8ef9b4b9395d325 Mon Sep 17 00:00:00 2001 From: Konstantin Tomashevich Date: Wed, 18 Mar 2026 21:44:18 +0300 Subject: [PATCH 006/407] SDL_systhread.c: Remove SIGCHLD from blocked signal mask. When SIGCHLD is blocked, some executables (for example CMake) do not exit properly when executed using `SDL_CreateProcess` from any SDL thread (not main thread). `SDL_CreateProcessWithProperties` docs say that `SIGCHILD` should not be ignored or handled, therefore blocking it during thread creation is a likely reason for the bug. Should fix #15210. Signed-off-by: Konstantin Tomashevich --- src/thread/pthread/SDL_systhread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 37001982c7..fd16b2d8eb 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -60,7 +60,7 @@ #ifdef HAVE_SIGNAL_H // List of signals to mask in the subthreads static const int sig_list[] = { - SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, + SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, SIGVTALRM, SIGPROF, 0 }; #endif From 0e50195d3790184b2c9f38d441de0693b14229db Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 20 Mar 2026 01:07:55 +0000 Subject: [PATCH 007/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_stdinc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index cbe41cfb9d..28e5f78744 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -4418,9 +4418,6 @@ extern SDL_DECLSPEC Sint32 SDLCALL SDL_rand_r(Uint64 *state, Sint32 n); /** * Generate a uniform pseudo-random floating point number less than 1.0 * - * If you want reproducible output, be sure to initialize with SDL_srand() - * first. - * * There are no guarantees as to the quality of the random sequence produced, * and this should not be used for security (cryptography, passwords) or where * money is on the line (loot-boxes, casinos). There are many random number From 7360a3718116491ad7da0463184c2c01979010b5 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 20 Mar 2026 15:39:03 +0000 Subject: [PATCH 008/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_stdinc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index 28e5f78744..ce8c7dbd5e 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -3996,7 +3996,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_strpbrk(const char *str, const char *brea * NULL-terminated, as the function will blindly read until it sees the NULL * char. * - * if `*pslen` is zero, it assumes the end of string is reached and returns a + * If `*pslen` is zero, it assumes the end of string is reached and returns a * zero codepoint regardless of the contents of the string buffer. * * If the resulting codepoint is zero (a NULL terminator), or `*pslen` is From 3462494ec1a34efc55ac57cc5033280babccdc23 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 20 Mar 2026 18:21:04 +0000 Subject: [PATCH 009/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_pixels.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_pixels.h b/include/SDL3/SDL_pixels.h index 475e5f9c38..fd1ed31a4a 100644 --- a/include/SDL3/SDL_pixels.h +++ b/include/SDL3/SDL_pixels.h @@ -1407,7 +1407,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixelvalue, const SDL_PixelFo * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). * - * If the surface has no alpha component, the alpha will be returned as 0xff + * If the format has no alpha component, the alpha will be returned as 0xff * (100% opaque). * * \param pixelvalue a pixel value. From 0f9292a367424edd4feb5917d23345f28ff32694 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 21 Mar 2026 14:08:40 -0700 Subject: [PATCH 010/407] Fixed incorrect sampler when changing Metal draw state --- src/render/metal/SDL_render_metal.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index 8aa78522ae..d5187b6113 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -1393,6 +1393,7 @@ typedef struct size_t constants_offset; SDL_Texture *texture; bool texture_palette; + SDL_PixelFormat texture_format; SDL_ScaleMode texture_scale_mode; SDL_TextureAddressMode texture_address_mode_u; SDL_TextureAddressMode texture_address_mode_v; @@ -1669,7 +1670,8 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c statecache->texture = texture; } - if (cmd->data.draw.texture_scale_mode != statecache->texture_scale_mode || + if (texture->format != statecache->texture_format || + cmd->data.draw.texture_scale_mode != statecache->texture_scale_mode || cmd->data.draw.texture_address_mode_u != statecache->texture_address_mode_u || cmd->data.draw.texture_address_mode_v != statecache->texture_address_mode_v) { id mtlsampler = GetSampler(data, texture->format, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v); @@ -1678,6 +1680,7 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c } [data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0]; + statecache->texture_format = texture->format; statecache->texture_scale_mode = cmd->data.draw.texture_scale_mode; statecache->texture_address_mode_u = cmd->data.draw.texture_address_mode_u; statecache->texture_address_mode_v = cmd->data.draw.texture_address_mode_v; From a48dee5ac1dcf73eb3b6391e605817bd97fcd9e0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 21 Mar 2026 16:03:40 -0700 Subject: [PATCH 011/407] Updated documentation on customizing your Android app name --- docs/README-android.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/README-android.md b/docs/README-android.md index f8e14d4f44..297088fe67 100644 --- a/docs/README-android.md +++ b/docs/README-android.md @@ -168,7 +168,7 @@ build-scripts/create-android-project.py --variant aar com.yourcompany.yourapp < Customizing your application name ================================================================================ -To customize your application name, edit AndroidManifest.xml and build.gradle to replace +To customize your application name, edit build.gradle to replace "org.libsdl.app" with an identifier for your product package. Then create a Java class extending SDLActivity and place it in a directory @@ -194,6 +194,8 @@ Here's an example of a minimal class file: Then replace "SDLActivity" in AndroidManifest.xml with the name of your class, .e.g. "MyGame" +Then edit app/src/main/res/values/strings.xml and change the name there. + Customizing your application icon ================================================================================ From ad9138470478969c9e2c5329943385e99434dda9 Mon Sep 17 00:00:00 2001 From: Edgar J San Martin <29460583+ej-sanmartin@users.noreply.github.com> Date: Tue, 30 Dec 2025 17:15:47 -0500 Subject: [PATCH 012/407] Base GCMouse raw input implementation Fix duplicate button/scroll events when GCMouse active Fix duplicate events and add thread-safe atomic for GCMouse Fix GCMouse relative mode sync when connected after mode enabled Respect SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE in GCMouse handler Fix variable shadowing in GCMouse motion handler --- docs/README-macos.md | 16 ++ src/video/cocoa/SDL_cocoamouse.h | 5 + src/video/cocoa/SDL_cocoamouse.m | 257 +++++++++++++++++++++++++++++- src/video/cocoa/SDL_cocoavideo.m | 11 +- src/video/cocoa/SDL_cocoawindow.m | 5 + 5 files changed, 284 insertions(+), 10 deletions(-) diff --git a/docs/README-macos.md b/docs/README-macos.md index 147174c015..0a97b3d5b9 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -246,6 +246,22 @@ You are free to modify your Cocoa app with generally no consequence to SDL. You cannot, however, easily change the SDL window itself. Functionality may be added in the future to help this. + +## Raw Mouse Input + +On macOS 11.0 (Big Sur) and later, SDL uses the Game Controller framework's +GCMouse API to provide raw, unaccelerated mouse input in relative mode. This +is ideal for games and applications requiring precise 1:1 mouse movement. + +On older macOS versions, SDL falls back to NSEvent-based mouse input, which +includes system mouse acceleration. + +To use accelerated (system-scaled) mouse movement on macOS 11.0+, set the hint: + +```c +SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "1"); +``` + # Bug reports Bugs are tracked at [the GitHub issue tracker](https://github.com/libsdl-org/SDL/issues/). diff --git a/src/video/cocoa/SDL_cocoamouse.h b/src/video/cocoa/SDL_cocoamouse.h index cc2711a12a..d9ce0e841d 100644 --- a/src/video/cocoa/SDL_cocoamouse.h +++ b/src/video/cocoa/SDL_cocoamouse.h @@ -32,6 +32,11 @@ extern void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event); extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y); extern void Cocoa_QuitMouse(SDL_VideoDevice *_this); +extern void Cocoa_InitGCMouse(void); +extern bool Cocoa_GCMouseRelativeMode(void); +extern bool Cocoa_HasGCMouse(void); +extern void Cocoa_QuitGCMouse(void); + struct SDL_CursorData { NSTimer *frameTimer; diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 17fb24452c..88f0744d39 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -27,6 +27,8 @@ #include "../../events/SDL_mouse_c.h" +#import + #if 0 #define DEBUG_COCOAMOUSE #endif @@ -254,6 +256,219 @@ static SDL_Cursor *Cocoa_CreateDefaultCursor(void) return Cocoa_CreateSystemCursor(id); } +// GCMouse support for raw (unaccelerated) mouse input on macOS 11.0+ +static id cocoa_mouse_connect_observer = nil; +static id cocoa_mouse_disconnect_observer = nil; +// Atomic for thread-safe access during high-frequency mouse input +static SDL_AtomicInt cocoa_gcmouse_relative_mode; +static bool cocoa_has_gcmouse = false; +static SDL_MouseWheelDirection cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; + +static void Cocoa_UpdateGCMouseScrollDirection(void) +{ + Boolean keyExistsAndHasValidFormat = NO; + Boolean naturalScrollDirection = CFPreferencesGetAppBooleanValue( + CFSTR("com.apple.swipescrolldirection"), + kCFPreferencesAnyApplication, + &keyExistsAndHasValidFormat); + if (!keyExistsAndHasValidFormat) { + // Couldn't read the preference, assume natural scrolling direction + naturalScrollDirection = YES; + } + if (naturalScrollDirection) { + cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; + } else { + cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; + } +} + +static bool Cocoa_SetGCMouseRelativeMode(bool enabled) +{ + SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, enabled ? 1 : 0); + return true; +} + +static void Cocoa_OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, + BOOL pressed) +{ + Uint64 timestamp = SDL_GetTicksNS(); + SDL_SendMouseButton(timestamp, SDL_GetMouseFocus(), mouseID, button, + pressed); +} + +static void Cocoa_OnGCMouseConnected(GCMouse *mouse) + API_AVAILABLE(macos(11.0)) +{ + SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse; + + SDL_AddMouse(mouseID, NULL); + cocoa_has_gcmouse = true; + + // Sync with SDL's current relative mode state (may have been set before + // GCMouse connected) + SDL_Mouse *sdl_mouse = SDL_GetMouse(); + if (sdl_mouse && sdl_mouse->relative_mode) { + SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, 1); + } + + mouse.mouseInput.leftButton.pressedChangedHandler = + ^(GCControllerButtonInput *button, float value, BOOL pressed) { + Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); + }; + mouse.mouseInput.middleButton.pressedChangedHandler = + ^(GCControllerButtonInput *button, float value, BOOL pressed) { + Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed); + }; + mouse.mouseInput.rightButton.pressedChangedHandler = + ^(GCControllerButtonInput *button, float value, BOOL pressed) { + Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); + }; + + int auxiliary_button = SDL_BUTTON_X1; + for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { + const int current_button = auxiliary_button; + btn.pressedChangedHandler = + ^(GCControllerButtonInput *button, float value, BOOL pressed) { + Cocoa_OnGCMouseButtonChanged(mouseID, current_button, pressed); + }; + ++auxiliary_button; + } + + mouse.mouseInput.mouseMovedHandler = + ^(GCMouseInput *mouseInput, float deltaX, float deltaY) { + if (Cocoa_GCMouseRelativeMode()) { + // Skip raw input if user wants system-scaled (accelerated) deltas + SDL_Mouse *m = SDL_GetMouse(); + if (m && m->enable_relative_system_scale) { + return; + } + Uint64 timestamp = SDL_GetTicksNS(); + SDL_SendMouseMotion(timestamp, SDL_GetMouseFocus(), mouseID, + true, deltaX, -deltaY); + } + }; + + mouse.mouseInput.scroll.valueChangedHandler = + ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + Uint64 timestamp = SDL_GetTicksNS(); + // Raw scroll values: vertical in first axis, horizontal in second. + // Vertical values are inverted compared to SDL conventions. + float vertical = -xValue; + float horizontal = yValue; + + if (cocoa_mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { + vertical = -vertical; + horizontal = -horizontal; + } + SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), mouseID, + horizontal, vertical, + cocoa_mouse_scroll_direction); + }; + Cocoa_UpdateGCMouseScrollDirection(); + + // Use high-priority queue for low-latency input + dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.mouse", + DISPATCH_QUEUE_SERIAL); + dispatch_set_target_queue(queue, + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); + mouse.handlerQueue = queue; +} + +static void Cocoa_OnGCMouseDisconnected(GCMouse *mouse) + API_AVAILABLE(macos(11.0)) +{ + SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse; + + mouse.mouseInput.mouseMovedHandler = nil; + mouse.mouseInput.leftButton.pressedChangedHandler = nil; + mouse.mouseInput.middleButton.pressedChangedHandler = nil; + mouse.mouseInput.rightButton.pressedChangedHandler = nil; + mouse.mouseInput.scroll.valueChangedHandler = nil; + + for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) { + button.pressedChangedHandler = nil; + } + + SDL_RemoveMouse(mouseID); + + // Check if any GCMouse devices remain + if (@available(macOS 11.0, *)) { + cocoa_has_gcmouse = ([GCMouse mice].count > 0); + } +} + +void Cocoa_InitGCMouse(void) +{ + @autoreleasepool { + if (@available(macOS 11.0, *)) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + cocoa_mouse_connect_observer = [center + addObserverForName:GCMouseDidConnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + Cocoa_OnGCMouseConnected(mouse); + }]; + + cocoa_mouse_disconnect_observer = [center + addObserverForName:GCMouseDidDisconnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + Cocoa_OnGCMouseDisconnected(mouse); + }]; + + // Enumerate already-connected mice + for (GCMouse *mouse in [GCMouse mice]) { + Cocoa_OnGCMouseConnected(mouse); + } + } + } +} + +bool Cocoa_GCMouseRelativeMode(void) +{ + return SDL_GetAtomicInt(&cocoa_gcmouse_relative_mode) != 0; +} + +bool Cocoa_HasGCMouse(void) +{ + return cocoa_has_gcmouse; +} + +void Cocoa_QuitGCMouse(void) +{ + @autoreleasepool { + if (@available(macOS 11.0, *)) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + if (cocoa_mouse_connect_observer) { + [center removeObserver:cocoa_mouse_connect_observer + name:GCMouseDidConnectNotification + object:nil]; + cocoa_mouse_connect_observer = nil; + } + + if (cocoa_mouse_disconnect_observer) { + [center removeObserver:cocoa_mouse_disconnect_observer + name:GCMouseDidDisconnectNotification + object:nil]; + cocoa_mouse_disconnect_observer = nil; + } + + for (GCMouse *mouse in [GCMouse mice]) { + Cocoa_OnGCMouseDisconnected(mouse); + } + + cocoa_has_gcmouse = false; + SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, 0); + } + } +} + static void Cocoa_FreeCursor(SDL_Cursor *cursor) { @autoreleasepool { @@ -360,19 +575,29 @@ static bool Cocoa_SetRelativeMouseMode(bool enabled) { CGError result; + // Update GCMouse relative mode state if available + if (Cocoa_HasGCMouse()) { + Cocoa_SetGCMouseRelativeMode(enabled); + } + if (enabled) { SDL_Window *window = SDL_GetKeyboardFocus(); if (window) { - /* We will re-apply the relative mode when the window finishes being moved, - * if it is being moved right now. + /* We will re-apply the relative mode when the window finishes + * being moved, if it is being moved right now. */ - SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal; + SDL_CocoaWindowData *data = + (__bridge SDL_CocoaWindowData *)window->internal; if ([data.listener isMovingOrFocusClickPending]) { return true; } - // make sure the mouse isn't at the corner of the window, as this can confuse things if macOS thinks a window resize is happening on the first click. - const CGPoint point = CGPointMake((float)(window->x + (window->w / 2)), (float)(window->y + (window->h / 2))); + // Make sure the mouse isn't at the corner of the window, as this + // can confuse things if macOS thinks a window resize is happening + // on the first click. + const CGPoint point = CGPointMake( + (float)(window->x + (window->w / 2)), + (float)(window->y + (window->h / 2))); Cocoa_HandleMouseWarp(point.x, point.y); CGWarpMouseCursorPosition(point); } @@ -590,6 +815,17 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event) return; } + // When GCMouse is active in relative mode, it handles motion events + // directly with raw (unaccelerated) deltas. Skip NSEvent-based motion + // unless the user wants system-scaled (accelerated) input. + if (Cocoa_HasGCMouse() && Cocoa_GCMouseRelativeMode()) { + if (!mouse->enable_relative_system_scale) { + // GCMouse is providing raw input, skip NSEvent deltas + return; + } + // SYSTEM_SCALE is enabled: use NSEvent accelerated deltas instead + } + // Ignore events that aren't inside the client area (i.e. title bar.) if ([event window]) { NSRect windowRect = [[[event window] contentView] frame]; @@ -606,14 +842,21 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event) deltaX += (lastMoveX - data->lastWarpX); deltaY += ((videodata.mainDisplayHeight - lastMoveY) - data->lastWarpY); - DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY); + DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], + [event deltaY], deltaX, deltaY); } - SDL_SendMouseMotion(Cocoa_GetEventTimestamp([event timestamp]), mouse->focus, mouseID, true, deltaX, deltaY); + SDL_SendMouseMotion(Cocoa_GetEventTimestamp([event timestamp]), + mouse->focus, mouseID, true, deltaX, deltaY); } void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) { + // GCMouse handles scroll events directly, skip NSEvent path to avoid duplicates + if (Cocoa_HasGCMouse()) { + return; + } + SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID; SDL_MouseWheelDirection direction; CGFloat x, y; diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index fa343aca5d..081e162be0 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -209,10 +209,14 @@ static bool Cocoa_VideoInit(SDL_VideoDevice *_this) return false; } - // Assume we have a mouse and keyboard - // We could use GCMouse and GCKeyboard if we needed to, as is done in SDL_uikitevents.m + // Initialize GCMouse for raw input on macOS 11.0+ + Cocoa_InitGCMouse(); + + // Add default keyboard and mouse if GCMouse didn't provide any SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL); - SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL); + if (!Cocoa_HasGCMouse()) { + SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL); + } data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, true); data.trackpad_is_touch_only = SDL_GetHintBoolean(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, false); @@ -233,6 +237,7 @@ void Cocoa_VideoQuit(SDL_VideoDevice *_this) SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal; Cocoa_QuitModes(_this); Cocoa_QuitKeyboard(_this); + Cocoa_QuitGCMouse(); Cocoa_QuitMouse(_this); Cocoa_QuitPen(_this); SDL_DestroyMutex(data.swaplock); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 9225c225be..79c17713eb 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1717,6 +1717,11 @@ static NSCursor *Cocoa_GetDesiredCursor(void) static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_Window *window, Uint8 button, bool down) { + // GCMouse handles button events directly, skip NSEvent path to avoid duplicates + if (Cocoa_HasGCMouse()) { + return; + } + SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID; //const int clicks = (int)[theEvent clickCount]; SDL_Window *focus = SDL_GetKeyboardFocus(); From f22e0882111d1175c4456126efd4bec5fbd7b5c8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 22 Mar 2026 17:51:56 -0700 Subject: [PATCH 013/407] Clarified SDL_MostSignificantBitIndex32() documentation Fixes https://github.com/libsdl-org/SDL/issues/15247 --- include/SDL3/SDL_bits.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/SDL3/SDL_bits.h b/include/SDL3/SDL_bits.h index ddb5cdbabe..d3310ab15c 100644 --- a/include/SDL3/SDL_bits.h +++ b/include/SDL3/SDL_bits.h @@ -48,8 +48,7 @@ extern __inline int _SDL_bsr_watcom(Uint32); /** * Get the index of the most significant (set) bit in a 32-bit number. * - * Result is undefined when called with 0. This operation can also be stated - * as "count leading zeroes" and "log base 2". + * This operation can also be stated as "count leading zeroes" and "log base 2". * * Note that this is a forced-inline function in a header, and not a public * API function available in the SDL library (which is to say, the code is From 28423eed96a487959d9667040b2ca050c780bf20 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Mon, 23 Mar 2026 00:53:55 +0000 Subject: [PATCH 014/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_bits.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_bits.h b/include/SDL3/SDL_bits.h index d3310ab15c..98e977e0bf 100644 --- a/include/SDL3/SDL_bits.h +++ b/include/SDL3/SDL_bits.h @@ -48,7 +48,8 @@ extern __inline int _SDL_bsr_watcom(Uint32); /** * Get the index of the most significant (set) bit in a 32-bit number. * - * This operation can also be stated as "count leading zeroes" and "log base 2". + * This operation can also be stated as "count leading zeroes" and "log base + * 2". * * Note that this is a forced-inline function in a header, and not a public * API function available in the SDL library (which is to say, the code is From 00f9a2587975d0fcf9508e5083dd79116e9f4f8d Mon Sep 17 00:00:00 2001 From: William Horvath Date: Fri, 20 Mar 2026 06:18:32 -0700 Subject: [PATCH 015/407] windowsrawinput: Add missing WIN_SetRawKeyboardFlag_Inputsink stub. --- src/video/windows/SDL_windowsrawinput.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index 5ae2f51d23..53b06389cc 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -334,6 +334,11 @@ bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled) return SDL_Unsupported(); } +bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled) +{ + return SDL_Unsupported(); +} + #endif // !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES #endif // SDL_VIDEO_DRIVER_WINDOWS From 706e7f904329a3f47324bc4ae8e2631d9a0f562e Mon Sep 17 00:00:00 2001 From: William Horvath Date: Fri, 20 Mar 2026 06:19:48 -0700 Subject: [PATCH 016/407] windowsrawinput: Fix incorrect INVALID_HANDLE_VALUE checks. CreateEvent/CreateThread return NULL on failure. --- src/video/windows/SDL_windowsrawinput.c | 26 ++++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index 53b06389cc..9bbb07d861 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -46,13 +46,7 @@ typedef struct HANDLE thread; } RawInputThreadData; -static RawInputThreadData thread_data = { - false, - 0, - INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE -}; +static RawInputThreadData thread_data = { 0 }; static DWORD WINAPI WIN_RawInputThread(LPVOID param) { @@ -140,22 +134,22 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) static void CleanupRawInputThreadData(RawInputThreadData *data) { - if (data->thread != INVALID_HANDLE_VALUE) { + if (data->thread) { data->done = true; SetEvent(data->signal_event); WaitForSingleObject(data->thread, 3000); CloseHandle(data->thread); - data->thread = INVALID_HANDLE_VALUE; + data->thread = NULL; } - if (data->ready_event != INVALID_HANDLE_VALUE) { + if (data->ready_event) { CloseHandle(data->ready_event); - data->ready_event = INVALID_HANDLE_VALUE; + data->ready_event = NULL; } - if (data->signal_event != INVALID_HANDLE_VALUE) { + if (data->signal_event) { CloseHandle(data->signal_event); - data->signal_event = INVALID_HANDLE_VALUE; + data->signal_event = NULL; } } @@ -170,20 +164,20 @@ bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) thread_data.flags = flags; thread_data.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (thread_data.ready_event == INVALID_HANDLE_VALUE) { + if (!thread_data.ready_event) { WIN_SetError("CreateEvent"); goto done; } thread_data.done = false; thread_data.signal_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (thread_data.signal_event == INVALID_HANDLE_VALUE) { + if (!thread_data.signal_event) { WIN_SetError("CreateEvent"); goto done; } thread_data.thread = CreateThread(NULL, 0, WIN_RawInputThread, &thread_data, 0, NULL); - if (thread_data.thread == INVALID_HANDLE_VALUE) { + if (!thread_data.thread) { WIN_SetError("CreateThread"); goto done; } From 983e984afc742eec445431365ae87395298bf74f Mon Sep 17 00:00:00 2001 From: William Horvath Date: Fri, 20 Mar 2026 06:23:45 -0700 Subject: [PATCH 017/407] windowsrawinput: Unregister/register raw input devices as necessary. The thread is still created once and only shut down on WIN_VideoQuit, but the thread will unregister the devices when they're disabled to avoid wasting time processing raw input that won't be appreciated by anyone. This also allows RIDEV_NOLEGACY to be set on the devices, otherwise they swallow up the WM_MOUSE* events that would be going to the main thread when relative mode is disabled. That's out of scope for this change, though. --- src/video/windows/SDL_windowsrawinput.c | 307 +++++++++++++++--------- src/video/windows/SDL_windowsrawinput.h | 2 +- src/video/windows/SDL_windowsvideo.c | 4 +- src/video/windows/SDL_windowsvideo.h | 1 - 4 files changed, 200 insertions(+), 114 deletions(-) diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index 9bbb07d861..e9b4aad3d9 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -40,7 +40,7 @@ typedef struct { bool done; - Uint32 flags; + SDL_AtomicU32 flags; // Thread sets this to the actually-set flags if updating state failed HANDLE ready_event; HANDLE signal_event; HANDLE thread; @@ -48,13 +48,102 @@ typedef struct static RawInputThreadData thread_data = { 0 }; +typedef enum +{ + RINP_QUIT, + RINP_UPDATE, + RINP_CONTINUE +} RawInputIterateResult; + +static RawInputIterateResult IterateRawInputThread(void) +{ + // The high-order word of GetQueueStatus() will let us know if there's immediate raw input to be processed. + // A (necessary!) side effect is that it also marks the message queue bits as stale, + // so MsgWaitForMultipleObjects will block. + + // Any pending flag update won't be processed until the queue drains, but this is + // at most one poll cycle since GetQueueStatus clears the wake bits. + if (HIWORD(GetQueueStatus(QS_RAWINPUT)) & QS_RAWINPUT) { + return thread_data.done ? RINP_QUIT : RINP_CONTINUE; + } + + static const DWORD WAIT_SIGNAL = WAIT_OBJECT_0; + static const DWORD WAIT_INPUT = WAIT_OBJECT_0 + 1; + + // There wasn't anything, so we'll wait until new data (or signal_event) wakes us up. + DWORD wait_status = MsgWaitForMultipleObjects(1, &thread_data.signal_event, FALSE, INFINITE, QS_RAWINPUT); + if (wait_status == WAIT_SIGNAL) { + // signal_event can only be set if we need to update or quit. + return thread_data.done ? RINP_QUIT : RINP_UPDATE; + } else if (wait_status == WAIT_INPUT) { + return RINP_CONTINUE; + } else { + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Raw input thread exiting, unexpected wait result: %lu", wait_status); + return RINP_QUIT; + } +} + +static bool UpdateRawInputDeviceFlags(HWND window, Uint32 last_flags, Uint32 new_flags) +{ + // We had nothing enabled, and we're trying to stop everything. Nothing to do. + if (last_flags == new_flags) { + return true; + } + + RAWINPUTDEVICE devices[2] = { 0 }; + UINT count = 0; + + if ((new_flags & ENABLE_RAW_MOUSE_INPUT) != (last_flags & ENABLE_RAW_MOUSE_INPUT)) { + devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + devices[count].usUsage = USB_USAGE_GENERIC_MOUSE; + + if (new_flags & ENABLE_RAW_MOUSE_INPUT) { + devices[count].dwFlags = 0; + devices[count].hwndTarget = window; + } else { + devices[count].dwFlags = RIDEV_REMOVE; + devices[count].hwndTarget = NULL; + } + + ++count; + } + + const Uint32 old_kb_flags = last_flags & (ENABLE_RAW_KEYBOARD_INPUT | RAW_KEYBOARD_FLAG_NOHOTKEYS | RAW_KEYBOARD_FLAG_INPUTSINK); + const Uint32 new_kb_flags = new_flags & (ENABLE_RAW_KEYBOARD_INPUT | RAW_KEYBOARD_FLAG_NOHOTKEYS | RAW_KEYBOARD_FLAG_INPUTSINK); + + if (old_kb_flags != new_kb_flags) { + devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + devices[count].usUsage = USB_USAGE_GENERIC_KEYBOARD; + + if (new_kb_flags & ENABLE_RAW_KEYBOARD_INPUT) { + devices[count].dwFlags = 0; + devices[count].hwndTarget = window; + if (new_kb_flags & RAW_KEYBOARD_FLAG_NOHOTKEYS) { + devices[count].dwFlags |= RIDEV_NOHOTKEYS; + } + + if (new_kb_flags & RAW_KEYBOARD_FLAG_INPUTSINK) { + devices[count].dwFlags |= RIDEV_INPUTSINK; + } + } else { + devices[count].dwFlags = RIDEV_REMOVE; + devices[count].hwndTarget = NULL; + } + + ++count; + } + + if (RegisterRawInputDevices(devices, count, sizeof(devices[0]))) { + return true; + } + return false; +} + static DWORD WINAPI WIN_RawInputThread(LPVOID param) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); - RawInputThreadData *data = (RawInputThreadData *)param; - RAWINPUTDEVICE devices[2]; + Uint32 last_flags = 0; HWND window; - UINT count = 0; SDL_SYS_SetupThread("SDLRawInput"); @@ -63,31 +152,9 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) return 0; } - SDL_zeroa(devices); - - if (data->flags & ENABLE_RAW_MOUSE_INPUT) { - devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; - devices[count].usUsage = USB_USAGE_GENERIC_MOUSE; - devices[count].dwFlags = 0; - devices[count].hwndTarget = window; - ++count; - } - - if (data->flags & ENABLE_RAW_KEYBOARD_INPUT) { - devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; - devices[count].usUsage = USB_USAGE_GENERIC_KEYBOARD; - devices[count].dwFlags = 0; - if (data->flags & RAW_KEYBOARD_FLAG_NOHOTKEYS) { - devices[count].dwFlags |= RIDEV_NOHOTKEYS; - } - if (data->flags & RAW_KEYBOARD_FLAG_INPUTSINK) { - devices[count].dwFlags |= RIDEV_INPUTSINK; - } - devices[count].hwndTarget = window; - ++count; - } - - if (!RegisterRawInputDevices(devices, count, sizeof(devices[0]))) { + // This doesn't *really* need to be atomic, because the parent is waiting for us + last_flags = SDL_GetAtomicU32(&thread_data.flags); + if (!UpdateRawInputDeviceFlags(window, 0, last_flags)) { DestroyWindow(window); return 0; } @@ -96,24 +163,38 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); // Tell the parent we're ready to go! - SetEvent(data->ready_event); + SetEvent(thread_data.ready_event); + + RawInputIterateResult iter_result; Uint64 idle_begin = SDL_GetTicksNS(); - while (!data->done && - // The high-order word of GetQueueStatus() will let us know if there's currently raw input to be processed. - // If there isn't, then we'll wait for new data to arrive with MsgWaitForMultipleObjects(). - ((HIWORD(GetQueueStatus(QS_RAWINPUT)) & QS_RAWINPUT) || - (MsgWaitForMultipleObjects(1, &data->signal_event, FALSE, INFINITE, QS_RAWINPUT) == WAIT_OBJECT_0 + 1))) { + while ((iter_result = IterateRawInputThread()) != RINP_QUIT) { + switch (iter_result) { + case RINP_QUIT: // Unreachable + break; + case RINP_UPDATE: + { + const Uint32 new_flags = SDL_GetAtomicU32(&thread_data.flags); + if (!UpdateRawInputDeviceFlags(window, last_flags, new_flags)) { + // Revert the shared flags so the main thread can detect the failure + SDL_SetAtomicU32(&thread_data.flags, last_flags); + } else { + last_flags = new_flags; + } + } break; + case RINP_CONTINUE: + { + Uint64 idle_end = SDL_GetTicksNS(); + Uint64 idle_time = idle_end - idle_begin; + Uint64 usb_8khz_interval = SDL_US_TO_NS(125); + Uint64 poll_start = idle_time < usb_8khz_interval ? _this->internal->last_rawinput_poll : idle_end; - Uint64 idle_end = SDL_GetTicksNS(); - Uint64 idle_time = idle_end - idle_begin; - Uint64 usb_8khz_interval = SDL_US_TO_NS(125); - Uint64 poll_start = idle_time < usb_8khz_interval ? _this->internal->last_rawinput_poll : idle_end; + WIN_PollRawInput(_this, poll_start); - WIN_PollRawInput(_this, poll_start); - - // Reset idle_begin for the next go-around - idle_begin = SDL_GetTicksNS(); + // Reset idle_begin for the next go-around + idle_begin = SDL_GetTicksNS(); + } break; + } } if (_this->internal->raw_input_fake_pen_id) { @@ -121,48 +202,84 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) _this->internal->raw_input_fake_pen_id = 0; } - devices[0].dwFlags |= RIDEV_REMOVE; - devices[0].hwndTarget = NULL; - devices[1].dwFlags |= RIDEV_REMOVE; - devices[1].hwndTarget = NULL; - RegisterRawInputDevices(devices, count, sizeof(devices[0])); + // Reset this here, since if we're exiting due to failure, WIN_UpdateRawInputEnabled would see a stale value. + SDL_SetAtomicU32(&thread_data.flags, 0); + + UpdateRawInputDeviceFlags(NULL, last_flags, 0); DestroyWindow(window); return 0; } -static void CleanupRawInputThreadData(RawInputThreadData *data) +static void CleanupRawInputThreadData(void) { - if (data->thread) { - data->done = true; - SetEvent(data->signal_event); - WaitForSingleObject(data->thread, 3000); - CloseHandle(data->thread); - data->thread = NULL; + if (thread_data.thread) { + thread_data.done = true; + SetEvent(thread_data.signal_event); + WaitForSingleObject(thread_data.thread, 3000); + CloseHandle(thread_data.thread); } - if (data->ready_event) { - CloseHandle(data->ready_event); - data->ready_event = NULL; + if (thread_data.ready_event) { + CloseHandle(thread_data.ready_event); } - if (data->signal_event) { - CloseHandle(data->signal_event); - data->signal_event = NULL; + if (thread_data.signal_event) { + CloseHandle(thread_data.signal_event); } + + thread_data = (RawInputThreadData){ 0 }; } -bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) +// Computes the desired raw input flags from SDL_VideoData and ensures the +// raw input thread's device registrations match. +// Creates the thread on first use, only WIN_QuitRawInput actually shuts it down. +static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this) { bool result = false; + SDL_VideoData *data = _this->internal; + Uint32 desired_flags = 0; - CleanupRawInputThreadData(&thread_data); + if (data->raw_mouse_enabled) { + desired_flags |= ENABLE_RAW_MOUSE_INPUT; + } + if (data->raw_keyboard_enabled) { + desired_flags |= ENABLE_RAW_KEYBOARD_INPUT; + } + if (data->raw_keyboard_flag_nohotkeys) { + desired_flags |= RAW_KEYBOARD_FLAG_NOHOTKEYS; + } + if (data->raw_keyboard_flag_inputsink) { + desired_flags |= RAW_KEYBOARD_FLAG_INPUTSINK; + } - if (flags) { - HANDLE handles[2]; + if (desired_flags == SDL_GetAtomicU32(&thread_data.flags)) { + result = true; + goto done; + } - thread_data.flags = flags; + // If the thread exited unexpectedly (e.g. MsgWaitForMultipleObjects failed), + // the handle is stale. Clean it up so the creation path below can recover. + if (thread_data.thread && WaitForSingleObject(thread_data.thread, 0) != WAIT_TIMEOUT) { + CleanupRawInputThreadData(); + } + + // The thread will read from this to update its flags + SDL_SetAtomicU32(&thread_data.flags, desired_flags); + + if (thread_data.thread) { + // Thread is already running. Fire (the event) and forget, it'll read the atomic flags on wakeup. + + // If RegisterRawInputDevices fails, the thread reverts the atomic and the next call + // to this function will see the mismatch and retry. + SDL_assert(thread_data.signal_event); + SetEvent(thread_data.signal_event); + result = true; + } else if (desired_flags) { + HANDLE wait_handles[2]; + + // Thread isn't running, spin it up thread_data.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!thread_data.ready_event) { WIN_SetError("CreateEvent"); @@ -176,63 +293,31 @@ bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) goto done; } - thread_data.thread = CreateThread(NULL, 0, WIN_RawInputThread, &thread_data, 0, NULL); + thread_data.thread = CreateThread(NULL, 0, WIN_RawInputThread, NULL, 0, NULL); if (!thread_data.thread) { WIN_SetError("CreateThread"); goto done; } - // Wait for the thread to signal ready or exit - handles[0] = thread_data.ready_event; - handles[1] = thread_data.thread; - if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0) { + // Wait for the thread to complete initial setup or exit + wait_handles[0] = thread_data.ready_event; + wait_handles[1] = thread_data.thread; + if (WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE) != WAIT_OBJECT_0) { SDL_SetError("Couldn't set up raw input handling"); goto done; } result = true; } else { + // Thread isn't running and we tried to disable raw input, nothing to do result = true; } - done: if (!result) { - CleanupRawInputThreadData(&thread_data); + CleanupRawInputThreadData(); } return result; } -static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this) -{ - SDL_VideoData *data = _this->internal; - Uint32 flags = 0; - if (data->raw_mouse_enabled) { - flags |= ENABLE_RAW_MOUSE_INPUT; - } - if (data->raw_keyboard_enabled) { - flags |= ENABLE_RAW_KEYBOARD_INPUT; - } - if (data->raw_keyboard_flag_nohotkeys) { - flags |= RAW_KEYBOARD_FLAG_NOHOTKEYS; - } - if (data->raw_keyboard_flag_inputsink) { - flags |= RAW_KEYBOARD_FLAG_INPUTSINK; - } - - // Leave the thread running, as it takes several ms to shut it down and spin it up. - // We'll continue processing them so they don't back up in the thread event queue, - // but we won't deliver raw events in the application. - flags |= (data->raw_input_enabled & (ENABLE_RAW_MOUSE_INPUT | ENABLE_RAW_KEYBOARD_INPUT)); - - if (flags != data->raw_input_enabled) { - if (WIN_SetRawInputEnabled(_this, flags)) { - data->raw_input_enabled = flags; - } else { - return false; - } - } - return true; -} - bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled) { SDL_VideoData *data = _this->internal; @@ -306,13 +391,13 @@ bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled) return WIN_SetRawKeyboardFlag(_this, INPUTSINK, enabled); } -#else - -bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) +void WIN_QuitRawInput(SDL_VideoDevice *_this) { - return SDL_Unsupported(); + CleanupRawInputThreadData(); } +#else + bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled) { return SDL_Unsupported(); @@ -333,6 +418,10 @@ bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled) return SDL_Unsupported(); } +void WIN_QuitRawInput(SDL_VideoDevice *_this) +{ +} + #endif // !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES #endif // SDL_VIDEO_DRIVER_WINDOWS diff --git a/src/video/windows/SDL_windowsrawinput.h b/src/video/windows/SDL_windowsrawinput.h index 1adeb45f05..d5e6caa05a 100644 --- a/src/video/windows/SDL_windowsrawinput.h +++ b/src/video/windows/SDL_windowsrawinput.h @@ -23,7 +23,7 @@ #ifndef SDL_windowsrawinput_h_ #define SDL_windowsrawinput_h_ -extern bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags); +extern void WIN_QuitRawInput(SDL_VideoDevice *_this); extern bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled); extern bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled); extern bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 019a23c2d6..3a1527a443 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -671,9 +671,7 @@ void WIN_VideoQuit(SDL_VideoDevice *_this) SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); SDL_RemoveHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); - WIN_SetRawMouseEnabled(_this, false); - WIN_SetRawKeyboardEnabled(_this, false); - WIN_SetRawInputEnabled(_this, 0); + WIN_QuitRawInput(_this); WIN_QuitGameInput(_this); #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index fb34acfb23..b3240d3cb9 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -596,7 +596,6 @@ struct SDL_VideoData bool raw_keyboard_flag_nohotkeys; bool raw_keyboard_flag_inputsink; bool pending_E1_key_sequence; - Uint32 raw_input_enabled; SDL_PenID raw_input_fake_pen_id; WIN_GameInputData *gameinput_context; From 608416b5a92680044f960fcc32478680f783f1e3 Mon Sep 17 00:00:00 2001 From: Ian Monroe Date: Sun, 22 Mar 2026 04:53:21 +0000 Subject: [PATCH 018/407] support updating media name in the PipeWire backend with this, applications can do something like this: SDL_SetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, "current song") and this will be reflected in the Audio Devices Plasmoid, pavucontrol etc also cleaned up PW_KEY_MEDIA_NAME and PW_KEY_NODE_NAME; setting them to the same appears string appears to break convention, as it results in redundant titles in PipeWire application lists. --- src/audio/pipewire/SDL_pipewire.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index d40453d478..5dffd77578 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -90,6 +90,7 @@ static int (*PIPEWIRE_pw_stream_queue_buffer)(struct pw_stream *, struct pw_buff static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA_SENTINEL; static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *); static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4); +static int (*PIPEWIRE_pw_stream_update_properties)(struct pw_stream *, const struct spa_dict *); #ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC @@ -183,6 +184,7 @@ static bool load_pipewire_syms(void) SDL_PIPEWIRE_SYM(pw_properties_new); SDL_PIPEWIRE_SYM(pw_properties_set); SDL_PIPEWIRE_SYM(pw_properties_setf); + SDL_PIPEWIRE_SYM(pw_stream_update_properties); return true; } @@ -1118,6 +1120,24 @@ static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_E .add_buffer = stream_add_buffer_callback, .process = input_callback }; +static void SDLCALL PIPEWIRE_StreamNameChanged(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)userdata; + struct SDL_PrivateAudioData *priv = device->hidden; + + if (!priv || !priv->stream || !priv->loop) { + SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "PIPEWIRE: StreamNameChanged: stream not ready, skipping"); + return; + } + + struct spa_dict_item items[] = { { PW_KEY_MEDIA_NAME, newValue } }; + struct spa_dict dict = SPA_DICT_INIT(items, 1); + + PIPEWIRE_pw_thread_loop_lock(priv->loop); + PIPEWIRE_pw_stream_update_properties(priv->stream, &dict); + PIPEWIRE_pw_thread_loop_unlock(priv->loop); +} + static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) { /* @@ -1227,8 +1247,11 @@ static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) if (app_id) { PIPEWIRE_pw_properties_set(props, PW_KEY_APP_ID, app_id); } - PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name); - PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name); + // node_name/description describes the app, media_name what's currently playing + const char *node_name = (app_name && *app_name) ? app_name : stream_name; + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, node_name); + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, node_name); + PIPEWIRE_pw_properties_set(props, PW_KEY_MEDIA_NAME, stream_name); PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", device->sample_frames, device->spec.freq); PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", device->spec.freq); PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true"); @@ -1279,6 +1302,8 @@ static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) return SDL_SetError("Pipewire: Stream error: %s", error); } + SDL_AddHintCallback(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, PIPEWIRE_StreamNameChanged, device); + return true; } @@ -1288,6 +1313,8 @@ static void PIPEWIRE_CloseDevice(SDL_AudioDevice *device) return; } + SDL_RemoveHintCallback(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, PIPEWIRE_StreamNameChanged, device); + if (device->hidden->loop) { PIPEWIRE_pw_thread_loop_stop(device->hidden->loop); } From 299ed51984c54c269e22ba130e884796fcc75b86 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 23 Mar 2026 15:04:22 -0700 Subject: [PATCH 019/407] Added an internal hint to set OpenVR overlay flags --- src/video/openvr/SDL_openvrvideo.c | 42 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/video/openvr/SDL_openvrvideo.c b/src/video/openvr/SDL_openvrvideo.c index 24e31f37ee..545e11b5fc 100644 --- a/src/video/openvr/SDL_openvrvideo.c +++ b/src/video/openvr/SDL_openvrvideo.c @@ -568,7 +568,7 @@ static bool OPENVR_SetupJoystickBasedOnLoadedActionManifest(SDL_VideoData * vide return true; } -static bool OPENVR_InitializeOverlay(SDL_VideoDevice *_this,SDL_Window *window) +static bool OPENVR_InitializeOverlay(SDL_VideoDevice *_this, SDL_Window *window) { SDL_VideoData *videodata = (SDL_VideoData *)_this->internal; @@ -610,6 +610,32 @@ static bool OPENVR_InitializeOverlay(SDL_VideoDevice *_this,SDL_Window *window) SDL_free(cursorname); videodata->bHasShownOverlay = false; } + { + Uint32 overlay_flags = 0; + + const char *hint = SDL_GetHint("SDL_OPENVR_OVERLAY_FLAGS"); + if (hint && *hint) { + overlay_flags = SDL_atoi(hint); + } else { + overlay_flags |= (1 << 23); //vr::VROverlayFlags_EnableControlBar + overlay_flags |= (1 << 24); //vr::VROverlayFlags_EnableControlBarKeyboard + overlay_flags |= (1 << 25); //vr::VROverlayFlags_EnableControlBarClose +#if 0 + /* OpenVR overlays assume unpremultiplied alpha by default, set this flag to tag the source buffer as premultiplied. + * Note that (as of 2025) OpenVR overlay composition is higher quality when premultiplied buffers are provided, + * as texture samplers that blend energy (such as bilinear) do not yield sensical results when operating on natively + * unpremultiplied textures. It is thus preferable to hand openvr natively premultiplied buffers when accurate + * sampling / composition is required. */ + overlay_flags |= (1 << 21); // vr::VROverlayFlags_IsPremultiplied +#endif + } + + for (int i = 0; i < sizeof(overlay_flags) * 8; ++i) { + if (overlay_flags & (1 << i)) { + videodata->oOverlay->SetOverlayFlag(videodata->overlayID, (VROverlayFlags)(1 << i), true); + } + } + } { const char * hint = SDL_GetHint("SDL_OPENVR_OVERLAY_PANEL_WIDTH"); float fWidth = hint ? (float)SDL_atof(hint) : 1.0f; @@ -629,7 +655,7 @@ static bool OPENVR_InitializeOverlay(SDL_VideoDevice *_this,SDL_Window *window) EVROverlayError err = videodata->oOverlay->SetOverlayFromFile(videodata->thumbID, tmpcopy); SDL_free(tmpcopy); if (err == EVROverlayError_VROverlayError_None) { - videodata->bIconOverridden = SDL_GetHintBoolean("SDL_OPENVR_WINDOW_ICON_OVERRIDE",false); + videodata->bIconOverridden = SDL_GetHintBoolean("SDL_OPENVR_WINDOW_ICON_OVERRIDE", false); } } } @@ -646,22 +672,10 @@ static bool OPENVR_InitializeOverlay(SDL_VideoDevice *_this,SDL_Window *window) return false; } - global_openvr_driver = videodata; InitializeMouseFunctions(); // Actually show the overlay. - videodata->oOverlay->SetOverlayFlag(videodata->overlayID, 1<<23, true); //vr::VROverlayFlags_EnableControlBar - videodata->oOverlay->SetOverlayFlag(videodata->overlayID, 1<<24, true); //vr::VROverlayFlags_EnableControlBarKeyboard - videodata->oOverlay->SetOverlayFlag(videodata->overlayID, 1<<25, true); //vr::VROverlayFlags_EnableControlBarClose -#if 0 - /* OpenVR overlays assume unpremultiplied alpha by default, set this flag to tag the source buffer as premultiplied. - * Note that (as of 2025) OpenVR overlay composition is higher quality when premultiplied buffers are provided, - * as texture samplers that blend energy (such as bilinear) do not yield sensical results when operating on natively - * unpremultiplied textures. It is thus preferable to hand openvr natively premultiplied buffers when accurate - * sampling / composition is required. */ - videodata->oOverlay->SetOverlayFlag(videodata->overlayID, VROverlayFlags_IsPremultiplied, true ); -#endif videodata->oOverlay->SetOverlayName(videodata->overlayID, window->title); videodata->bDidCreateOverlay = true; From 998159fa954993693774449df5c129cb415461d4 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Tue, 24 Mar 2026 13:30:23 +0100 Subject: [PATCH 020/407] video: add more direct mjpeg to yuv conversions --- src/video/SDL_stb.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/video/SDL_stb.c b/src/video/SDL_stb.c index 78e89c7359..732b4ef016 100644 --- a/src/video/SDL_stb.c +++ b/src/video/SDL_stb.c @@ -22,6 +22,7 @@ #include "SDL_stb_c.h" #include "SDL_surface_c.h" +#include "SDL_yuv_c.h" /* STB image conversion */ #ifndef SDL_DISABLE_STB @@ -114,8 +115,37 @@ bool SDL_ConvertPixels_STB(int width, int height, SDL_PixelFormat dst_format, SDL_Colorspace dst_colorspace, SDL_PropertiesID dst_properties, void *dst, int dst_pitch) { #ifdef SDL_HAVE_STB - if (src_format == SDL_PIXELFORMAT_MJPG && dst_format == SDL_PIXELFORMAT_NV12) { - return SDL_ConvertPixels_MJPG_to_NV12(width, height, src, src_pitch, dst, dst_pitch); + if (src_format == SDL_PIXELFORMAT_MJPG) { + if (dst_format == SDL_PIXELFORMAT_NV12) { + return SDL_ConvertPixels_MJPG_to_NV12(width, height, src, src_pitch, dst, dst_pitch); + } else if ( + dst_format == SDL_PIXELFORMAT_YV12 || + dst_format == SDL_PIXELFORMAT_IYUV || + dst_format == SDL_PIXELFORMAT_YUY2 || + dst_format == SDL_PIXELFORMAT_UYVY || + dst_format == SDL_PIXELFORMAT_YVYU || + dst_format == SDL_PIXELFORMAT_NV21 || + dst_format == SDL_PIXELFORMAT_P010 + ) { + size_t temp_size = 0; + size_t temp_pitch = 0; + if (!SDL_CalculateYUVSize(dst_format, width, height, &temp_size, &temp_pitch)) { + return false; + } + void *temp_pixels = SDL_malloc(temp_size); + if (!temp_pixels) { + return false; + } + + if (!SDL_ConvertPixels_MJPG_to_NV12(width, height, src, src_pitch, temp_pixels, (int)temp_pitch)) { + SDL_free(temp_pixels); + return false; + } + + bool result = SDL_ConvertPixelsAndColorspace(width, height, SDL_PIXELFORMAT_NV12, src_colorspace, 0 /*props*/, temp_pixels, (int)temp_pitch, dst_format, dst_colorspace, dst_properties, dst, dst_pitch); + SDL_free(temp_pixels); + return result; + } } bool result; From 989de77f4f7d8ec4e51c317371e9aeb502f48d51 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Mon, 23 Mar 2026 22:10:15 +0100 Subject: [PATCH 021/407] render: Skip UV check when software-rendering untextured quads Fixes a crash when calling SDL_RenderGeometryRaw() with both `texture` and `uv` set to `NULL`, and with geometry that is laid out in a way that passes the quad checks. --- src/render/SDL_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index e54ff39821..fb14aa52af 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -5163,7 +5163,7 @@ static bool SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer, } // Check if UVs within range - if (is_quad) { + if (is_quad && uv) { const float *uv0_ = (const float *)((const char *)uv + A * color_stride); const float *uv1_ = (const float *)((const char *)uv + B * color_stride); const float *uv2_ = (const float *)((const char *)uv + C * color_stride); From 8eeef53a80228ce0e4bbb6b3f9c6a52cedd0ad8b Mon Sep 17 00:00:00 2001 From: c4veman <64951438+c4veman@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:53:36 +0000 Subject: [PATCH 022/407] Fix endmacro syntax in macros.cmake --- cmake/macros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/macros.cmake b/cmake/macros.cmake index a375649063..e64f0b4d39 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -21,7 +21,7 @@ macro(option_string _NAME _DESC _VALUE) add_to_alloptions(${_NAME}) set(${_NAME} ${_VALUE} CACHE STRING "${_DESC}") set(HAVE_${_NAME} ${_VALUE}) -ENDMACRO() +endmacro() macro(message_bool_option _NAME _VALUE) set(_PAD "\t") From be6f1efa26d9104b679ec8e112e15898d48c21f0 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 25 Mar 2026 18:37:01 +0100 Subject: [PATCH 023/407] ci: clang-tools-extra is no longer available for mingw32 mingw32 and mingw64 are in the process of being deprecated --- .github/workflows/create-test-plan.py | 25 +++++++++++++++++-------- .github/workflows/generic.yml | 10 +--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index 6173610ee3..4ce15489b7 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -212,8 +212,7 @@ class JobDetails: minidump: bool = False intel: bool = False msys2_msystem: str = "" - msys2_env: str = "" - msys2_no_perl: bool = False + msys2_packages: list[str] = dataclasses.field(default_factory=list) werror: bool = True msvc_vcvars_arch: str = "" msvc_vcvars_sdk: str = "" @@ -248,8 +247,7 @@ class JobDetails: "enable-artifacts": enable_artifacts, "shell": self.shell, "msys2-msystem": self.msys2_msystem, - "msys2-env": self.msys2_env, - "msys2-no-perl": self.msys2_no_perl, + "msys2-packages": my_shlex_join(self.msys2_packages), "android-ndk": self.android_ndk, "java": self.java, "intel": self.intel, @@ -739,15 +737,26 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta job.shell = "msys2 {0}" assert spec.msys2_platform job.msys2_msystem = spec.msys2_platform.value - job.msys2_env = { + job.shared_lib = SharedLibType.WIN32 + job.static_lib = StaticLibType.A + msys2_env = { "mingw32": "mingw-w64-i686", "mingw64": "mingw-w64-x86_64", "clang64": "mingw-w64-clang-x86_64", "ucrt64": "mingw-w64-ucrt-x86_64", }[spec.msys2_platform.value] - job.msys2_no_perl = spec.msys2_platform in (Msys2Platform.Mingw32, ) - job.shared_lib = SharedLibType.WIN32 - job.static_lib = StaticLibType.A + job.msys2_packages.extend([ + f"{msys2_env}-cc", + f"{msys2_env}-cmake", + f"{msys2_env}-ffmpeg", + f"{msys2_env}-ninja", + f"{msys2_env}-pkg-config", + ]) + if spec.msys2_platform not in (Msys2Platform.Mingw32, ): + job.msys2_packages.append(f"{msys2_env}-perl") + job.msys2_packages.append(f"{msys2_env}-clang-tools-extra") + if job.ccache: + job.msys2_packages.append(f"{msys2_env}-ccache") case SdlPlatform.Riscos: job.ccache = False # FIXME: enable when container gets upgrade # FIXME: Enable SDL_WERROR diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index f38a903c90..19cf4910ee 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -27,15 +27,7 @@ jobs: uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.platform.msys2-msystem }} - install: >- - ${{ matrix.platform.msys2-env }}-cc - ${{ matrix.platform.msys2-env }}-cmake - ${{ matrix.platform.msys2-env }}-ffmpeg - ${{ matrix.platform.msys2-env }}-ninja - ${{ (!matrix.platform.msys2-no-perl && format('{0}-perl', matrix.platform.msys2-env)) || '' }} - ${{ matrix.platform.msys2-env }}-pkg-config - ${{ matrix.platform.msys2-env }}-clang-tools-extra - ${{ (matrix.platform.ccache && format('{0}-ccache', matrix.platform.msys2-env)) || '' }} + install: ${{ matrix.platform.msys2-packages }} - name: 'About this job' run: | echo "key=${{ matrix.platform.key }}" From dcc177faa42c8c325ab5003d214fd1f3576e7a19 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 25 Mar 2026 09:58:41 -0400 Subject: [PATCH 024/407] emscripten: Add support for automounting persistent storage before SDL_main. Now apps can have persistent files available during SDL_main()/SDL_AppInit() and don't have to mess with Emscripten-specific code to prepare the filesystem for use. --- CMakeLists.txt | 10 ++++ docs/README-emscripten.md | 58 +++++++++++++++++++ include/build_config/SDL_build_config.h.cmake | 2 + src/filesystem/emscripten/SDL_sysfilesystem.c | 12 ++-- src/main/emscripten/SDL_sysmain_runapp.c | 30 +++++++++- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a0aec0083..d8afc5d4a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -393,6 +393,10 @@ set_option(SDL_CCACHE "Use Ccache to speed up build" OFF) set_option(SDL_CLANG_TIDY "Run clang-tidy static analysis" OFF) dep_option(SDL_GPU_OPENXR "Build SDL_GPU with OpenXR support" ON "SDL_GPU;NOT RISCOS" OFF) +if(EMSCRIPTEN) + option_string(SDL_EMSCRIPTEN_PERSISTENT_PATH "Path to mount Emscripten IDBFS at startup or '' to disable" "") +endif() + set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION") if(DEFINED CACHE{SDL_SHARED} OR DEFINED CACHE{SDL_STATIC}) @@ -1668,6 +1672,11 @@ elseif(EMSCRIPTEN) # project. Uncomment at will for verbose cross-compiling -I/../ path info. sdl_compile_options(PRIVATE "-Wno-warn-absolute-paths") + if(NOT SDL_EMSCRIPTEN_PERSISTENT_PATH STREQUAL "") + set(SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING "${SDL_EMSCRIPTEN_PERSISTENT_PATH}") + sdl_link_dependency(idbfs LIBS idbfs.js) + endif() + sdl_glob_sources( "${SDL3_SOURCE_DIR}/src/main/emscripten/*.c" "${SDL3_SOURCE_DIR}/src/main/emscripten/*.h" @@ -4001,6 +4010,7 @@ if(SDL_SHARED) ) endif() endif() + target_link_libraries(SDL3-shared PRIVATE ${SDL_CMAKE_DEPENDS}) target_include_directories(SDL3-shared PRIVATE diff --git a/docs/README-emscripten.md b/docs/README-emscripten.md index 2663cdaebb..6a373b21ba 100644 --- a/docs/README-emscripten.md +++ b/docs/README-emscripten.md @@ -346,6 +346,64 @@ all has to live in memory at runtime. [Emscripten's documentation on the matter](https://emscripten.org/docs/porting/files/packaging_files.html) gives other options and details, and is worth a read. +Please also read the next section on persistent storage, for a little help +from SDL. + + +## Automount persistent storage + +The file tree in Emscripten is provided by MEMFS by default, which stores all +files in RAM. This is often what you want, because it's fast and can be +accessed with the usual synchronous i/o functions like fopen or SDL_IOFromFile. +You can also write files to MEMFS, but when the browser tab goes away, so do +the files. But we want things like high scores, save games, etc, to still +exist if we reload the game later. + +For this, Emscripten offers IDBFS, which backs files with the browser's +[IndexedDB](https://en.wikipedia.org/wiki/IndexedDB) functionality. + +To use this, the app has to mount the IDBFS filesystem somewhere in the +virtual file tree, and then wait for it to sync up. This needs to be done in +Javascript code. The sync will not complete until at least one (but possibly +several) iterations of the mainloop have passed, which means you can not +access any saved files during main() or SDL_AppInit() by default. + +SDL can solve this problem for you: it can be built to automatically mount the +persistent files from IDBFS to a specific place in the file tree and wait +until the sync has completed before calling main() or SDL_AppInit(), so to +your C code, it looks like the files were always available. + +To use this functionality, set the CMake variable +`SDL_EMSCRIPTEN_PERSISTENT_PATH` to a path in the filetree where persistent +storage should be mounted: + +```bash +mkdir build +cd build +emcmake cmake -DSDL_EMSCRIPTEN_PERSISTENT_PATH=/storage .. +``` + +You should also link your app with `-lidbfs.js`. If your project links to SDL +using CMake's find_package(SDL3), or uses `pkg-config sdl3 --libs`, this will +be handled for you when used with an SDL built with +`-DSDL_EMSCRIPTEN_PERSISTENT_PATH`. + +Now `/storage` will be prepared when your program runs, and SDL_GetPrefPath() +will return a directory under that path. The storage is mounted with the +`autoPersist: true` option, so when you write to that tree, whether with +SDL APIs or other functions like fopen(), Emscripten will know it needs to +sync that data back to the persistent database, and will do so automatically +within the next few iterations of the mainloop. + +It's best to assume the sync will take a few frames to complete, and the +data is not safe until it does. + +To summarize how to automate this: + +- Build with `emcmake cmake -DSDL_EMSCRIPTEN_PERSISTENT_PATH=/storage` +- Link your app with `-lidbfs.js` if not handled automatically. +- Write under `/storage`, or use SDL_GetPrefPath() + ## Customizing index.html diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 3350723aa2..267e941c4f 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -574,6 +574,8 @@ #cmakedefine SDL_VIDEO_VITA_PVR 1 #cmakedefine SDL_VIDEO_VITA_PVR_OGL 1 +#cmakedefine SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING "@SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING@" + /* xkbcommon version info */ #define SDL_XKBCOMMON_VERSION_MAJOR @SDL_XKBCOMMON_VERSION_MAJOR@ #define SDL_XKBCOMMON_VERSION_MINOR @SDL_XKBCOMMON_VERSION_MINOR@ diff --git a/src/filesystem/emscripten/SDL_sysfilesystem.c b/src/filesystem/emscripten/SDL_sysfilesystem.c index 13427fcdab..0d21cd2698 100644 --- a/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -39,19 +39,23 @@ char *SDL_SYS_GetBasePath(void) char *SDL_SYS_GetPrefPath(const char *org, const char *app) { - const char *append = "/libsdl/"; + #ifdef SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING + const char *append = SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING; + #else + const char *append = "/libsdl"; + #endif char *result; char *ptr = NULL; - const size_t len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3; + const size_t len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 4; result = (char *)SDL_malloc(len); if (!result) { return NULL; } if (*org) { - SDL_snprintf(result, len, "%s%s/%s/", append, org, app); + SDL_snprintf(result, len, "%s/%s/%s/", append, org, app); } else { - SDL_snprintf(result, len, "%s%s/", append, app); + SDL_snprintf(result, len, "%s/%s/", append, app); } for (ptr = result + 1; *ptr; ptr++) { diff --git a/src/main/emscripten/SDL_sysmain_runapp.c b/src/main/emscripten/SDL_sysmain_runapp.c index 0564240ac8..5671c96ed9 100644 --- a/src/main/emscripten/SDL_sysmain_runapp.c +++ b/src/main/emscripten/SDL_sysmain_runapp.c @@ -28,6 +28,11 @@ EM_JS_DEPS(sdlrunapp, "$dynCall,$stringToNewUTF8"); +EMSCRIPTEN_KEEPALIVE int CallSDLEmscriptenMainFunction(int argc, char *argv[], SDL_main_func mainFunction) +{ + return SDL_CallMainFunction(argc, argv, mainFunction); +} + int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserved) { (void)reserved; @@ -52,7 +57,30 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserv } }, SDL_setenv_unsafe); - return SDL_CallMainFunction(argc, argv, mainFunction); + #ifdef SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING + MAIN_THREAD_EM_ASM({ + const persistent_path = UTF8ToString($0); + const argc = $1; + const argv = $2; + const mainFunction = $3; + //console.log("SDL is automounting persistent storage to '" + persistent_path + "' ...please wait."); + FS.mkdirTree(persistent_path); + FS.mount(IDBFS, { autoPersist: true }, persistent_path); + FS.syncfs(true, function(err) { + if (err) { + console.error(`WARNING: Failed to populate persistent store at '${persistent_path}' (${err.name}: ${err.message}). Save games likely lost?`); + } + _CallSDLEmscriptenMainFunction(argc, argv, mainFunction); // error or not, start the actual SDL_main(). + }); + }, SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING, argc, argv, mainFunction); + + // we need to stop running code until FS.syncfs() finishes, but we need the runtime to not clean up. + // The actual SDL_main/SDL_AppInit() will be called when the sync is done and things will pick back up where they were. + emscripten_exit_with_live_runtime(); + return 0; + #else + return CallSDLEmscriptenMainFunction(argc, argv, mainFunction); + #endif } #endif From 6efe0e19a7c9f41988615a84341038de34af674e Mon Sep 17 00:00:00 2001 From: Clownacy Date: Wed, 25 Mar 2026 20:14:03 +0000 Subject: [PATCH 025/407] Fix DirectSound buffer creation failure with >200kHz Caps the sample rate at 200kHz so that SDL's mixer will downsample any streams which are higher than that. My Mega Drive emulator outputs at 223721Hz (the sample rate of the PSG chip), and `SDL_OpenAudioDeviceStream` fails due to DirectSound's `CreateSoundBuffer` returning an 'invalid parameter' error code. Lowering the sample rate makes the error go away. Reported to me by @B3HKO in this issue: https://github.com/Clownacy/clownmdemu-frontend/issues/60 The 200kHz limit is documented here: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee419022(v=vs.85) DirectSound's Wikipedia article mentions that problems may occur with sample rates above 192kHz, but no source is provided, so I am unsure whether to take it seriously. --- src/audio/directsound/SDL_directsound.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c index 3a097a3c4b..445d14a716 100644 --- a/src/audio/directsound/SDL_directsound.c +++ b/src/audio/directsound/SDL_directsound.c @@ -545,6 +545,7 @@ static bool DSOUND_OpenDevice(SDL_AudioDevice *device) tried_format = true; device->spec.format = test_format; + device->spec.freq = SDL_min(200000, device->spec.freq); // DirectSound has an arbitrary limit of 200,000Hz. // Update the fragment size as size in bytes SDL_UpdatedAudioDeviceFormat(device); From 1d2f9f0e0e1745b5a1122469155ac0ead1907e67 Mon Sep 17 00:00:00 2001 From: Regan Green Date: Wed, 25 Mar 2026 20:02:34 -0400 Subject: [PATCH 026/407] Use DSBFREQUENCY_MAX instead of hardcoded constant for DirectSound driver max frequency. --- src/audio/directsound/SDL_directsound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c index 445d14a716..89480ee49d 100644 --- a/src/audio/directsound/SDL_directsound.c +++ b/src/audio/directsound/SDL_directsound.c @@ -545,7 +545,7 @@ static bool DSOUND_OpenDevice(SDL_AudioDevice *device) tried_format = true; device->spec.format = test_format; - device->spec.freq = SDL_min(200000, device->spec.freq); // DirectSound has an arbitrary limit of 200,000Hz. + device->spec.freq = SDL_min(DSBFREQUENCY_MAX, device->spec.freq); // Update the fragment size as size in bytes SDL_UpdatedAudioDeviceFormat(device); From 53c799a7a9790bbf31f781cffffacef4f6bd5fa3 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Thu, 26 Mar 2026 13:22:30 +0100 Subject: [PATCH 027/407] SDL_SetWindowShape(): Remove shape when argument is NULL --- src/video/SDL_video.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 588f61d18f..6cb30d83a8 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -6147,9 +6147,13 @@ bool SDL_SetWindowShape(SDL_Window *window, SDL_Surface *shape) return false; } - surface = SDL_ConvertSurface(shape, SDL_PIXELFORMAT_ARGB32); - if (!surface) { - return false; + if (shape) { + surface = SDL_ConvertSurface(shape, SDL_PIXELFORMAT_ARGB32); + if (!surface) { + return false; + } + } else { + surface = NULL; } if (!SDL_SetSurfaceProperty(props, SDL_PROP_WINDOW_SHAPE_POINTER, surface)) { From 159bba9aa1d3ec8ad92ed15d99dc248304f06e48 Mon Sep 17 00:00:00 2001 From: c4veman <64951438+c4veman@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:12:37 +0000 Subject: [PATCH 028/407] Check Windows version before setting window attributes --- src/video/windows/SDL_windowswindow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 367c810f3a..506fdc1ae5 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -1227,7 +1227,7 @@ static void WIN_UpdateCornerRoundingForHWND(SDL_VideoDevice *_this, HWND hwnd, D { #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) SDL_VideoData *videodata = _this->internal; - if (videodata->DwmSetWindowAttribute) { + if (videodata->DwmSetWindowAttribute && WIN_IsWindows11OrGreater()) { videodata->DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref)); } #endif @@ -1237,7 +1237,7 @@ static void WIN_UpdateBorderColorForHWND(SDL_VideoDevice *_this, HWND hwnd, COLO { #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) SDL_VideoData *videodata = _this->internal; - if (videodata->DwmSetWindowAttribute) { + if (videodata->DwmSetWindowAttribute && WIN_IsWindows11OrGreater()) { videodata->DwmSetWindowAttribute(hwnd, DWMWA_BORDER_COLOR, &colorRef, sizeof(colorRef)); } #endif From 6a9449c0986553a4cfc997198a3deaf02dd67c85 Mon Sep 17 00:00:00 2001 From: Strultz <69481716+Strultz@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:14:19 -0500 Subject: [PATCH 029/407] Fix window caption drawing on borderless windows (#15275) --- src/video/windows/SDL_windowsevents.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 19f49e9b36..0f32f9733a 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -61,6 +61,14 @@ // #define HIGHDPI_DEBUG +// Undocumented window messages +#ifndef WM_NCUAHDRAWCAPTION +#define WM_NCUAHDRAWCAPTION 0xAE +#endif +#ifndef WM_NCUAHDRAWFRAME +#define WM_NCUAHDRAWFRAME 0xAF +#endif + // Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... #ifndef WM_XBUTTONDOWN #define WM_XBUTTONDOWN 0x020B @@ -1214,6 +1222,24 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara actually being the foreground window, but this appears to get called in all cases where the global foreground window changes to and from this window. */ WIN_UpdateFocus(data->window, !!wParam, GetMessagePos()); + + /* Handle borderless windows; this event is intended for drawing the titlebar, so we need + to stop that from happening. */ + if (data->window->flags & SDL_WINDOW_BORDERLESS) { + lParam = -1; // According to MSDN, DefWindowProc will draw a title bar if lParam != -1 + } + } break; + + case WM_NCUAHDRAWCAPTION: + case WM_NCUAHDRAWFRAME: + { + /* These messages are undocumented. They are responsible for redrawing the window frame and + caption. Notably, WM_NCUAHDRAWCAPTION is sent when calling SetWindowText on a window. + For borderless windows, we don't want to draw a frame or caption, so we should stop + that from happening. */ + if (data->window->flags & SDL_WINDOW_BORDERLESS) { + returnCode = 0; + } } break; case WM_ACTIVATE: From 122ad3d6f600229dbb4f52883a907699cd3a1acd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 27 Mar 2026 05:45:36 -0700 Subject: [PATCH 030/407] Added SDL_IsPhone() --- include/SDL3/SDL_system.h | 13 +++++++++++++ src/SDL.c | 11 +++++++++++ src/dynapi/SDL_dynapi.sym | 1 + src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + 5 files changed, 27 insertions(+) diff --git a/include/SDL3/SDL_system.h b/include/SDL3/SDL_system.h index 18ad26a94c..3353bb7741 100644 --- a/include/SDL3/SDL_system.h +++ b/include/SDL3/SDL_system.h @@ -616,6 +616,19 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SendAndroidMessage(Uint32 command, int para #endif /* SDL_PLATFORM_ANDROID */ +/** + * Query if the current device is a phone. + * + * If SDL can't determine this, it will return false. + * + * \returns true if the device is a phone, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.6.0. + */ +extern SDL_DECLSPEC bool SDLCALL SDL_IsPhone(void); + /** * Query if the current device is a tablet. * diff --git a/src/SDL.c b/src/SDL.c index b1a1a56354..cd7ec4b656 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -828,6 +828,17 @@ const char *SDL_GetPlatform(void) #endif } +bool SDL_IsPhone(void) +{ +#if defined(SDL_PLATFORM_ANDROID) || \ + (defined(SDL_PLATFORM_IOS) && !defined(SDL_PLATFORM_VISIONOS)) + if (!SDL_IsTablet() && !SDL_IsTV()) { + return true; + } +#endif + return false; +} + bool SDL_IsTablet(void) { #ifdef SDL_PLATFORM_ANDROID diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index ef10030d26..a16d0f79c3 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1285,6 +1285,7 @@ SDL3_0.0.0 { SDL_SetGPURenderStateStorageBuffers; SDL_GDKSuspendRenderer; SDL_GDKResumeRenderer; + SDL_IsPhone; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 410917721d..c60b5223d4 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1311,3 +1311,4 @@ #define SDL_SetGPURenderStateStorageBuffers SDL_SetGPURenderStateStorageBuffers_REAL #define SDL_GDKSuspendRenderer SDL_GDKSuspendRenderer_REAL #define SDL_GDKResumeRenderer SDL_GDKResumeRenderer_REAL +#define SDL_IsPhone SDL_IsPhone_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 175f2fd4da..203d9726c8 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1319,3 +1319,4 @@ SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageTextures,(SDL_GPURenderState *a SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageBuffers,(SDL_GPURenderState *a,int b,SDL_GPUBuffer *const*c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_GDKSuspendRenderer,(SDL_Renderer *a),(a),) SDL_DYNAPI_PROC(void,SDL_GDKResumeRenderer,(SDL_Renderer *a),(a),) +SDL_DYNAPI_PROC(bool,SDL_IsPhone,(void),(),return) From 995d4e10a6f49f33b3e09a6027e8c9cdab0b952c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 27 Mar 2026 08:43:30 -0700 Subject: [PATCH 031/407] Added documentation for getting the full resolution in iOS --- docs/README-ios.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/README-ios.md b/docs/README-ios.md index e07de24900..54cd9ed222 100644 --- a/docs/README-ios.md +++ b/docs/README-ios.md @@ -103,6 +103,19 @@ matrix using the size in points (SDL_GetWindowSize()) can be used in order to display content at the same scale no matter whether a Retina device is used or not. +Notes -- Getting full screen resolution +============================================================================== + +Make sure that you have a Launch Screen key in your Info.plist, e.g. +``` + UILaunchScreen + +``` +If you don't specify a launch screen, then the OS will assume that your +application needs an older compatibility mode and will get a limited +resolution screen. + + Notes -- Application events ============================================================================== From 1df279a04f604bc50b6f36c9e903b5e64c4fe2a3 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Thu, 26 Mar 2026 14:51:20 -0400 Subject: [PATCH 032/407] x11: Look for text/uri-list in the list of MIME types more thoroughly A uri-list of files is the preferred format, so don't bail if a preferred text format is encountered first. --- src/video/x11/SDL_x11events.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 22fd0f1d12..6bfb914273 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -122,15 +122,19 @@ static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) if available, else return None */ static Atom X11_PickTarget(Display *disp, Atom list[], int list_count) { + const Atom text_uri_request = X11_XInternAtom(disp, "text/uri-list", False); Atom request = None; - char *name; - int i; - for (i = 0; i < list_count && request == None; i++) { - name = X11_XGetAtomName(disp, list[i]); + Atom preferred = None; + + for (int i = 0; i < list_count && request != text_uri_request; i++) { + char *name = X11_XGetAtomName(disp, list[i]); // Preferred MIME targets if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain;charset=utf-8", name) == 0) || (SDL_strcmp("UTF8_STRING", name) == 0)) { + if (preferred == None) { + preferred = list[i]; + } request = list[i]; } // Fallback MIME targets @@ -142,6 +146,11 @@ static Atom X11_PickTarget(Display *disp, Atom list[], int list_count) } X11_XFree(name); } + + // The type 'text/uri-list' is preferred over all others. + if (preferred != None && request != text_uri_request) { + request = preferred; + } return request; } From a157d96de87fce84f06e60f4049dd96b8a6993e3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 28 Mar 2026 11:18:03 -0400 Subject: [PATCH 033/407] stdlib: Patched SDL_rand_f to compile on pre-C99 compilers. Visual Studio _still_ doesn't report itself as C99 compatible, afaict, but does support the syntax as of VS2017 15.6, apparently. This page mentions the first version of Visual Studio that handles hexidecimal float notation: https://stackoverflow.com/questions/18180116/vc-rejecting-hexadecimal-floating-point-constant?utm_source=chatgpt.com If not Visual Studio, we also take the messier path for things that don't report themselves as C99. Most things will take the cleaner path, though. Closes #15276. --- src/stdlib/SDL_random.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/stdlib/SDL_random.c b/src/stdlib/SDL_random.c index f1c6f99861..747d85413f 100644 --- a/src/stdlib/SDL_random.c +++ b/src/stdlib/SDL_random.c @@ -110,6 +110,12 @@ Sint32 SDL_rand_r(Uint64 *state, Sint32 n) float SDL_randf_r(Uint64 *state) { // Note: its using 24 bits because float has 23 bits significand + 1 implicit bit +#if (defined(_MSC_VER) && (_MSC_VER < 1913)) || (!defined(_MSC_VER) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L))) + // no hexidecimal float notation, do it the hard way. MSVC before 15.6 (2017), etc, needs this. + const union { Uint32 u32; float f; } float_union = { 0x33800000U }; + return (SDL_rand_bits_r(state) >> (32 - 24)) * float_union.f; +#else return (SDL_rand_bits_r(state) >> (32 - 24)) * 0x1p-24f; +#endif } From 815fd4bf450fc97363c6a38b7443e18173e73b1f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 28 Mar 2026 22:22:25 -0700 Subject: [PATCH 034/407] Removed spurious whitespace --- .../main/java/org/libsdl/app/HIDDeviceBLESteamController.java | 2 +- .../app/src/main/java/org/libsdl/app/SDLActivity.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java index 97b4c127f4..e3dc36cc7d 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java @@ -682,7 +682,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe if (getProductId() == D0G_BLE2_PID) { //Log.v(TAG, "writeOutputReport " + HexDump.dumpHexString(report)); writeCharacteristic(reportCharacteristic, report); - return report.length; + return report.length; } // If we're a Triton, we need to find the correct report characteristic. diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index dcc61d8729..9eb003da23 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -1963,7 +1963,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); - int flags = Intent.FLAG_ACTIVITY_NO_HISTORY + int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT; i.addFlags(flags); From a54dd7ba457fc6780ff460dc4eccccb5df4b3890 Mon Sep 17 00:00:00 2001 From: Semphris Date: Wed, 11 Mar 2026 17:57:08 -0400 Subject: [PATCH 035/407] Fix Windows file dialog calling the callback twice If the modern implementation of file dialogs on Windows fails, it will invoke the callback on error and report an error, then SDL would attempt invoking the dialog again using an older implementation, which would call the callback again. This is not desired behavior, so it has been changed as follows: - If the modern dialog fails before showing (missing library/symbol), don't call the callback and try the older dialogs in case we're on an old platform. - If the dialog fails while or after showing, assume the error is a normal invocation error (such as an invalid path), call the callback and don't show the older dialogs to prevent showing two dialogs in succession to the user. --- src/dialog/windows/SDL_windowsdialog.c | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/dialog/windows/SDL_windowsdialog.c b/src/dialog/windows/SDL_windowsdialog.c index 631fff5c18..400fcf03ad 100644 --- a/src/dialog/windows/SDL_windowsdialog.c +++ b/src/dialog/windows/SDL_windowsdialog.c @@ -456,6 +456,9 @@ char *clear_filt_names(const char *filt) return cleared; } +// This function returns NOT success or error, but rather whether the callback +// was invoked or not (and if it was, no fallback should be attempted to prevent +// calling the callback twice). See https://github.com/libsdl-org/SDL/issues/15194 bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const char *default_file, SDL_Window *parent, bool allow_many, SDL_DialogFileCallback callback, void *userdata, const char *title, const char *accept, const char *cancel, wchar_t *filter_wchar, int nfilters) { bool is_save = dialog_type == SDL_FILEDIALOG_SAVEFILE; @@ -488,7 +491,8 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch wchar_t *default_file_w = NULL; wchar_t *default_folder_w = NULL; - bool success = false; + bool callback_called = false; + bool call_callback_on_error = false; bool co_init = false; // We can assume shell32 is already loaded here. @@ -604,6 +608,10 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch CHECK(pFileDialog->lpVtbl->SetFileName(pFileDialog, default_file_w)); } + // Right after this, a dialog is shown. No fallback should be attempted on + // error to prevent showing two dialogs to the user. + call_callback_on_error = true; + if (parent) { HWND window = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(parent), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); @@ -616,7 +624,7 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch // This is a one-based index, not zero-based. Doc link in similar comment below CHECK(pFileDialog->lpVtbl->GetFileTypeIndex(pFileDialog, &selected_filter)); callback(userdata, results, selected_filter - 1); - success = true; + callback_called = true; goto quit; } else if (!SUCCEEDED(hr)) { goto quit; @@ -631,7 +639,7 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch // This is a one-based index, not zero-based. Doc link in similar comment below CHECK(pFileDialog->lpVtbl->GetFileTypeIndex(pFileDialog, &selected_filter)); callback(userdata, results, selected_filter - 1); - success = true; + callback_called = true; goto quit; } else if (!SUCCEEDED(hr)) { goto quit; @@ -665,7 +673,7 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch } callback(userdata, (const char * const *) files, selected_filter - 1); - success = true; + callback_called = true; } else { // This is a one-based index, not zero-based. // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-getfiletypeindex#parameters @@ -681,18 +689,17 @@ bool windows_ShowModernFileFolderDialog(SDL_FileDialogType dialog_type, const ch } const char * const results[] = { file, NULL }; callback(userdata, results, selected_filter - 1); - success = true; + callback_called = true; SDL_free(file); } - success = true; - #undef CHECK quit: - if (!success) { - WIN_SetError("dialogg"); + if (!callback_called && call_callback_on_error) { + WIN_SetError("dialog"); callback(userdata, NULL, -1); + callback_called = true; } if (co_init) { @@ -750,7 +757,7 @@ quit: SDL_free(files); } - return success; + return callback_called; } // TODO: The new version of file dialogs From e66f1b516255a1efe2b85634e1fcc7d5def965ff Mon Sep 17 00:00:00 2001 From: zn-arf <4260168+zn-arf@users.noreply.github.com> Date: Sun, 29 Mar 2026 17:01:48 +0200 Subject: [PATCH 036/407] Fix Metal GPU backend not being included in CMake configuration Fixes #15285 Missing Metal GPU block in CMakeLists.txt prevents `HAVE_SDL_GPU` from being set when only Metal is enabled. --- CMakeLists.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8afc5d4a4..350d5c747e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2735,13 +2735,6 @@ elseif(APPLE) set(SDL_VIDEO_RENDER_METAL 1) set(HAVE_RENDER_METAL TRUE) endif() - if (SDL_GPU) - set(SDL_GPU_METAL 1) - sdl_glob_sources( - "${SDL3_SOURCE_DIR}/src/gpu/metal/*.m" - "${SDL3_SOURCE_DIR}/src/gpu/metal/*.h" - ) - endif() endif() endif() endif() @@ -3554,6 +3547,14 @@ if(SDL_GPU) set(SDL_GPU_VULKAN 1) set(HAVE_SDL_GPU TRUE) endif() + if(SDL_VIDEO_METAL) + sdl_glob_sources( + "${SDL3_SOURCE_DIR}/src/gpu/metal/*.m" + "${SDL3_SOURCE_DIR}/src/gpu/metal/*.h" + ) + set(SDL_GPU_METAL 1) + set(HAVE_SDL_GPU TRUE) + endif() if(SDL_RENDER_GPU AND HAVE_SDL_GPU) set(SDL_VIDEO_RENDER_GPU 1) set(HAVE_RENDER_GPU TRUE) From 0756603e6d88d4e453e9dbfba5fea10c15babee6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 30 Mar 2026 10:08:06 -0400 Subject: [PATCH 037/407] thread: SDL_CreateThread() shouldn't return before the new thread is set up. Fixes #15290. --- src/thread/SDL_thread.c | 14 ++++++++++++++ src/thread/SDL_thread_c.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 04b0573920..9ffba9592c 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -333,6 +333,8 @@ void SDL_RunThread(SDL_Thread *thread) // Get the thread id thread->threadid = SDL_GetCurrentThreadID(); + SDL_SignalSemaphore(thread->ready_sem); // the thread is officially ready to run! + // Run the function *statusloc = userfunc(userdata); @@ -389,6 +391,13 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props, } } + thread->ready_sem = SDL_CreateSemaphore(0); + if (!thread->ready_sem) { + SDL_free(thread->name); + SDL_free(thread); + return NULL; + } + thread->userfunc = fn; thread->userdata = userdata; thread->stacksize = stacksize; @@ -399,11 +408,16 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props, if (!SDL_SYS_CreateThread(thread, pfnBeginThread, pfnEndThread)) { // Oops, failed. Gotta free everything SDL_SetObjectValid(thread, SDL_OBJECT_TYPE_THREAD, false); + SDL_DestroySemaphore(thread->ready_sem); SDL_free(thread->name); SDL_free(thread); thread = NULL; } + SDL_WaitSemaphore(thread->ready_sem); + SDL_DestroySemaphore(thread->ready_sem); + thread->ready_sem = NULL; + // Everything is running now return thread; } diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 3659b85cc4..25b7096482 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -54,6 +54,7 @@ struct SDL_Thread SDL_error errbuf; char *name; size_t stacksize; // 0 for default, >0 for user-specified stack size. + SDL_Semaphore *ready_sem; // signals when the thread is set up and about to start running. int(SDLCALL *userfunc)(void *); void *userdata; void *data; From b878ab16910924ca93f0048e48a34f44dfb54357 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 30 Mar 2026 10:37:09 -0700 Subject: [PATCH 038/407] Fix msvc analyzer warnings - Initialize some out variables that are annotated inout in the function setting them. - Fix 'dwVerHandle' might not be '0' warning from msvc analyzer calling GetFileVersionInfoA. MSDN says that the lpdwHandle param to GetFileVersionInfoSize is optional (set to zero) and the dwHandle param to GetFileVersionInfoA is ignored. msvc goes a step further and explicitly warns if dwHandle is not provably 0. Fixes the following: SDL3\src\stdlib\SDL_string.c(2359): warning C6054: String 'text' might not be zero-terminated. SDL3\src\video\windows\SDL_windowsevents.c(897): warning C6001: Using uninitialized memory 'devName'. SDL3\src\video\windows\SDL_windowskeyboard.c(644): warning C6388: 'dwVerHandle' might not be '0': this does not adhere to the specification for the function 'GetFileVersionInfoA'. --- src/stdlib/SDL_string.c | 4 ++++ src/video/windows/SDL_windowsevents.c | 1 + src/video/windows/SDL_windowskeyboard.c | 5 ++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 7f43025fc9..4a870f6e0d 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -2358,6 +2358,10 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FO int SDL_vswprintf(SDL_OUT_Z_CAP(maxlen) wchar_t *text, size_t maxlen, const wchar_t *fmt, va_list ap) { + if (text) { + text[0] = 0; + } + char *fmt_utf8 = NULL; if (fmt) { fmt_utf8 = SDL_iconv_string("UTF-8", "WCHAR_T", (const char *)fmt, (SDL_wcslen(fmt) + 1) * sizeof(wchar_t)); diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 0f32f9733a..d9b6520a9a 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -901,6 +901,7 @@ static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instanc if (hid_loaded) { char devName[MAX_PATH + 1]; + devName[0] = '\0'; UINT cap = sizeof(devName) - 1; UINT len = GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, devName, &cap); if (len != (UINT)-1) { diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index ca15a1c1f8..9c03df7a49 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -599,7 +599,6 @@ static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex) static HKL hklprev = 0; static DWORD dwRet[2] = { 0 }; DWORD dwVerSize = 0; - DWORD dwVerHandle = 0; LPVOID lpVerBuffer = 0; LPVOID lpVerData = 0; UINT cbVerData = 0; @@ -637,11 +636,11 @@ static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex) return dwRet[0]; } #undef LCID_INVARIANT - dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle); + dwVerSize = GetFileVersionInfoSizeA(szTemp, NULL); if (dwVerSize) { lpVerBuffer = SDL_malloc(dwVerSize); if (lpVerBuffer) { - if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) { + if (GetFileVersionInfoA(szTemp, 0, dwVerSize, lpVerBuffer)) { if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) { #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR *)lpVerData) DWORD dwVer = pVerFixedInfo->dwFileVersionMS; From f13cd9a666f8ab069dfa8d4700528243496be027 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 30 Mar 2026 16:17:27 -0400 Subject: [PATCH 039/407] process: Don't duplicate NULL stdio handles on Windows. It's okay to pass null handles to win32's CreateProcess(). Fixes #14977. --- src/process/windows/SDL_windowsprocess.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/process/windows/SDL_windowsprocess.c b/src/process/windows/SDL_windowsprocess.c index 5c4bde8699..dfefa54f38 100644 --- a/src/process/windows/SDL_windowsprocess.c +++ b/src/process/windows/SDL_windowsprocess.c @@ -263,6 +263,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID HANDLE stdin_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stdout_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stderr_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; + HANDLE handle; DWORD pipe_mode = PIPE_NOWAIT; bool result = false; @@ -357,7 +358,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), + handle = GetStdHandle(STD_INPUT_HANDLE); + if (!handle) { + startup_info.hStdInput = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdInput = INVALID_HANDLE_VALUE; @@ -394,7 +398,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), + handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (!handle) { + startup_info.hStdOutput = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdOutput = INVALID_HANDLE_VALUE; @@ -405,7 +412,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID } if (redirect_stderr) { - if (!DuplicateHandle(GetCurrentProcess(), startup_info.hStdOutput, + handle = startup_info.hStdOutput; + if (!handle) { + startup_info.hStdError = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdError = INVALID_HANDLE_VALUE; @@ -440,7 +450,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), + handle = GetStdHandle(STD_ERROR_HANDLE); + if (!handle) { + startup_info.hStdError = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdError = INVALID_HANDLE_VALUE; From d6129d063f512583c9446a8443ca34ebebb39c49 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Fri, 27 Mar 2026 22:57:48 +0100 Subject: [PATCH 040/407] SDL_GlobDirectory(): Don't descend into sub-directories, if not requested by pattern --- src/filesystem/SDL_filesystem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem/SDL_filesystem.c b/src/filesystem/SDL_filesystem.c index 6a52baf28b..dca0da5c99 100644 --- a/src/filesystem/SDL_filesystem.c +++ b/src/filesystem/SDL_filesystem.c @@ -203,7 +203,7 @@ static bool WildcardMatch(const char *pattern, const char *str, bool *matched_to pch = *(++pattern); } - *matched_to_dir = ((pch == '/') || (pch == '\0')); // end of string and the pattern is complete or failed at a '/'? We should descend into this directory. + *matched_to_dir = (pch == '/'); // end of string and the pattern failed at a '/'? We should descend into this directory. return (pch == '\0'); // survived the whole pattern? That's a match! } From 8e1bdbaa926a89cf84bcc3b2297bdb46b63efc6e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 31 Mar 2026 11:10:22 -0700 Subject: [PATCH 041/407] Updated support for the GameSir Pro 8K The latest firmware (v1.97) corrects the report frequency, and no longer reports the mute button. --- src/joystick/hidapi/SDL_hidapi_gamesir.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_gamesir.c b/src/joystick/hidapi/SDL_hidapi_gamesir.c index ce659308bb..13a0d534cb 100644 --- a/src/joystick/hidapi/SDL_hidapi_gamesir.c +++ b/src/joystick/hidapi/SDL_hidapi_gamesir.c @@ -35,7 +35,10 @@ #define GAMESIR_PACKET_HEADER_0 0xA1 #define GAMESIR_PACKET_HEADER_1_GAMEPAD 0xC8 -#define GAMESIR_IMU_RATE_HZ 250 +#define GAMESIR_IMU_RATE_HZ_WIRED 1000 +#define GAMESIR_IMU_RATE_HZ_WIRELESS 250 +// We can't tell whether it's connected via dongle or not... +#define GAMESIR_IMU_RATE_HZ GAMESIR_IMU_RATE_HZ_WIRED #define BTN_A 0x01 #define BTN_B 0x02 @@ -91,7 +94,7 @@ enum //SDL_GAMEPAD_BUTTON_GAMESIR_R7, // This button doesn't exist? //SDL_GAMEPAD_BUTTON_GAMESIR_L8, // This button doesn't exist? //SDL_GAMEPAD_BUTTON_GAMESIR_R8, // This button doesn't exist? - SDL_GAMEPAD_BUTTON_GAMESIR_MUTE, // This button controls the audio mute LED + //SDL_GAMEPAD_BUTTON_GAMESIR_MUTE, // This button controls the audio mute LED and doesn't seem to be reported //SDL_GAMEPAD_BUTTON_GAMESIR_M // This button is for internal use by the firmware SDL_GAMEPAD_NUM_GAMESIR_BUTTONS }; @@ -622,7 +625,7 @@ static void HIDAPI_DriverGameSir_HandleStatePacket(SDL_Joystick *joystick, SDL_D //SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GAMESIR_M, buttons & BTN_M); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GAMESIR_L4, buttons & BTN_L4); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GAMESIR_R4, buttons & BTN_R4); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GAMESIR_MUTE, buttons & BTN_MUTE); + //SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GAMESIR_MUTE, buttons & BTN_MUTE); } if (last[3] != data[3]) { From 6466c10ae4eb11c961d2d97e32c2fac9d3f0b1c6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 1 Apr 2026 16:37:14 -0700 Subject: [PATCH 042/407] Added documentation to fix building on macOS with Xcode 12.2 (thanks @buhman!) Fixes https://github.com/libsdl-org/SDL/issues/15167 --- docs/README-macos.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/README-macos.md b/docs/README-macos.md index 0a97b3d5b9..79b3a4f868 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -32,6 +32,10 @@ sudo cmake --install . Please note that building SDL requires at least Xcode 12.2 and the macOS 11.0 SDK. +If you are getting errors building SDL_mfijoystick.m with Xcode 12.2, find your SDKs +directory and move MacOSX10.15.sdk out of the way so it isn't accidentally being used +by the build environment. + To use the library once it's built, you essential have two possibilities: use the traditional autoconf/automake/make method, or use Xcode. From 4d17b99d0a1c33c5257063b098f883c669ade40b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 1 Apr 2026 20:38:27 -0400 Subject: [PATCH 043/407] aaudio: Respect SDL_HINT_AUDIO_DEVICE_STREAM_ROLE hint. Fixes #15299. --- include/SDL3/SDL_hints.h | 5 +++++ src/audio/aaudio/SDL_aaudio.c | 24 ++++++++++++++++++++++++ src/audio/aaudio/SDL_aaudiofuncs.h | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 0596171b98..b02b13b8f4 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -402,6 +402,11 @@ extern "C" { * - "Movie" - Music or sound with dialog * - "Media" - Music or sound without dialog * + * Android's AAudio target supports this hint as of SDL 3.4.4. Android does + * not support the exact same options as WASAPI, but for portability, will + * attempt to map these same strings to the `aaudio_usage_t` constants. For + * example, "Movie" and "Media" will both map to `AAUDIO_USAGE_MEDIA`, etc. + * * If your application applies its own echo cancellation, gain control, and * noise reduction it should also set SDL_HINT_AUDIO_DEVICE_RAW_STREAM. * diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c index bc0e7a285d..ea5e1c09a5 100644 --- a/src/audio/aaudio/SDL_aaudio.c +++ b/src/audio/aaudio/SDL_aaudio.c @@ -285,6 +285,28 @@ static void AAUDIO_CloseDevice(SDL_AudioDevice *device) } } +static void SetOptionalStreamUsage(AAudioStreamBuilder *builder) +{ + if (ctx.AAudioStreamBuilder_setUsage) { // optional API: requires Android 28 + const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE); + if (hint) { + aaudio_usage_t usage = AAUDIO_USAGE_MEDIA; // covers most things, and is the system default. + if ((SDL_strcasecmp(hint, "Communications") == 0) || (SDL_strcasecmp(hint, "GameChat") == 0)) { + usage = AAUDIO_USAGE_VOICE_COMMUNICATION; + } else if (SDL_strcasecmp(hint, "Game") == 0) { + usage = AAUDIO_USAGE_GAME; + } + ctx.AAudioStreamBuilder_setUsage(builder, usage); + + // !!! FIXME: I _think_ this is okay with the current set of usages we support, but the docs + // !!! FIXME: say you need to dip down into Java to call android.app.Activity.setVolumeControlStream(usage) + // !!! FIXME: so the physical volume buttons control this stream, but that might be more for special cases + // !!! FIXME: like notification sounds, etc, and it's possible you _don't_ want to override this for those + // !!! FIXME: special cases, too! We'll revisit if there are bug reports. + } + } +} + static bool BuildAAudioStream(SDL_AudioDevice *device) { struct SDL_PrivateAudioData *hidden = device->hidden; @@ -343,6 +365,8 @@ static bool BuildAAudioStream(SDL_AudioDevice *device) SDL_Log("Low latency audio disabled"); } + SetOptionalStreamUsage(builder); + if (recording && ctx.AAudioStreamBuilder_setInputPreset) { // optional API: requires Android 28 // try to use a microphone that is for recording external audio. Otherwise Android might choose the mic used for talking // on the telephone when held to the user's ear, which is often not useful at any distance from the device. diff --git a/src/audio/aaudio/SDL_aaudiofuncs.h b/src/audio/aaudio/SDL_aaudiofuncs.h index 2cea7f68e1..6568c12b0f 100644 --- a/src/audio/aaudio/SDL_aaudiofuncs.h +++ b/src/audio/aaudio/SDL_aaudiofuncs.h @@ -37,7 +37,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction)) SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) -SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28 +SDL_PROC_OPTIONAL(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) // API 28 SDL_PROC_OPTIONAL(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) // API 28 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) // API 29 From 32ef82caaf29ec340ac4614859668f734279fd66 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 2 Apr 2026 11:48:35 -0400 Subject: [PATCH 044/407] pipewire: Don't mark a device disconnected if pw_stream_dequeue_buffer fails. Apparently this _can_ happen under load, or maybe some other weird condition. Hopefully this will encourage PipeWire to fire output_callback again, and we'll just try again later. Reference Issue #14916. --- src/audio/pipewire/SDL_pipewire.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index 5dffd77578..0719d04f0f 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -976,18 +976,18 @@ static void initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info static Uint8 *PIPEWIRE_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - // See if a buffer is available. If this returns NULL, SDL_PlaybackAudioThreadIterate will return false, but since we own the thread, it won't kill playback. - // !!! FIXME: It's not clear to me if this ever returns NULL or if this was just defensive coding. - + // See if a buffer is available. If this sets *buffer_size=0, then SDL_PlaybackAudioThreadIterate will skip this iteration but try again next time. struct pw_stream *stream = device->hidden->stream; struct pw_buffer *pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); if (pw_buf == NULL) { + *buffer_size = 0; return NULL; } struct spa_buffer *spa_buf = pw_buf->buffer; if (spa_buf->datas[0].data == NULL) { PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + *buffer_size = 0; return NULL; } From b5ef75249f2f39bae77fcb009832ba6ec753a3cc Mon Sep 17 00:00:00 2001 From: Janne Virtala Date: Thu, 2 Apr 2026 17:45:43 +0300 Subject: [PATCH 045/407] SDL_PrivateJoystickForceRecentering(): fix infinite loop --- src/joystick/SDL_joystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index dde9927008..1dbcdce8b5 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -2492,7 +2492,7 @@ bool SDL_IsJoystickBeingAdded(void) void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick) { - Uint8 i, j; + int i, j; Uint64 timestamp = SDL_GetTicksNS(); SDL_AssertJoysticksLocked(); From 156187bf58a3a556c6f669acb0639bc4b6ae6990 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 2 Apr 2026 10:30:32 -0700 Subject: [PATCH 046/407] Added a hint "SDL_SURFACE_MALLOC" to disable aligned surface allocation This is needed for sdl12-compat, where all surfaces were not aligned. --- src/video/SDL_surface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index c3350e311c..6658ae8df5 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -229,12 +229,16 @@ SDL_Surface *SDL_CreateSurface(int width, int height, SDL_PixelFormat format) if (surface->w && surface->h && format != SDL_PIXELFORMAT_MJPG) { surface->flags &= ~SDL_SURFACE_PREALLOCATED; - surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size); + if (SDL_GetHintBoolean("SDL_SURFACE_MALLOC", false)) { + surface->pixels = SDL_malloc(size); + } else { + surface->flags |= SDL_SURFACE_SIMD_ALIGNED; + surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size); + } if (!surface->pixels) { SDL_DestroySurface(surface); return NULL; } - surface->flags |= SDL_SURFACE_SIMD_ALIGNED; // This is important for bitmaps SDL_memset(surface->pixels, 0, size); From 501ee05129581d51226853f4b70d81cf6e8be22d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 2 Apr 2026 11:00:17 -0700 Subject: [PATCH 047/407] Don't strip the alpha channel when scaling surfaces if it will be needed Fixes https://github.com/libsdl-org/SDL/issues/15297 --- src/video/SDL_surface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 6658ae8df5..d96dc7fb4e 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -1314,7 +1314,8 @@ bool SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcrect, S // Change source format if not appropriate for scaling if (SDL_BYTESPERPIXEL(src->format) != 4 || src->format == SDL_PIXELFORMAT_ARGB2101010) { SDL_PixelFormat fmt; - if (SDL_BYTESPERPIXEL(dst->format) == 4 && dst->format != SDL_PIXELFORMAT_ARGB2101010) { + if (SDL_BYTESPERPIXEL(dst->format) == 4 && dst->format != SDL_PIXELFORMAT_ARGB2101010 && + (SDL_ISPIXELFORMAT_ALPHA(dst->format) || !is_complex_copy_flags)) { fmt = dst->format; } else { fmt = SDL_PIXELFORMAT_ARGB8888; From 48e80c8f269365c3320f42c0bdad77369a447fc4 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Apr 2026 19:25:54 +0200 Subject: [PATCH 048/407] memcpy with a NULL src/dst argument is UB malloc of UBSAN returns NULL when allocating 0 bytes, causing a call to memcpy(NULL, xxx, 0); --- src/video/SDL_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 6cb30d83a8..a338645c96 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1352,7 +1352,9 @@ SDL_DisplayMode **SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *co result = (SDL_DisplayMode **)SDL_malloc((num_modes + 1) * sizeof(*result) + num_modes * sizeof(**result)); if (result) { SDL_DisplayMode *modes = (SDL_DisplayMode *)((Uint8 *)result + ((num_modes + 1) * sizeof(*result))); - SDL_memcpy(modes, display->fullscreen_modes, num_modes * sizeof(*modes)); + if (num_modes) { + SDL_memcpy(modes, display->fullscreen_modes, num_modes * sizeof(*modes)); + } for (i = 0; i < num_modes; ++i) { result[i] = modes++; } From df72e3f59d3b7d062b82d665a362c7221fe9dd65 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Apr 2026 20:04:41 +0200 Subject: [PATCH 049/407] Shifting a number into the sign bit of a signed integer is UB Shift as a unsigned number instead. --- test/testatomic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testatomic.c b/test/testatomic.c index 31e39f8b1f..946d4ea501 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -101,7 +101,7 @@ static void RunBasicTest(void) #define VALBITS (sizeof(atomicValue) * 8) #define atomicValue int -#define CountTo ((atomicValue)((unsigned int)(1 << (VALBITS - 1)) - 1)) +#define CountTo ((atomicValue)((1u << (VALBITS - 1)) - 1)) #define NInter (CountTo / CountInc / NThreads) #define Expect (CountTo - NInter * CountInc * NThreads) From f7661ff016c6a832c80e026d84c1e4ac248f65aa Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Apr 2026 20:11:54 +0200 Subject: [PATCH 050/407] Avoid unaligned memory access while testing SSE4.2 CRC intrinsics --- test/testautomation_intrinsics.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/testautomation_intrinsics.c b/test/testautomation_intrinsics.c index 8338d33d35..9b0c28b1f8 100644 --- a/test/testautomation_intrinsics.c +++ b/test/testautomation_intrinsics.c @@ -256,11 +256,26 @@ SDL_TARGETING("sse4.2") static Uint32 calculate_crc32c_sse4_2(const char *text) Uint32 crc32c = ~0u; size_t len = SDL_strlen(text); + if (len >= 1 && ((uintptr_t)text & 0x1)) { + crc32c = (Uint32)_mm_crc32_u8(crc32c, *text); + len -= 1; + text += 1; + } + if (len >= 2 && ((uintptr_t)text & 0x2)) { + crc32c = (Uint32)_mm_crc32_u16(crc32c, *(Sint16*)text); + len -= 2; + text += 2; + } #if defined(__x86_64__) || defined(_M_X64) + if (len >= 4 && ((uintptr_t)text & 0x4)) { + crc32c = (Uint32)_mm_crc32_u32(crc32c, *(Sint32*)text); + len -= 4; + text += 4; + } for (; len >= 8; len -= 8, text += 8) { crc32c = (Uint32)_mm_crc32_u64(crc32c, *(Sint64*)text); } - if (len >= 4) { + if (len & 0x4) { crc32c = (Uint32)_mm_crc32_u32(crc32c, *(Sint32*)text); len -= 4; text += 4; @@ -270,13 +285,15 @@ SDL_TARGETING("sse4.2") static Uint32 calculate_crc32c_sse4_2(const char *text) crc32c = (Uint32)_mm_crc32_u32(crc32c, *(Sint32*)text); } #endif - if (len >= 2) { + if (len & 0x2) { crc32c = (Uint32)_mm_crc32_u16(crc32c, *(Sint16*)text); len -= 2; text += 2; } - if (len) { + if (len & 0x1) { crc32c = (Uint32)_mm_crc32_u8(crc32c, *text); + len -= 1; + text += 1; } return ~crc32c; } From b77fdcc63882d65e8f70679b99e6026491fac27f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Apr 2026 20:13:44 +0200 Subject: [PATCH 051/407] Disable UB sanitizer in signed shift test --- test/testplatform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testplatform.c b/test/testplatform.c index 9d409d91b8..4e79f6326c 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -208,6 +208,9 @@ static int TST_uallrem(void *a, void *b, int arg, void *result, void *expected) return (*(unsigned long long *)result) == (*(unsigned long long *)expected); } +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__ICC) +static int TST_allshl(void *a, void *b, int arg, void *result, void *expected) __attribute__ ((no_sanitize("undefined"))); +#endif static int TST_allshl(void *a, void *b, int arg, void *result, void *expected) { (*(long long *)result) = (*(long long *)a) << arg; From 03f74f3ad32ce6b36c68804022079eab0129eee7 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Apr 2026 20:24:04 +0200 Subject: [PATCH 052/407] testyuv: make test params static const --- test/testyuv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testyuv.c b/test/testyuv.c index bd4b8b2981..85f3ee4c8f 100644 --- a/test/testyuv.c +++ b/test/testyuv.c @@ -766,7 +766,7 @@ done: int main(int argc, char **argv) { - struct + static const struct { bool enable_intrinsics; int pattern_size; From e21f7d77f3ac73ac9dcc35c4ddcf3e7341cbd695 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 2 Apr 2026 14:08:20 -0700 Subject: [PATCH 053/407] Fixed unaligned 16-bit memory access The previous code technically works on platforms with SSE2, but this fixes an ubsan warning. --- src/video/SDL_yuv.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/video/SDL_yuv.c b/src/video/SDL_yuv.c index 3d09e97edc..6b57d54dc1 100644 --- a/src/video/SDL_yuv.c +++ b/src/video/SDL_yuv.c @@ -1499,8 +1499,17 @@ static bool SDL_TARGETING("sse2") SDL_ConvertPixels_SwapNV_SSE2(int width, int h dstUV += 8; x -= 8; } - while (x--) { - *dstUV++ = SDL_Swap16(*srcUV++); + if (x > 0) { + const Uint8 *srcUV8 = (const Uint8 *)srcUV; + Uint8 *dstUV8 = (Uint8 *)dstUV; + srcUV += x; + dstUV += x; + while (x--) { + Uint8 u = *srcUV8++; + Uint8 v = *srcUV8++; + *dstUV8++ = v; + *dstUV8++ = u; + } } srcUV += srcUVPitchLeft; dstUV += dstUVPitchLeft; From c58a61fdd4c70530a4d155996f58b012fa5f814d Mon Sep 17 00:00:00 2001 From: Sanjay Govind Date: Fri, 3 Apr 2026 13:10:42 +1300 Subject: [PATCH 054/407] Update to GameInput V3 (#15302) --- src/core/windows/SDL_gameinput.h | 4 +++- src/joystick/gdk/SDL_gameinputjoystick.cpp | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index a046489900..0d7b6f85e7 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -31,7 +31,9 @@ #define GAMEINPUT_API_VERSION 0 #endif -#if GAMEINPUT_API_VERSION == 2 +#if GAMEINPUT_API_VERSION == 3 +using namespace GameInput::v3; +#elif GAMEINPUT_API_VERSION == 2 using namespace GameInput::v2; #elif GAMEINPUT_API_VERSION == 1 using namespace GameInput::v1; diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index 0e3d50a2b4..d60251a71e 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -542,9 +542,15 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) } #endif // GAMEINPUT_API_VERSION >= 1 } else { +#if GAMEINPUT_API_VERSION >= 3 + joystick->naxes = info->controllerInfo->controllerAxisCount; + joystick->nbuttons = info->controllerInfo->controllerButtonCount; + joystick->nhats = info->controllerInfo->controllerSwitchCount; +#else joystick->naxes = info->controllerAxisCount; joystick->nbuttons = info->controllerButtonCount; joystick->nhats = info->controllerSwitchCount; +#endif // GAMEINPUT_API_VERSION >= 3 } if (info->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) { @@ -676,13 +682,13 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) #undef CONVERT_TRIGGER } } else { - bool *button_state = SDL_stack_alloc(bool, info->controllerButtonCount); - float *axis_state = SDL_stack_alloc(float, info->controllerAxisCount); - GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, info->controllerSwitchCount); + bool *button_state = SDL_stack_alloc(bool, joystick->nbuttons); + float *axis_state = SDL_stack_alloc(float, joystick->naxes); + GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, joystick->nhats); if (button_state) { uint32_t i; - uint32_t button_count = reading->GetControllerButtonState(info->controllerButtonCount, button_state); + uint32_t button_count = reading->GetControllerButtonState(joystick->nbuttons, button_state); for (i = 0; i < button_count; ++i) { SDL_SendJoystickButton(timestamp, joystick, (Uint8)i, button_state[i]); } @@ -692,7 +698,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) #define CONVERT_AXIS(v) (Sint16)((v)*65535.0f - 32768.0f) if (axis_state) { uint32_t i; - uint32_t axis_count = reading->GetControllerAxisState(info->controllerAxisCount, axis_state); + uint32_t axis_count = reading->GetControllerAxisState(joystick->naxes, axis_state); for (i = 0; i < axis_count; ++i) { SDL_SendJoystickAxis(timestamp, joystick, (Uint8)i, CONVERT_AXIS(axis_state[i])); } @@ -702,7 +708,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) if (switch_state) { uint32_t i; - uint32_t switch_count = reading->GetControllerSwitchState(info->controllerSwitchCount, switch_state); + uint32_t switch_count = reading->GetControllerSwitchState(joystick->nhats, switch_state); for (i = 0; i < switch_count; ++i) { Uint8 hat; switch (switch_state[i]) { From f423a2ae34afd759063a7304e7034fedb9cd91e4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 2 Apr 2026 20:39:53 -0400 Subject: [PATCH 055/407] kmsdrm: Disable atomic mouse code for now. The rest of the atomic codepath is still enabled and usable. This fixes missing and weird mouse cursors. We'll debug this code later on. Reference Issue #15242. --- src/video/kmsdrm/SDL_kmsdrmmouse.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c index df321031ae..8f48df3e8e 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.c +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -32,6 +32,9 @@ #include "../SDL_pixels_c.h" +// !!! FIXME: atomic cursors are broken right now. +#define USE_ATOMIC_CURSOR 0 + static SDL_Cursor *KMSDRM_CreateDefaultCursor(void); static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y); static bool KMSDRM_ShowCursor(SDL_Cursor *cursor); @@ -40,10 +43,10 @@ static void KMSDRM_FreeCursor(SDL_Cursor *cursor); /**************************************************************************************/ // BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS. -// How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have +// How does SDL manage cursors internally? First, mouse != cursor. The mouse can have // many cursors in mouse->cursors. // -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many -// cursosr with this, not only one. +// cursors with this, not only one. // -SDL stores those cursors in a cursors array, in mouse->cursors. // -Whenever it wants (or the programmer wants) takes a cursor from that array // and shows it on screen with KMSDRM_ShowCursor(). @@ -68,7 +71,7 @@ void KMSDRM_DestroyCursorBO(SDL_VideoDevice *_this, SDL_VideoDisplay *display) // Destroy the curso GBM BO. if (dispdata->cursor_bo) { SDL_VideoData *viddata = (SDL_VideoData *) _this->internal; - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { if (dispdata->cursor_plane) { // Unset the the cursor BO from the cursor plane. KMSDRM_PlaneInfo info; @@ -99,7 +102,7 @@ bool KMSDRM_CreateCursorBO(SDL_VideoDisplay *display) SDL_VideoData *viddata = dev->internal; SDL_DisplayData *dispdata = display->internal; - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { setup_plane(dev, dispdata, &dispdata->cursor_plane, DRM_PLANE_TYPE_CURSOR); } @@ -141,7 +144,7 @@ static bool KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display) SDL_VideoDevice *video_device = SDL_GetVideoDevice(); SDL_VideoData *viddata = video_device->internal; - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { if (dispdata->cursor_plane) { KMSDRM_PlaneInfo info; SDL_zero(info); @@ -207,7 +210,7 @@ static bool KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Mouse *mouse, S goto cleanup; } - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { // Get the fb_id for the GBM BO so we can show it on the cursor plane. KMSDRM_FBInfo *fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo); KMSDRM_PlaneInfo info; @@ -400,7 +403,7 @@ static bool KMSDRM_WarpMouseGlobal(float x, float y) if (dispdata->cursor_bo) { SDL_VideoDevice *dev = SDL_GetVideoDevice(); SDL_VideoData *viddata = dev->internal; - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { const SDL_CursorData *curdata = (const SDL_CursorData *) mouse->cur_cursor->internal; drm_atomic_movecursor(dispdata, curdata, (uint16_t) (int) x, (uint16_t) (int) y); } else { @@ -467,7 +470,7 @@ static bool KMSDRM_MoveCursor(SDL_Cursor *cursor) return SDL_SetError("Cursor not initialized properly."); } - if (viddata->is_atomic) { + if (USE_ATOMIC_CURSOR && viddata->is_atomic) { /* !!! FIXME: Some programs expect cursor movement even while they don't do SwapWindow() calls, and since we ride on the atomic_commit() in SwapWindow() for cursor movement, cursor won't move in these situations. We could do an atomic_commit() here From 3c11b43e59a8faf6288213207aafcd1f895999f3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 2 Apr 2026 20:45:20 -0500 Subject: [PATCH 056/407] kmsdrm: Initialize kms_in_fence_fd to -1 Prior to this fix, we closed stdin on the first call to drm_atomic_commit(). --- src/video/kmsdrm/SDL_kmsdrmvideo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 7d5c13e19b..0c061b9d29 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1125,6 +1125,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *conn, dr to sane values. */ dispdata->cursor_bo = NULL; dispdata->cursor_bo_drm_fd = -1; + dispdata->kms_in_fence_fd = -1; dispdata->kms_out_fence_fd = -1; /* Since we create and show the default cursor on KMSDRM_InitMouse(), From be8643f739c3a70f459d6dfb9b7bcfd09bc5fea9 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 2 Apr 2026 19:17:02 -0700 Subject: [PATCH 057/407] emscripten: Fix navigator.getGamepads crash in worker threads The three EM_JS functions (SDL_GetEmscriptenJoystickVendor, SDL_GetEmscriptenJoystickProduct, SDL_IsEmscriptenJoystickXInput) call navigator.getGamepads() which is only available on the main browser thread. With PROXY_TO_PTHREAD, the joystick callbacks are dispatched to a worker where the Gamepad API is not available, causing a TypeError. Convert these from EM_JS to static functions using MAIN_THREAD_EM_ASM_INT, which proxies the JavaScript execution to the main browser thread. This matches the pattern already used by other navigator.getGamepads() calls in the same file. --- src/joystick/emscripten/SDL_sysjoystick.c | 83 +++++++++++++---------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 42f12b033d..156917e682 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -35,53 +35,62 @@ static SDL_joylist_item *SDL_joylist = NULL; static SDL_joylist_item *SDL_joylist_tail = NULL; static int numjoysticks = 0; -EM_JS(int, SDL_GetEmscriptenJoystickVendor, (int device_index), { +static int SDL_GetEmscriptenJoystickVendor(int device_index) +{ // Let's assume that if we're calling these function then the gamepad object definitely exists - let gamepad = navigator['getGamepads']()[device_index]; + return MAIN_THREAD_EM_ASM_INT({ + let gamepad = navigator['getGamepads']()[$0]; - // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) - let vendor_str = 'Vendor: '; - if (gamepad['id']['indexOf'](vendor_str) > 0) { - let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length']; - return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16); - } + // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) + let vendor_str = 'Vendor: '; + if (gamepad['id']['indexOf'](vendor_str) > 0) { + let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length']; + return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16); + } - // Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action) - let id_split = gamepad['id']['split']('-'); - if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) { - return parseInt(id_split[0], 16); - } + // Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action) + let id_split = gamepad['id']['split']('-'); + if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) { + return parseInt(id_split[0], 16); + } - return 0; -}); + return 0; + }, device_index); +} -EM_JS(int, SDL_GetEmscriptenJoystickProduct, (int device_index), { - let gamepad = navigator['getGamepads']()[device_index]; +static int SDL_GetEmscriptenJoystickProduct(int device_index) +{ + return MAIN_THREAD_EM_ASM_INT({ + let gamepad = navigator['getGamepads']()[$0]; - // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) - let product_str = 'Product: '; - if (gamepad['id']['indexOf'](product_str) > 0) { - let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length']; - return parseInt(gamepad['id']['substr'](product_str_index, 4), 16); - } + // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) + let product_str = 'Product: '; + if (gamepad['id']['indexOf'](product_str) > 0) { + let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length']; + return parseInt(gamepad['id']['substr'](product_str_index, 4), 16); + } - // Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action) - let id_split = gamepad['id']['split']('-'); - if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) { - return parseInt(id_split[1], 16); - } + // Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action) + let id_split = gamepad['id']['split']('-'); + if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) { + return parseInt(id_split[1], 16); + } - return 0; -}); + return 0; + }, device_index); +} -EM_JS(int, SDL_IsEmscriptenJoystickXInput, (int device_index), { - let gamepad = navigator['getGamepads']()[device_index]; +static int SDL_IsEmscriptenJoystickXInput(int device_index) +{ + return MAIN_THREAD_EM_ASM_INT({ + let gamepad = navigator['getGamepads']()[$0]; - // Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD) - // Firefox: xinput - // TODO: Safari - return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0; -}); + // Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD) + // Firefox: xinput + // TODO: Safari + return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0; + }, device_index); +} static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { From 1674a04b018a86ad05088e343d74dd57d7f7c9ec Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 2 Apr 2026 22:02:18 -0500 Subject: [PATCH 058/407] kmsdrm: Add missing KMSDRM_FBFromBO() failure check --- src/video/kmsdrm/SDL_kmsdrmmouse.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c index 8f48df3e8e..1cee269dd6 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.c +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -215,6 +215,11 @@ static bool KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Mouse *mouse, S KMSDRM_FBInfo *fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo); KMSDRM_PlaneInfo info; + if (!fb) { + result = SDL_SetError("Failed to get cursor FB from BO"); + goto cleanup; + } + // Show the GBM BO buffer on the cursor plane. SDL_zero(info); info.plane = dispdata->cursor_plane; From f3a3b4b95a37d84ef9c1510f02d32b87ab8205c9 Mon Sep 17 00:00:00 2001 From: nilFinx Date: Fri, 3 Apr 2026 16:01:21 +0900 Subject: [PATCH 059/407] haiku: Always assume that the URL is encoded (required on nightly) (#15305) --- src/misc/haiku/SDL_sysurl.cc | 4 ++++ src/video/haiku/SDL_bvideo.cc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/misc/haiku/SDL_sysurl.cc b/src/misc/haiku/SDL_sysurl.cc index 0372dd9c53..2c673abc51 100644 --- a/src/misc/haiku/SDL_sysurl.cc +++ b/src/misc/haiku/SDL_sysurl.cc @@ -25,7 +25,11 @@ bool SDL_SYS_OpenURL(const char *url) { +#if B_BEOS_VERSION <= B_HAIKU_VERSION_1_BETA_5 BUrl burl(url); +#else + BUrl burl(url, true); +#endif const status_t rc = burl.OpenWithPreferredApplication(false); if (rc != B_NO_ERROR) { return SDL_SetError("URL open failed (err=%d)", (int)rc); diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index 93fc67d18f..9297704a7a 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -316,7 +316,11 @@ void HAIKU_VideoQuit(SDL_VideoDevice *_this) extern "C" bool HAIKU_OpenURL(const char *url) { +#if B_HAIKU_VERSION <= B_HAIKU_VERSION_1_BETA_5 BUrl burl(url); +#else + BUrl burl(url, true); +#endif const status_t rc = burl.OpenWithPreferredApplication(false); if (rc != B_NO_ERROR) { return SDL_SetError("URL open failed (err=%d)", (int)rc); From 5ae1308e5b49fdcb2e43a29c843faf0113e41f39 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 3 Apr 2026 01:32:09 -0700 Subject: [PATCH 060/407] Use the correct source rectangle when doing scaled blits Fixes https://github.com/libsdl-org/SDL/issues/15309 --- src/video/SDL_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index d96dc7fb4e..8164f76fbc 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -2326,7 +2326,7 @@ SDL_Surface *SDL_ConvertSurfaceRect(SDL_Surface *surface, const SDL_Rect *rect, return NULL; } - return SDL_ConvertSurfaceRectAndColorspace(surface, NULL, format, NULL, SDL_GetDefaultColorspaceForFormat(format), surface->props); + return SDL_ConvertSurfaceRectAndColorspace(surface, rect, format, NULL, SDL_GetDefaultColorspaceForFormat(format), surface->props); } SDL_Surface *SDL_ConvertSurface(SDL_Surface *surface, SDL_PixelFormat format) From 045a127572fb53b3ee8cce3d56de2410b52dc650 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 3 Apr 2026 11:47:41 -0400 Subject: [PATCH 061/407] Add CHECK_PARAM as a conditional macro in clang-format Otherwise, it won't be treated as a conditional expression, and clang-format will automatically move the opening brace to the line below it. --- .clang-format | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.clang-format b/.clang-format index 4e932d022d..c3c963c725 100644 --- a/.clang-format +++ b/.clang-format @@ -77,6 +77,11 @@ SpaceInEmptyParentheses: false UseCRLF: false UseTab: Never +IfMacros: + [ + "CHECK_PARAM", + ] + ForEachMacros: [ "spa_list_for_each", From 59602fb4732c8ab6f3e0a9d94d7fb8e34f1f79f8 Mon Sep 17 00:00:00 2001 From: foxtacles Date: Fri, 3 Apr 2026 15:07:50 -0700 Subject: [PATCH 062/407] (emscripten) Add null checks for gamepad in vendor/product/xinput helpers (#15313) navigator.getGamepads() can return null for a slot if the gamepad disconnects between the gamepadconnected event and the proxied MAIN_THREAD_EM_ASM_INT call. This causes a TypeError when accessing gamepad.id. Add null guards matching the pattern already used in EMSCRIPTEN_JoystickOpen and EMSCRIPTEN_JoystickRumble. --- src/joystick/emscripten/SDL_sysjoystick.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 156917e682..5d831bddbb 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -37,9 +37,11 @@ static int numjoysticks = 0; static int SDL_GetEmscriptenJoystickVendor(int device_index) { - // Let's assume that if we're calling these function then the gamepad object definitely exists return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) let vendor_str = 'Vendor: '; @@ -62,6 +64,9 @@ static int SDL_GetEmscriptenJoystickProduct(int device_index) { return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) let product_str = 'Product: '; @@ -84,6 +89,9 @@ static int SDL_IsEmscriptenJoystickXInput(int device_index) { return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD) // Firefox: xinput From 7f86f9107d0270f963a7896180e80dc6ed28ea9e Mon Sep 17 00:00:00 2001 From: Sanjay Govind Date: Sat, 4 Apr 2026 12:02:14 +1300 Subject: [PATCH 063/407] Add support for GIP guitars via gameinput (#15301) --- include/SDL3/SDL_hints.h | 20 ++ src/joystick/gdk/SDL_gameinputjoystick.cpp | 396 ++++++++++++++------- src/joystick/usb_ids.h | 8 + 3 files changed, 303 insertions(+), 121 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index b02b13b8f4..0c1a19d36d 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -1444,6 +1444,26 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_GAMEINPUT "SDL_JOYSTICK_GAMEINPUT" +/** + * A variable controlling whether GameInput should be used for handling + * GIP devices that require raw report processing, but aren't supported + * by HIDRAW, such as Xbox One Guitars. + * + * Note that this is only supported with GameInput 3 or newer. + * + * The variable can be set to the following values: + * + * - "0": GameInput is not used to handle raw GIP devices. + * - "1": GameInput is used. + * + * The default is "1" when using GameInput 3 or newer, and is "0" otherwise. + * + * This hint should be set before SDL is initialized. + * + * \since This hint is available since SDL 3.4.4. + */ +#define SDL_HINT_JOYSTICK_GAMEINPUT_RAW "SDL_JOYSTICK_GAMEINPUT_RAW" + /** * A variable containing a list of devices known to have a GameCube form * factor. diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index d60251a71e..5d373a2550 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -44,6 +44,15 @@ enum SDL_GAMEPAD_BUTTON_GAMEINPUT_SHARE = 11 }; +enum +{ + SDL_GAMEINPUT_RAWTYPE_NONE, + SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR, + SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_DRUM_KIT, + SDL_GAMEINPUT_RAWTYPE_GUITAR_HERO_LIVE_GUITAR, + SDL_GAMEINPUT_RAWTYPE_LEGACY_ADAPTER, +}; + typedef struct GAMEINPUT_InternalDevice { IGameInputDevice *device; @@ -52,6 +61,7 @@ typedef struct GAMEINPUT_InternalDevice SDL_GUID guid; // generated by SDL SDL_JoystickID device_instance; // generated by SDL const GameInputDeviceInfo *info; + int raw_type; int steam_virtual_gamepad_slot; bool isAdded; bool isDeleteRequested; @@ -89,9 +99,66 @@ static bool GAMEINPUT_InternalIsGamepad(const GameInputDeviceInfo *info) return false; } +static Uint8 GAMEINPUT_GetDeviceRawType(const GameInputDeviceInfo *info) +{ +#if GAMEINPUT_API_VERSION >= 3 + GameInputKind supportedInput = info->supportedInput; + if (supportedInput & GameInputKindRawDeviceReport) { + switch (info->vendorId) { + case USB_VENDOR_MADCATZ: + switch (info->productId) { + case USB_PRODUCT_MADCATZ_XB1_STRATOCASTER_GUITAR: + return SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR; + case USB_PRODUCT_MADCATZ_XB1_DRUM_KIT: + return SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_DRUM_KIT; + case USB_PRODUCT_MADCATZ_XB1_LEGACY_ADAPTER: + return SDL_GAMEINPUT_RAWTYPE_LEGACY_ADAPTER; + default: + break; + } + break; + case USB_VENDOR_PDP: + switch (info->productId) { + case USB_PRODUCT_PDP_XB1_JAGUAR_GUITAR: + case USB_PRODUCT_PDP_XB1_RIFFMASTER_GUITAR: + return SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR; + case USB_PRODUCT_PDP_XB1_DRUM_KIT: + return SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_DRUM_KIT; + default: + break; + } + break; + case USB_VENDOR_CRKD: + switch (info->productId) { + case USB_PRODUCT_PDP_XB1_JAGUAR_GUITAR: + return SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR; + default: + break; + } + break; + case USB_VENDOR_RED_OCTANE: + switch (info->productId) { + case USB_PRODUCT_RED_OCTANE_XB1_GUITAR_HERO_LIVE_GUITAR: + return SDL_GAMEINPUT_RAWTYPE_GUITAR_HERO_LIVE_GUITAR; + default: + break; + } + break; + } + } +#endif // GAMEINPUT_API_VERSION >= 3 + return SDL_GAMEINPUT_RAWTYPE_NONE; +} static Uint8 GAMEINPUT_GetDeviceSubtype(const GameInputDeviceInfo *info) { GameInputKind supportedInput = info->supportedInput; + Uint8 rawType = GAMEINPUT_GetDeviceRawType(info); + if (rawType == SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR || rawType == SDL_GAMEINPUT_RAWTYPE_GUITAR_HERO_LIVE_GUITAR) { + return SDL_JOYSTICK_TYPE_GUITAR; + } + if (rawType == SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_DRUM_KIT) { + return SDL_JOYSTICK_TYPE_DRUM_KIT; + } if (supportedInput & GameInputKindRacingWheel) { return SDL_JOYSTICK_TYPE_WHEEL; } @@ -132,6 +199,7 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) const char *product_string = NULL; Uint8 driver_signature = 'g'; Uint8 subtype = 0; + int raw_type = SDL_GAMEINPUT_RAWTYPE_NONE; char tmp[4]; int idx = 0; @@ -154,6 +222,7 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) product = info->productId; //version = (info->firmwareVersion.major << 8) | info->firmwareVersion.minor; subtype = GAMEINPUT_GetDeviceSubtype(info); + raw_type = GAMEINPUT_GetDeviceRawType(info); #if GAMEINPUT_API_VERSION >= 1 if (info->displayName) { @@ -177,7 +246,7 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) } #endif - if (!GAMEINPUT_InternalIsGamepad(info)) { + if (!GAMEINPUT_InternalIsGamepad(info) && raw_type == SDL_GAMEINPUT_RAWTYPE_NONE) { #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_DIRECTINPUT, true) || SDL_XINPUT_Enabled()) { // Let other backends handle non-gamepad controllers to possibly avoid bugs and/or regressions. @@ -226,6 +295,7 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, NULL, product_string, driver_signature, subtype); elem->device_instance = SDL_GetNextObjectID(); elem->info = info; + elem->raw_type = raw_type; #if GAMEINPUT_API_VERSION >= 1 elem->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(info->pnpPath); #else @@ -318,11 +388,20 @@ static void CALLBACK GAMEINPUT_InternalJoystickDeviceCallback( static void GAMEINPUT_JoystickDetect(void); static void GAMEINPUT_JoystickQuit(void); +static bool GAMEINPUT_IsRawGameInputEnabled(void) +{ +#if GAMEINPUT_API_VERSION >= 3 + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT_RAW, true); +#else + return false; +#endif +} + static bool GAMEINPUT_JoystickInit(void) { HRESULT hr; - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT) && !GAMEINPUT_IsRawGameInputEnabled()) { return true; } @@ -336,8 +415,16 @@ static bool GAMEINPUT_JoystickInit(void) g_pGameInput->SetFocusPolicy(GameInputEnableBackgroundInput | GameInputEnableBackgroundGuideButton | GameInputEnableBackgroundShareButton); #endif + GameInputKind kind = GameInputKindUnknown; + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) { + kind |= GameInputKindController; + } + if (GAMEINPUT_IsRawGameInputEnabled()) { + kind |= GameInputKindRawDeviceReport; + } + hr = g_pGameInput->RegisterDeviceCallback(NULL, - GameInputKindController, + kind, GameInputDeviceConnected, GameInputBlockingEnumeration, NULL, @@ -527,7 +614,7 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) hwdata->devref = elem; joystick->hwdata = hwdata; - if (GAMEINPUT_InternalIsGamepad(info)) { + if (GAMEINPUT_InternalIsGamepad(info) || GAMEINPUT_GetDeviceRawType(info) != SDL_GAMEINPUT_RAWTYPE_NONE) { joystick->naxes = 6; joystick->nbuttons = 11; joystick->nhats = 1; @@ -612,14 +699,191 @@ static bool GAMEINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool ena return true; } +static void GAMEINPUT_GuitarUpdate(SDL_Joystick *joystick, IGameInputReading *reading, Uint64 timestamp) +{ + IGameInputRawDeviceReport* rawState; + if (reading->GetRawReport(&rawState)) { + static WORD s_GuitarButtons[] = { + 0x0010, // SDL_GAMEPAD_BUTTON_SOUTH + 0x0020, // SDL_GAMEPAD_BUTTON_EAST + 0x0040, // SDL_GAMEPAD_BUTTON_WEST + 0x0080, // SDL_GAMEPAD_BUTTON_NORTH + 0x0008, // SDL_GAMEPAD_BUTTON_BACK + 0, // The guide button is not available + 0x0004, // SDL_GAMEPAD_BUTTON_START + 0, // right joystick click unavailable + 0x4000, // SDL_GAMEPAD_BUTTON_RIGHT_STICK + 0x1000, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER + 0, // right shoulder unavailable + }; + Uint8 btnidx = 0, hat = 0; + uint8_t rawData[40]; + SDL_memset(rawData, 0, sizeof(rawData)); + size_t len = rawState->GetRawData(sizeof(rawData), rawData); + uint16_t buttons = rawData[0] | rawData[1] << 8; + if (len >= 10) { + for (btnidx = 0; btnidx < SDL_arraysize(s_GuitarButtons); ++btnidx) { + WORD button_mask = s_GuitarButtons[btnidx]; + if (!button_mask) { + continue; + } + bool down = ((buttons & button_mask) != 0); + SDL_SendJoystickButton(timestamp, joystick, btnidx, down); + } + if (buttons & 0x0100) { + hat |= SDL_HAT_UP; + } + if (buttons & 0x0200) { + hat |= SDL_HAT_DOWN; + } + if (buttons & 0x0400) { + hat |= SDL_HAT_LEFT; + } + if (buttons & 0x0800) { + hat |= SDL_HAT_RIGHT; + } + SDL_SendJoystickHat(timestamp, joystick, 0, hat); + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, (rawData[3] * 257) - 32768); + // PS3 RB guitars had tilt on right shoulder + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, rawData[2] >= 0xD0); + // PS3 RB guitars send L2 when using solo buttons + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, (rawData[6]) ? 32767 : -32768); + // Align pickup selector mappings with PS3 instruments + static const Sint16 effects_mappings[] = {-26880, -13568, -1792, 11008, 24576}; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, effects_mappings[rawData[4] >> 4]); + } + } +} + +static void GAMEINPUT_GamepadUpdate(SDL_Joystick *joystick, IGameInputReading *reading, Uint64 timestamp) { + GameInputGamepadState state; + static WORD s_XInputButtons[] = { + GameInputGamepadA, // SDL_GAMEPAD_BUTTON_SOUTH + GameInputGamepadB, // SDL_GAMEPAD_BUTTON_EAST + GameInputGamepadX, // SDL_GAMEPAD_BUTTON_WEST + GameInputGamepadY, // SDL_GAMEPAD_BUTTON_NORTH + GameInputGamepadView, // SDL_GAMEPAD_BUTTON_BACK + 0, // The guide button is not available + GameInputGamepadMenu, // SDL_GAMEPAD_BUTTON_START + GameInputGamepadLeftThumbstick, // SDL_GAMEPAD_BUTTON_LEFT_STICK + GameInputGamepadRightThumbstick, // SDL_GAMEPAD_BUTTON_RIGHT_STICK + GameInputGamepadLeftShoulder, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER + GameInputGamepadRightShoulder, // SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER + }; + Uint8 btnidx = 0, hat = 0; + + if (reading->GetGamepadState(&state)) { + for (btnidx = 0; btnidx < SDL_arraysize(s_XInputButtons); ++btnidx) { + WORD button_mask = s_XInputButtons[btnidx]; + if (!button_mask) { + continue; + } + bool down = ((state.buttons & button_mask) != 0); + SDL_SendJoystickButton(timestamp, joystick, btnidx, down); + } + + if (state.buttons & GameInputGamepadDPadUp) { + hat |= SDL_HAT_UP; + } + if (state.buttons & GameInputGamepadDPadDown) { + hat |= SDL_HAT_DOWN; + } + if (state.buttons & GameInputGamepadDPadLeft) { + hat |= SDL_HAT_LEFT; + } + if (state.buttons & GameInputGamepadDPadRight) { + hat |= SDL_HAT_RIGHT; + } + SDL_SendJoystickHat(timestamp, joystick, 0, hat); + +#define CONVERT_AXIS(v) (Sint16)(((v) < 0.0f) ? ((v)*32768.0f) : ((v)*32767.0f)) + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, CONVERT_AXIS(state.leftThumbstickX)); + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, CONVERT_AXIS(-state.leftThumbstickY)); + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, CONVERT_AXIS(state.rightThumbstickX)); + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, CONVERT_AXIS(-state.rightThumbstickY)); +#undef CONVERT_AXIS +#define CONVERT_TRIGGER(v) (Sint16)((v)*65535.0f - 32768.0f) + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, CONVERT_TRIGGER(state.leftTrigger)); + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, CONVERT_TRIGGER(state.rightTrigger)); +#undef CONVERT_TRIGGER + } +} + +static void GAMEINPUT_ControllerUpdate(SDL_Joystick *joystick, IGameInputReading *reading, Uint64 timestamp) +{ + bool *button_state = SDL_stack_alloc(bool, joystick->nbuttons); + float *axis_state = SDL_stack_alloc(float, joystick->naxes); + GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, joystick->nhats); + + if (button_state) { + uint32_t i; + uint32_t button_count = reading->GetControllerButtonState(joystick->nbuttons, button_state); + for (i = 0; i < button_count; ++i) { + SDL_SendJoystickButton(timestamp, joystick, (Uint8)i, button_state[i]); + } + SDL_stack_free(button_state); + } + +#define CONVERT_AXIS(v) (Sint16)((v)*65535.0f - 32768.0f) + if (axis_state) { + uint32_t i; + uint32_t axis_count = reading->GetControllerAxisState(joystick->naxes, axis_state); + for (i = 0; i < axis_count; ++i) { + SDL_SendJoystickAxis(timestamp, joystick, (Uint8)i, CONVERT_AXIS(axis_state[i])); + } + SDL_stack_free(axis_state); + } +#undef CONVERT_AXIS + + if (switch_state) { + uint32_t i; + uint32_t switch_count = reading->GetControllerSwitchState(joystick->nhats, switch_state); + for (i = 0; i < switch_count; ++i) { + Uint8 hat; + switch (switch_state[i]) { + case GameInputSwitchUp: + hat = SDL_HAT_UP; + break; + case GameInputSwitchUpRight: + hat = SDL_HAT_UP | SDL_HAT_RIGHT; + break; + case GameInputSwitchRight: + hat = SDL_HAT_RIGHT; + break; + case GameInputSwitchDownRight: + hat = SDL_HAT_DOWN | SDL_HAT_RIGHT; + break; + case GameInputSwitchDown: + hat = SDL_HAT_DOWN; + break; + case GameInputSwitchDownLeft: + hat = SDL_HAT_DOWN | SDL_HAT_LEFT; + break; + case GameInputSwitchLeft: + hat = SDL_HAT_LEFT; + break; + case GameInputSwitchUpLeft: + hat = SDL_HAT_UP | SDL_HAT_LEFT; + break; + case GameInputSwitchCenter: + default: + hat = SDL_HAT_CENTERED; + break; + } + SDL_SendJoystickHat(timestamp, joystick, (Uint8)i, hat); + } + SDL_stack_free(switch_state); + } +} + static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) { GAMEINPUT_InternalJoystickHwdata *hwdata = joystick->hwdata; + GAMEINPUT_InternalDevice *internal_device = hwdata->devref; IGameInputDevice *device = hwdata->devref->device; const GameInputDeviceInfo *info = hwdata->devref->info; IGameInputReading *reading = NULL; Uint64 timestamp; - GameInputGamepadState state; HRESULT hr; hr = g_pGameInput->GetCurrentReading(info->supportedInput, device, &reading); @@ -629,122 +893,12 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) } timestamp = SDL_US_TO_NS(reading->GetTimestamp() + g_GameInputTimestampOffset); - - if (GAMEINPUT_InternalIsGamepad(info)) { - static WORD s_XInputButtons[] = { - GameInputGamepadA, // SDL_GAMEPAD_BUTTON_SOUTH - GameInputGamepadB, // SDL_GAMEPAD_BUTTON_EAST - GameInputGamepadX, // SDL_GAMEPAD_BUTTON_WEST - GameInputGamepadY, // SDL_GAMEPAD_BUTTON_NORTH - GameInputGamepadView, // SDL_GAMEPAD_BUTTON_BACK - 0, // The guide button is not available - GameInputGamepadMenu, // SDL_GAMEPAD_BUTTON_START - GameInputGamepadLeftThumbstick, // SDL_GAMEPAD_BUTTON_LEFT_STICK - GameInputGamepadRightThumbstick, // SDL_GAMEPAD_BUTTON_RIGHT_STICK - GameInputGamepadLeftShoulder, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER - GameInputGamepadRightShoulder, // SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER - }; - Uint8 btnidx = 0, hat = 0; - - if (reading->GetGamepadState(&state)) { - for (btnidx = 0; btnidx < SDL_arraysize(s_XInputButtons); ++btnidx) { - WORD button_mask = s_XInputButtons[btnidx]; - if (!button_mask) { - continue; - } - bool down = ((state.buttons & button_mask) != 0); - SDL_SendJoystickButton(timestamp, joystick, btnidx, down); - } - - if (state.buttons & GameInputGamepadDPadUp) { - hat |= SDL_HAT_UP; - } - if (state.buttons & GameInputGamepadDPadDown) { - hat |= SDL_HAT_DOWN; - } - if (state.buttons & GameInputGamepadDPadLeft) { - hat |= SDL_HAT_LEFT; - } - if (state.buttons & GameInputGamepadDPadRight) { - hat |= SDL_HAT_RIGHT; - } - SDL_SendJoystickHat(timestamp, joystick, 0, hat); - -#define CONVERT_AXIS(v) (Sint16)(((v) < 0.0f) ? ((v)*32768.0f) : ((v)*32767.0f)) - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, CONVERT_AXIS(state.leftThumbstickX)); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, CONVERT_AXIS(-state.leftThumbstickY)); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, CONVERT_AXIS(state.rightThumbstickX)); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, CONVERT_AXIS(-state.rightThumbstickY)); -#undef CONVERT_AXIS -#define CONVERT_TRIGGER(v) (Sint16)((v)*65535.0f - 32768.0f) - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, CONVERT_TRIGGER(state.leftTrigger)); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, CONVERT_TRIGGER(state.rightTrigger)); -#undef CONVERT_TRIGGER - } + if (internal_device->raw_type == SDL_GAMEINPUT_RAWTYPE_ROCK_BAND_GUITAR) { + GAMEINPUT_GuitarUpdate(joystick, reading, timestamp); + } else if (GAMEINPUT_InternalIsGamepad(info)) { + GAMEINPUT_GamepadUpdate(joystick, reading, timestamp); } else { - bool *button_state = SDL_stack_alloc(bool, joystick->nbuttons); - float *axis_state = SDL_stack_alloc(float, joystick->naxes); - GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, joystick->nhats); - - if (button_state) { - uint32_t i; - uint32_t button_count = reading->GetControllerButtonState(joystick->nbuttons, button_state); - for (i = 0; i < button_count; ++i) { - SDL_SendJoystickButton(timestamp, joystick, (Uint8)i, button_state[i]); - } - SDL_stack_free(button_state); - } - -#define CONVERT_AXIS(v) (Sint16)((v)*65535.0f - 32768.0f) - if (axis_state) { - uint32_t i; - uint32_t axis_count = reading->GetControllerAxisState(joystick->naxes, axis_state); - for (i = 0; i < axis_count; ++i) { - SDL_SendJoystickAxis(timestamp, joystick, (Uint8)i, CONVERT_AXIS(axis_state[i])); - } - SDL_stack_free(axis_state); - } -#undef CONVERT_AXIS - - if (switch_state) { - uint32_t i; - uint32_t switch_count = reading->GetControllerSwitchState(joystick->nhats, switch_state); - for (i = 0; i < switch_count; ++i) { - Uint8 hat; - switch (switch_state[i]) { - case GameInputSwitchUp: - hat = SDL_HAT_UP; - break; - case GameInputSwitchUpRight: - hat = SDL_HAT_UP | SDL_HAT_RIGHT; - break; - case GameInputSwitchRight: - hat = SDL_HAT_RIGHT; - break; - case GameInputSwitchDownRight: - hat = SDL_HAT_DOWN | SDL_HAT_RIGHT; - break; - case GameInputSwitchDown: - hat = SDL_HAT_DOWN; - break; - case GameInputSwitchDownLeft: - hat = SDL_HAT_DOWN | SDL_HAT_LEFT; - break; - case GameInputSwitchLeft: - hat = SDL_HAT_LEFT; - break; - case GameInputSwitchUpLeft: - hat = SDL_HAT_UP | SDL_HAT_LEFT; - break; - case GameInputSwitchCenter: - default: - hat = SDL_HAT_CENTERED; - break; - } - SDL_SendJoystickHat(timestamp, joystick, (Uint8)i, hat); - } - SDL_stack_free(switch_state); - } + GAMEINPUT_ControllerUpdate(joystick, reading, timestamp); } #ifdef GAMEINPUT_SENSOR_SUPPORT @@ -821,7 +975,7 @@ static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap { GAMEINPUT_InternalDevice *elem = GAMEINPUT_InternalFindByIndex(device_index); - if (!GAMEINPUT_InternalIsGamepad(elem->info)) { + if (!GAMEINPUT_InternalIsGamepad(elem->info) && elem->raw_type == SDL_GAMEINPUT_RAWTYPE_NONE) { return false; } diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h index e2afd509da..6095f1eb66 100644 --- a/src/joystick/usb_ids.h +++ b/src/joystick/usb_ids.h @@ -53,6 +53,7 @@ #define USB_VENDOR_POWERA_ALT 0x20d6 #define USB_VENDOR_QANBA 0x2c22 #define USB_VENDOR_RAZER 0x1532 +#define USB_VENDOR_RED_OCTANE 0x1430 #define USB_VENDOR_SAITEK 0x06a3 #define USB_VENDOR_SCEA 0x12ba #define USB_VENDOR_SHANWAN 0x2563 @@ -102,6 +103,9 @@ #define USB_PRODUCT_LOGITECH_F310 0xc216 #define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1 #define USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK 0x2218 +#define USB_PRODUCT_MADCATZ_XB1_STRATOCASTER_GUITAR 0x4161 +#define USB_PRODUCT_MADCATZ_XB1_DRUM_KIT 0x4262 +#define USB_PRODUCT_MADCATZ_XB1_LEGACY_ADAPTER 0x4164 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRELESS 0x0d16 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRED 0x0d17 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS 0x0d18 @@ -127,6 +131,9 @@ #define USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V104 0x7214 #define USB_PRODUCT_PDP_ROCK_CANDY 0x0246 #define USB_PRODUCT_PDP_REALMZ_WIRELESS 0x018c +#define USB_PRODUCT_PDP_XB1_DRUM_KIT 0x0171 +#define USB_PRODUCT_PDP_XB1_JAGUAR_GUITAR 0x0170 +#define USB_PRODUCT_PDP_XB1_RIFFMASTER_GUITAR 0x0248 #define USB_PRODUCT_POWERA_MINI 0x541a #define USB_PRODUCT_RAZER_ATROX 0x0a00 #define USB_PRODUCT_RAZER_KITSUNE 0x1012 @@ -146,6 +153,7 @@ #define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRED 0x1010 #define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRELESS 0x1011 #define USB_PRODUCT_RAZER_WOLVERINE_V3_PRO 0x0a3f +#define USB_PRODUCT_RED_OCTANE_XB1_GUITAR_HERO_LIVE_GUITAR 0x0170 #define USB_PRODUCT_SAITEK_CYBORG_V3 0xf622 #define USB_PRODUCT_SCEA_PS3_GH_GUITAR 0x0100 #define USB_PRODUCT_SCEA_PS3_GH_DRUMS 0x0120 From 5c8714cc957cad0f8504d0d384e45029f91b59e3 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 3 Apr 2026 23:03:43 +0000 Subject: [PATCH 064/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_hints.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 0c1a19d36d..d01f36f8a9 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -1445,10 +1445,10 @@ extern "C" { #define SDL_HINT_JOYSTICK_GAMEINPUT "SDL_JOYSTICK_GAMEINPUT" /** - * A variable controlling whether GameInput should be used for handling - * GIP devices that require raw report processing, but aren't supported - * by HIDRAW, such as Xbox One Guitars. - * + * A variable controlling whether GameInput should be used for handling GIP + * devices that require raw report processing, but aren't supported by HIDRAW, + * such as Xbox One Guitars. + * * Note that this is only supported with GameInput 3 or newer. * * The variable can be set to the following values: From 41c3a910792bc913d3d530cab67711105c5d743e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 3 Apr 2026 16:07:49 -0700 Subject: [PATCH 065/407] Use the correct index for PS2 controllers Closes https://github.com/libsdl-org/SDL/pull/15294 --- src/joystick/ps2/SDL_sysjoystick.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/joystick/ps2/SDL_sysjoystick.c b/src/joystick/ps2/SDL_sysjoystick.c index e8ac2bbc2e..36a4dc09b0 100644 --- a/src/joystick/ps2/SDL_sysjoystick.c +++ b/src/joystick/ps2/SDL_sysjoystick.c @@ -258,8 +258,7 @@ static void PS2_InitializePad(int port, int slot) */ static bool PS2_JoystickOpen(SDL_Joystick *joystick, int device_index) { - int index = joystick->instance_id; - struct JoyInfo *info = &joyInfo[index]; + struct JoyInfo *info = &joyInfo[device_index]; if (!info->opened) { if (padPortOpen(info->port, info->slot, (void *)info->padBuf) > 0) { @@ -284,7 +283,7 @@ static bool PS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumb { char actAlign[6]; int res; - int index = joystick->instance_id; + int index = (int)(joystick->instance_id - 1); struct JoyInfo *info = &joyInfo[index]; if (!rumble_status(index)) { @@ -339,7 +338,7 @@ static void PS2_JoystickUpdate(SDL_Joystick *joystick) uint16_t mask, previous, current; struct padButtonStatus buttons; uint8_t all_axis[PS2_TOTAL_AXIS]; - int index = joystick->instance_id; + int index = (int)(joystick->instance_id - 1); struct JoyInfo *info = &joyInfo[index]; int state = padGetState(info->port, info->slot); Uint64 timestamp = SDL_GetTicksNS(); @@ -384,7 +383,7 @@ static void PS2_JoystickUpdate(SDL_Joystick *joystick) // Function to close a joystick after use static void PS2_JoystickClose(SDL_Joystick *joystick) { - int index = joystick->instance_id; + int index = (int)(joystick->instance_id - 1); struct JoyInfo *info = &joyInfo[index]; padPortClose(info->port, info->slot); info->opened = 0; From 173adc1bf6e1227b944d31b971f75d91d427a4bc Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 4 Apr 2026 08:12:51 -0700 Subject: [PATCH 066/407] Enable npot texture wrapping if GL_OES_texture_npot is available --- src/render/opengles2/SDL_render_gles2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 52423884dc..8f4dc4eb56 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -2464,7 +2464,9 @@ static bool GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL // Full NPOT textures (that can use GL_REPEAT, etc) are a core feature of GLES3, // and an extension in GLES2. - if ((major < 3) && !SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) { + if (major < 3 && + !SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two") && + !SDL_GL_ExtensionSupported("GL_OES_texture_npot")) { renderer->npot_texture_wrap_unsupported = true; } From fc2f4fcc225d0c61eb8155245b05fe8c0a01454b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 4 Apr 2026 10:07:58 -0700 Subject: [PATCH 067/407] Send SDL_EVENT_SCREEN_KEYBOARD_HIDDEN when the keyboard is hidden on Android --- .../app/src/main/java/org/libsdl/app/SDLSurface.java | 6 ++++++ src/video/SDL_video.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java index 1579b73345..42eceb5096 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java @@ -208,6 +208,12 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, WindowInsets.Type.displayCutout()); SDLActivity.onNativeInsetsChanged(combined.left, combined.right, combined.top, combined.bottom); + + if (insets.isVisible(WindowInsets.Type.ime())) { + SDLActivity.onNativeScreenKeyboardShown(); + } else { + SDLActivity.onNativeScreenKeyboardHidden(); + } } // Pass these to any child views in case they need them diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index a338645c96..764eee219d 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -5900,7 +5900,7 @@ bool SDL_ScreenKeyboardShown(SDL_Window *window) void SDL_SendScreenKeyboardShown(void) { - if (_this->screen_keyboard_shown) { + if (!_this || _this->screen_keyboard_shown) { return; } @@ -5916,7 +5916,7 @@ void SDL_SendScreenKeyboardShown(void) void SDL_SendScreenKeyboardHidden(void) { - if (!_this->screen_keyboard_shown) { + if (!_this || !_this->screen_keyboard_shown) { return; } From 25aa1c643f53bc3f1901d1725e48c7d054c40053 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 4 Apr 2026 15:24:05 +0200 Subject: [PATCH 068/407] CMake: Replace CMAKE_COMPILER_IS_GNUCC with CMAKE_C_COMPILER_ID CMAKE_COMPILER_IS_GNUCC is obsolete variable and can be replaced with CMAKE_C_COMPILER_ID (also available since early CMake versions). In the past CMake versions also LCC and QCC compilers had this varible set to boolean true but these aren't relevant here. --- cmake/sdlcompilers.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/sdlcompilers.cmake b/cmake/sdlcompilers.cmake index f9d5a9c313..87b00bbd70 100644 --- a/cmake/sdlcompilers.cmake +++ b/cmake/sdlcompilers.cmake @@ -11,7 +11,7 @@ macro(SDL_DetectCompiler) if(MSVC) set(MSVC_CLANG TRUE) endif() - elseif(CMAKE_COMPILER_IS_GNUCC) + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") set(USE_GCC TRUE) elseif(CMAKE_C_COMPILER_ID MATCHES "^Intel$") set(USE_INTELCC TRUE) From c85786181511cf567516b362b0d16adde26d7350 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Sat, 4 Apr 2026 14:01:45 +0500 Subject: [PATCH 069/407] Add support for Oklick W-2 racing wheel controller This PR adds the proper mapping for this racing wheel controller to comply with XInput documentation (mostly to treat the pedals as the trigger axes). --- src/joystick/SDL_gamepad.c | 2 +- src/joystick/SDL_gamepad_db.h | 1 + src/joystick/SDL_joystick.c | 11 ++++++++--- src/joystick/SDL_joystick_c.h | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 71e7b2524b..3d2171e73e 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1087,7 +1087,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL); - if (SDL_IsJoystickWheel(vendor, product)) { + if (SDL_IsJoystickWheel(vendor, product, 0)) { // We don't want to pick up Logitech FFB wheels here // Some versions of WINE will also not treat devices that show up as gamepads as wheels return NULL; diff --git a/src/joystick/SDL_gamepad_db.h b/src/joystick/SDL_gamepad_db.h index 476ead6f44..89bfe56624 100644 --- a/src/joystick/SDL_gamepad_db.h +++ b/src/joystick/SDL_gamepad_db.h @@ -212,6 +212,7 @@ static const char *s_GamepadMappings[] = { "03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,", "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,", + "03000000ff1100003133000000000000,Oklick W-2,crc:faf6,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a1,leftx:a0,rightshoulder:b5,rightstick:b11,righttrigger:-a1,start:b9,x:b0,y:b1,", "03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,", "03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,", diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 1dbcdce8b5..c9b15f6097 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3425,8 +3425,12 @@ bool SDL_IsJoystickVIRTUAL(SDL_GUID guid) return (guid.data[14] == 'v') ? true : false; } -bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id) +bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id, Uint16 crc) { + if (vendor_id == 0x11FF && product_id == 0x3331 && crc == 0xFAF6) { + // Oklick W-2 racing wheel controller (on Windows via DirectInput). + return true; + } return SDL_VIDPIDInList(vendor_id, product_id, &wheel_devices); } @@ -3459,10 +3463,11 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_GUID guid) { Uint16 vendor; Uint16 product; + Uint16 crc; - SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, &crc); - if (SDL_IsJoystickWheel(vendor, product)) { + if (SDL_IsJoystickWheel(vendor, product, crc)) { return SDL_JOYSTICK_TYPE_WHEEL; } diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 46acbc5ca8..62e1f9f865 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -172,7 +172,7 @@ extern bool SDL_IsJoystickRAWINPUT(SDL_GUID guid); extern bool SDL_IsJoystickVIRTUAL(SDL_GUID guid); // Function to return whether a joystick is a wheel -extern bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id); +extern bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id, Uint16 crc); // Function to return whether a joystick should be ignored extern bool SDL_ShouldIgnoreJoystick(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); From 19f70284adcbdde918267e77325df309a267098c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 4 Apr 2026 11:36:10 -0700 Subject: [PATCH 070/407] Document that you can pass -1 to SDL_WaitEventTimeout() to wait indefinitely --- include/SDL3/SDL_events.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index 8c6e0cd8c5..fa923b0d1e 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -1343,7 +1343,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitEvent(SDL_Event *event); * \param event the SDL_Event structure to be filled in with the next event * from the queue, or NULL. * \param timeoutMS the maximum number of milliseconds to wait for the next - * available event. + * available event, or -1 to wait indefinitely. * \returns true if this got an event or false if the timeout elapsed without * any events available. * From 8b00b57468a7ec32f9735a53ca2664800593cf90 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 5 Apr 2026 01:08:07 -0400 Subject: [PATCH 071/407] filesystem: Rename a variable named "append" that is actually prepending. (Strictly speaking, this was probably meant to be an "append" to the home/base directory before the org/app name are appended to _that_, but it's definitely added to the absolute start of the string on Emscripten, so might as well make all of these match. Reference PR #15262. --- src/filesystem/emscripten/SDL_sysfilesystem.c | 10 +++++----- src/filesystem/haiku/SDL_sysfilesystem.cc | 10 +++++----- src/filesystem/unix/SDL_sysfilesystem.c | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/filesystem/emscripten/SDL_sysfilesystem.c b/src/filesystem/emscripten/SDL_sysfilesystem.c index 0d21cd2698..3156af5cd5 100644 --- a/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -40,22 +40,22 @@ char *SDL_SYS_GetBasePath(void) char *SDL_SYS_GetPrefPath(const char *org, const char *app) { #ifdef SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING - const char *append = SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING; + const char *prepend = SDL_EMSCRIPTEN_PERSISTENT_PATH_STRING; #else - const char *append = "/libsdl"; + const char *prepend = "/libsdl"; #endif char *result; char *ptr = NULL; - const size_t len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 4; + const size_t len = SDL_strlen(prepend) + SDL_strlen(org) + SDL_strlen(app) + 4; result = (char *)SDL_malloc(len); if (!result) { return NULL; } if (*org) { - SDL_snprintf(result, len, "%s/%s/%s/", append, org, app); + SDL_snprintf(result, len, "%s/%s/%s/", prepend, org, app); } else { - SDL_snprintf(result, len, "%s/%s/", append, app); + SDL_snprintf(result, len, "%s/%s/", prepend, app); } for (ptr = result + 1; *ptr; ptr++) { diff --git a/src/filesystem/haiku/SDL_sysfilesystem.cc b/src/filesystem/haiku/SDL_sysfilesystem.cc index 380e05ce1e..48bfb1ed6a 100644 --- a/src/filesystem/haiku/SDL_sysfilesystem.cc +++ b/src/filesystem/haiku/SDL_sysfilesystem.cc @@ -69,19 +69,19 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app) { // !!! FIXME: is there a better way to do this? const char *home = SDL_getenv("HOME"); - const char *append = "/config/settings/"; + const char *prepend = "/config/settings/"; size_t len = SDL_strlen(home); if (!len || (home[len - 1] == '/')) { - ++append; // home empty or ends with separator, skip the one from append + ++prepend; // home empty or ends with separator, skip the one from prepend } - len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3; + len += SDL_strlen(prepend) + SDL_strlen(org) + SDL_strlen(app) + 3; char *result = (char *) SDL_malloc(len); if (result) { if (*org) { - SDL_snprintf(result, len, "%s%s%s/%s/", home, append, org, app); + SDL_snprintf(result, len, "%s%s%s/%s/", home, prepend, org, app); } else { - SDL_snprintf(result, len, "%s%s%s/", home, append, app); + SDL_snprintf(result, len, "%s%s%s/", home, prepend, app); } create_directory(result, 0700); // Haiku api: creates missing dirs } diff --git a/src/filesystem/unix/SDL_sysfilesystem.c b/src/filesystem/unix/SDL_sysfilesystem.c index 9edbf6dc0b..9cba8db2eb 100644 --- a/src/filesystem/unix/SDL_sysfilesystem.c +++ b/src/filesystem/unix/SDL_sysfilesystem.c @@ -266,7 +266,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app) * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html */ const char *envr = SDL_getenv("XDG_DATA_HOME"); - const char *append; + const char *prepend; char *result = NULL; char *ptr = NULL; @@ -278,26 +278,26 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app) SDL_SetError("neither XDG_DATA_HOME nor HOME environment is set"); return NULL; } - append = "/.local/share/"; + prepend = "/.local/share/"; } else { - append = "/"; + prepend = "/"; } size_t len = SDL_strlen(envr); if (envr[len - 1] == '/') { - append += 1; + prepend += 1; } - len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3; + len += SDL_strlen(prepend) + SDL_strlen(org) + SDL_strlen(app) + 3; result = (char *)SDL_malloc(len); if (!result) { return NULL; } if (*org) { - (void)SDL_snprintf(result, len, "%s%s%s/%s/", envr, append, org, app); + (void)SDL_snprintf(result, len, "%s%s%s/%s/", envr, prepend, org, app); } else { - (void)SDL_snprintf(result, len, "%s%s%s/", envr, append, app); + (void)SDL_snprintf(result, len, "%s%s%s/", envr, prepend, app); } for (ptr = result + 1; *ptr; ptr++) { From 1442c5a4a0b97e697362c44983a62eed46e29856 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 5 Apr 2026 01:12:08 -0400 Subject: [PATCH 072/407] emscripten: Added more variables to PreseedEmscriptenCache.cmake. --- cmake/PreseedEmscriptenCache.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/PreseedEmscriptenCache.cmake b/cmake/PreseedEmscriptenCache.cmake index 78504a5d5f..1d75a4aca4 100644 --- a/cmake/PreseedEmscriptenCache.cmake +++ b/cmake/PreseedEmscriptenCache.cmake @@ -181,5 +181,13 @@ if(EMSCRIPTEN) set(HAVE_PPOLL "" CACHE INTERNAL "Have symbol ppoll") set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR "" CACHE INTERNAL "Have symbol posix_spawn_file_actions_addchdir") set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP "1" CACHE INTERNAL "Have symbol posix_spawn_file_actions_addchdir_np") + set(LIBC_HAS_VFORK "1" CACHE INTERNAL "Have symbol vfork") + set(HAVE_GETRESUID "1" CACHE INTERNAL "Have symbol getresuid") + set(HAVE_GETRESGID "1" CACHE INTERNAL "Have symbol getresgid") + set(HAVE_LIBUDEV_H "" CACHE INTERNAL "Have include libudev.h") + set(HAVE_WFORMAT "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT") + set(HAVE_WFORMAT_OVERFLOW "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT_OVERFLOW") + set(HAVE_WFORMAT_EXTRA_ARGS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT_EXTRA_ARGS") + set(COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS") endfunction() endif() From 6f7fb0a3dcc4b157208513d3354b9407e7a87baf Mon Sep 17 00:00:00 2001 From: Jesse Chounard Date: Sun, 5 Apr 2026 11:40:16 -0500 Subject: [PATCH 073/407] Add text input properties for on-screen keyboard customization --- include/SDL3/SDL_keyboard.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h index d14ab6fb27..0d3d67033b 100644 --- a/include/SDL3/SDL_keyboard.h +++ b/include/SDL3/SDL_keyboard.h @@ -449,6 +449,14 @@ typedef enum SDL_Capitalization * are allowed. This defaults to true if SDL_HINT_RETURN_KEY_HIDES_IME is * "0" or is not set, and defaults to false if SDL_HINT_RETURN_KEY_HIDES_IME * is "1". + * - `SDL_PROP_TEXTINPUT_TITLE_STRING` - a title for the top of the on-screen + * keyboard window, if it has one. + * - `SDL_PROP_TEXTINPUT_PLACEHOLDER_STRING` - the placeholder shown before the + * user starts typing, when the field is empty. + * - `SDL_PROP_TEXTINPUT_DEFAULT_TEXT_STRING` - text to prefill the text field + * with. + * - `SDL_PROP_TEXTINPUT_MAX_LENGTH_NUMBER` - maximum length for the text field, + * in characters (not bytes). * * On Android you can directly specify the input type: * @@ -476,6 +484,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_StartTextInputWithProperties(SDL_Window *wi #define SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER "SDL.textinput.capitalization" #define SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN "SDL.textinput.autocorrect" #define SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN "SDL.textinput.multiline" +#define SDL_PROP_TEXTINPUT_TITLE_STRING "SDL.textinput.title" +#define SDL_PROP_TEXTINPUT_PLACEHOLDER_STRING "SDL.textinput.placeholder" +#define SDL_PROP_TEXTINPUT_DEFAULT_TEXT_STRING "SDL.textinput.default_text" +#define SDL_PROP_TEXTINPUT_MAX_LENGTH_NUMBER "SDL.textinput.max_length" #define SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER "SDL.textinput.android.inputtype" /** From f8feccfa46714395a3b3cf508dc96efa7e7dc655 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Sun, 5 Apr 2026 18:33:22 +0000 Subject: [PATCH 074/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_keyboard.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h index 0d3d67033b..da0a4185b0 100644 --- a/include/SDL3/SDL_keyboard.h +++ b/include/SDL3/SDL_keyboard.h @@ -451,12 +451,12 @@ typedef enum SDL_Capitalization * is "1". * - `SDL_PROP_TEXTINPUT_TITLE_STRING` - a title for the top of the on-screen * keyboard window, if it has one. - * - `SDL_PROP_TEXTINPUT_PLACEHOLDER_STRING` - the placeholder shown before the - * user starts typing, when the field is empty. + * - `SDL_PROP_TEXTINPUT_PLACEHOLDER_STRING` - the placeholder shown before + * the user starts typing, when the field is empty. * - `SDL_PROP_TEXTINPUT_DEFAULT_TEXT_STRING` - text to prefill the text field * with. - * - `SDL_PROP_TEXTINPUT_MAX_LENGTH_NUMBER` - maximum length for the text field, - * in characters (not bytes). + * - `SDL_PROP_TEXTINPUT_MAX_LENGTH_NUMBER` - maximum length for the text + * field, in characters (not bytes). * * On Android you can directly specify the input type: * From 682da4ee9885c28bccf0dee832f3089b0abca547 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sat, 4 Apr 2026 22:28:06 -0400 Subject: [PATCH 075/407] misc: Use the OpenURI D-Bus portal for opening URLs This works inside of containers, and supports passing an activation token with the request, which is needed on Wayland to transfer focus to the browser. --- src/core/linux/SDL_dbus.c | 57 ++++++++++++ src/core/linux/SDL_dbus.h | 2 + src/misc/unix/SDL_sysurl.c | 39 ++++++++ src/video/wayland/SDL_waylandutil.c | 134 ++++++++++++++++++++++++++++ src/video/wayland/SDL_waylandutil.h | 34 +++++++ test/testurl.c | 52 ++++++++--- 6 files changed, 307 insertions(+), 11 deletions(-) create mode 100644 src/video/wayland/SDL_waylandutil.c create mode 100644 src/video/wayland/SDL_waylandutil.h diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 2d083e8f29..df114e0e19 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -471,6 +471,63 @@ static bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const cha return SDL_DBus_AppendDictWithKeysAndValues(iterInit, keys, values, 1); } +bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token) +{ + const char *bus_name = "org.freedesktop.portal.Desktop"; + const char *path = "/org/freedesktop/portal/desktop"; + const char *interface = "org.freedesktop.portal.OpenURI"; + DBusMessageIter iterInit; + bool ret = false; + + if (!dbus.session_conn) { + /* We either lost connection to the session bus or were not able to + * load the D-Bus library at all. + */ + return false; + } + + DBusMessage *msg = dbus.message_new_method_call(bus_name, path, interface, "OpenURI"); + if (!msg) { + return false; + } + + if (!window_id) { + window_id = ""; + } + if (!dbus.message_append_args(msg, DBUS_TYPE_STRING, &window_id, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID)) { + goto done; + } + + dbus.message_iter_init_append(msg, &iterInit); + + if (activation_token) { + if (!SDL_DBus_AppendDictWithKeyValue(&iterInit, "activation_token", activation_token)) { + goto done; + } + } else { + // The array must be in the parameter list, even if empty. + DBusMessageIter iterArray; + if (!dbus.message_iter_open_container(&iterInit, DBUS_TYPE_ARRAY, "{sv}", &iterArray)) { + goto done; + } + if (!dbus.message_iter_close_container(&iterInit, &iterArray)) { + goto done; + } + } + + { + DBusMessage *reply = dbus.connection_send_with_reply_and_block(dbus.session_conn, msg, -1, NULL); + if (reply) { + ret = true; + dbus.message_unref(reply); + } + } + +done: + dbus.message_unref(msg); + return ret; +} + bool SDL_DBus_ScreensaverInhibit(bool inhibit) { const char *default_inhibit_reason = "Playing a game"; diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index e6f81b48ac..568dd74bb2 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -119,6 +119,8 @@ extern void SDL_DBus_FreeReply(DBusMessage **saved_reply); extern void SDL_DBus_ScreensaverTickle(void); extern bool SDL_DBus_ScreensaverInhibit(bool inhibit); +extern bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token); + extern void SDL_DBus_PumpEvents(void); extern char *SDL_DBus_GetLocalMachineId(void); diff --git a/src/misc/unix/SDL_sysurl.c b/src/misc/unix/SDL_sysurl.c index 8745576e2c..32e2d476ea 100644 --- a/src/misc/unix/SDL_sysurl.c +++ b/src/misc/unix/SDL_sysurl.c @@ -33,8 +33,42 @@ extern char **environ; #endif +#ifdef HAVE_DBUS_DBUS_H +#include "../../core/linux/SDL_dbus.h" +#endif + +#ifdef SDL_VIDEO_DRIVER_WAYLAND +#include "../../video/wayland/SDL_waylandutil.h" +#endif + +// Wayland requires an activation token for the browser to take focus. +static void GetActivationToken(char **token, char **window_id) +{ +#ifdef SDL_VIDEO_DRIVER_WAYLAND + SDL_VideoDevice *vid = SDL_GetVideoDevice(); + + if (vid && SDL_strcmp(vid->name, "wayland") == 0) { + Wayland_GetActivationTokenForExport(vid, token, window_id); + } +#endif +} + bool SDL_SYS_OpenURL(const char *url) { + char *activation_token = NULL; + char *window_id = NULL; + + GetActivationToken(&activation_token, &window_id); + + // Prefer the D-Bus portal, if available. +#ifdef HAVE_DBUS_DBUS_H + if (SDL_DBus_OpenURI(url, window_id, activation_token)) { + SDL_free(activation_token); + SDL_free(window_id); + return true; + } +#endif + const char *args[] = { "xdg-open", url, NULL }; SDL_Environment *env = NULL; SDL_Process *process = NULL; @@ -47,6 +81,9 @@ bool SDL_SYS_OpenURL(const char *url) // Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam SDL_UnsetEnvironmentVariable(env, "LD_PRELOAD"); + if (activation_token) { + SDL_SetEnvironmentVariable(env, "XDG_ACTIVATION_TOKEN", activation_token, false); + } SDL_PropertiesID props = SDL_CreateProperties(); if (!props) { @@ -64,6 +101,8 @@ bool SDL_SYS_OpenURL(const char *url) result = true; done: + SDL_free(activation_token); + SDL_free(window_id); SDL_DestroyEnvironment(env); SDL_DestroyProcess(process); diff --git a/src/video/wayland/SDL_waylandutil.c b/src/video/wayland/SDL_waylandutil.c new file mode 100644 index 0000000000..d6461cb071 --- /dev/null +++ b/src/video/wayland/SDL_waylandutil.c @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL_waylandevents_c.h" +#include "SDL_waylandutil.h" +#include "xdg-activation-v1-client-protocol.h" + +#define WAYLAND_HANDLE_PREFIX "wayland:" + +typedef struct Wayland_ActivationParams +{ + char **token; + bool done; +} Wayland_ActivationParams; + +static void handle_xdg_activation_done(void *data, struct xdg_activation_token_v1 *xdg_activation_token_v1, const char *token) +{ + Wayland_ActivationParams *activation_params = (Wayland_ActivationParams *)data; + *activation_params->token = SDL_strdup(token); + activation_params->done = true; + + xdg_activation_token_v1_destroy(xdg_activation_token_v1); +} + +static const struct xdg_activation_token_v1_listener xdg_activation_listener = { + handle_xdg_activation_done +}; + +bool Wayland_GetActivationTokenForExport(SDL_VideoDevice *_this, char **token, char **window_id) +{ + if (!_this || !token) { + return false; + } + + SDL_VideoData *viddata = _this->internal; + + SDL_WaylandSeat *seat = viddata->last_implicit_grab_seat; + SDL_WindowData *focus = NULL; + + if (seat) { + focus = seat->keyboard.focus; + if (!focus) { + focus = seat->pointer.focus; + } + } + + const char *xdg_activation_token = SDL_getenv("XDG_ACTIVATION_TOKEN"); + if (xdg_activation_token) { + *token = SDL_strdup(xdg_activation_token); + if (!*token) { + return false; + } + + // Unset the envvar after claiming the token. + SDL_unsetenv_unsafe("XDG_ACTIVATION_TOKEN"); + } else if (viddata->activation_manager) { + struct wl_surface *requesting_surface = focus ? focus->surface : NULL; + Wayland_ActivationParams params = { + .token = token, + .done = false + }; + + struct wl_event_queue *activation_token_queue = Wayland_DisplayCreateQueue(viddata->display, "SDL Activation Token Generation Queue"); + + struct wl_proxy *activation_manager_wrapper = WAYLAND_wl_proxy_create_wrapper(viddata->activation_manager); + WAYLAND_wl_proxy_set_queue(activation_manager_wrapper, activation_token_queue); + struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token((struct xdg_activation_v1 *)activation_manager_wrapper); + xdg_activation_token_v1_add_listener(activation_token, &xdg_activation_listener, ¶ms); + + if (requesting_surface) { + // This specifies the surface from which the activation request is originating, not the activation target surface. + xdg_activation_token_v1_set_surface(activation_token, requesting_surface); + } + if (seat && seat->wl_seat) { + xdg_activation_token_v1_set_serial(activation_token, seat->last_implicit_grab_serial, seat->wl_seat); + } + if (focus && focus->app_id) { + // Set the app ID for external use. + xdg_activation_token_v1_set_app_id(activation_token, focus->app_id); + } + xdg_activation_token_v1_commit(activation_token); + + while (!params.done) { + WAYLAND_wl_display_dispatch_queue(viddata->display, activation_token_queue); + } + WAYLAND_wl_proxy_wrapper_destroy(activation_manager_wrapper); + WAYLAND_wl_event_queue_destroy(activation_token_queue); + + if (!*token) { + return false; + } + } + + if (focus && window_id) { + const char *id = SDL_GetStringProperty(focus->sdlwindow->props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_EXPORT_HANDLE_STRING, NULL); + if (id) { + const size_t len = SDL_strlen(id) + sizeof(WAYLAND_HANDLE_PREFIX) + 1; + *window_id = SDL_malloc(len); + if (!*window_id) { + SDL_free(*token); + *token = NULL; + return false; + } + + SDL_strlcpy(*window_id, WAYLAND_HANDLE_PREFIX, len); + SDL_strlcat(*window_id, id, len); + } + } + + return true; +} + +#endif // SDL_VIDEO_DRIVER_WAYLAND diff --git a/src/video/wayland/SDL_waylandutil.h b/src/video/wayland/SDL_waylandutil.h new file mode 100644 index 0000000000..daad6effb3 --- /dev/null +++ b/src/video/wayland/SDL_waylandutil.h @@ -0,0 +1,34 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifndef SDL_waylandutil_h_ +#define SDL_waylandutil_h_ + +#include "../SDL_sysvideo.h" + +/** + * Generates an activation token that can be passed to external clients. + * The token and window_id parameters must be freed with SDL_free() when done. + */ +extern bool Wayland_GetActivationTokenForExport(SDL_VideoDevice *_this, char **token, char **window_id); + +#endif // SDL_waylandutil_h_ diff --git a/test/testurl.c b/test/testurl.c index 56b1904e6a..a6fd9c5ec4 100644 --- a/test/testurl.c +++ b/test/testurl.c @@ -25,29 +25,27 @@ static void tryOpenURL(const char *url) int main(int argc, char **argv) { - int i; - SDLTest_CommonState *state; - - state = SDLTest_CommonCreateState(argv, 0); - - if (!SDL_Init(SDL_INIT_VIDEO)) { - SDL_Log("SDL_Init failed: %s", SDL_GetError()); - return 1; - } + const char *url = NULL; + SDLTest_CommonState *state = SDLTest_CommonCreateState(argv, 0); + bool use_gui = false; /* Parse commandline */ - for (i = 1; i < argc;) { + for (int i = 1; i < argc;) { int consumed; consumed = SDLTest_CommonArg(state, i); if (consumed == 0) { if (argv[i][0] != '-') { - tryOpenURL(argv[i]); + url = argv[i]; + consumed = 1; + } else if (SDL_strcasecmp(argv[i], "--gui") == 0) { + use_gui = true; consumed = 1; } } if (consumed <= 0) { static const char *options[] = { + "[--gui]" "[URL [...]]", NULL, }; @@ -57,6 +55,38 @@ int main(int argc, char **argv) i += consumed; } + state->flags = SDL_INIT_VIDEO; + if (!SDLTest_CommonInit(state)) { + return SDL_APP_FAILURE; + } + + if (!use_gui) { + tryOpenURL(url); + } else { + SDL_Event event; + bool quit = false; + + while (!quit) { + while (SDL_PollEvent(&event)) { + if (event.type == SDL_EVENT_KEY_DOWN) { + if (event.key.key == SDLK_SPACE) { + tryOpenURL(url); + } else if (event.key.key == SDLK_ESCAPE) { + quit = true; + } + } else if (event.type == SDL_EVENT_QUIT) { + quit = true; + } + } + + SDL_SetRenderDrawColor(state->renderers[0], 0, 0, 0, 255); + SDL_RenderClear(state->renderers[0]); + SDL_SetRenderDrawColor(state->renderers[0], 255, 255, 255, 255); + SDL_RenderDebugTextFormat(state->renderers[0], 8.f, 16.f, "Press space to open %s", url); + SDL_RenderPresent(state->renderers[0]); + } + } + SDL_Quit(); SDLTest_CommonDestroyState(state); return 0; From c98b36ff03023affddd12c9c8951d370f7ccb742 Mon Sep 17 00:00:00 2001 From: Sascha Reuter Date: Mon, 6 Apr 2026 19:57:00 +1000 Subject: [PATCH 076/407] GPU Vulkan: handle VK_ERROR_SURFACE_LOST_KHR in acquire path On Android, backgrounding and foregrounding an app causes the Vulkan surface to be destroyed. vkAcquireNextImageKHR returns VK_ERROR_SURFACE_LOST_KHR, but the acquire while(true) loop only calls RecreateSwapchain which doesn't recreate the surface, resulting in an infinite retry loop and a black screen. Handle VK_ERROR_SURFACE_LOST_KHR by setting both needsSurfaceRecreate and needsSwapchainRecreate, then returning to let the existing recreation path handle it on the next call. Fixes #15322 --- src/gpu/vulkan/SDL_gpu_vulkan.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index cbb7fc72bd..af4f265643 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -10214,6 +10214,13 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture( break; // we got the next image! } + // Surface lost — flag for surface + swapchain recreation on next call + if (acquireResult == VK_ERROR_SURFACE_LOST_KHR) { + windowData->needsSurfaceRecreate = true; + windowData->needsSwapchainRecreate = true; + return true; + } + // If acquisition is invalid, let's try to recreate Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); if (!recreateSwapchainResult) { From 0a54fdb8624f47eae1c796e3cddf475481d948fd Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 6 Apr 2026 11:11:23 -0400 Subject: [PATCH 077/407] dbus: Use OpenFile for opening local 'file://' URIs Per the spec, OpenURI can't open local paths, so OpenFile needs to be used instead. --- src/core/linux/SDL_dbus.c | 54 ++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index df114e0e19..3b1f095a23 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -22,6 +22,9 @@ #include "SDL_dbus.h" #include "../../stdlib/SDL_vacopy.h" +#include +#include + #ifdef SDL_USE_LIBDBUS // we never link directly to libdbus. #define SDL_DRIVER_DBUS_DYNAMIC "libdbus-1.so.3" @@ -473,11 +476,9 @@ static bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const cha bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token) { - const char *bus_name = "org.freedesktop.portal.Desktop"; - const char *path = "/org/freedesktop/portal/desktop"; - const char *interface = "org.freedesktop.portal.OpenURI"; - DBusMessageIter iterInit; - bool ret = false; + static const char *bus_name = "org.freedesktop.portal.Desktop"; + static const char *path = "/org/freedesktop/portal/desktop"; + static const char *interface = "org.freedesktop.portal.OpenURI"; if (!dbus.session_conn) { /* We either lost connection to the session bus or were not able to @@ -486,20 +487,43 @@ bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activa return false; } - DBusMessage *msg = dbus.message_new_method_call(bus_name, path, interface, "OpenURI"); - if (!msg) { - return false; - } + // The OpenURI method can't open local 'file://' URIs, so OpenFile must be used instead. + DBusMessageIter iterInit; + DBusMessage *msg = NULL; + int fd = -1; + bool ret = false; - if (!window_id) { - window_id = ""; + if (SDL_strncasecmp(uri, "file://", 7) == 0) { + fd = open(uri + 7, O_RDWR | O_CLOEXEC); + if (fd >= 0) { + msg = dbus.message_new_method_call(bus_name, path, interface, "OpenFile"); + } + } else { + msg = dbus.message_new_method_call(bus_name, path, interface, "OpenURI"); } - if (!dbus.message_append_args(msg, DBUS_TYPE_STRING, &window_id, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID)) { + if (!msg) { goto done; } dbus.message_iter_init_append(msg, &iterInit); + if (!window_id) { + window_id = ""; + } + if (!dbus.message_iter_append_basic(&iterInit, DBUS_TYPE_STRING, &window_id)) { + goto done; + } + + if (fd >= 0) { + if (!dbus.message_iter_append_basic(&iterInit, DBUS_TYPE_UNIX_FD, &fd)) { + goto done; + } + } else { + if (!dbus.message_iter_append_basic(&iterInit, DBUS_TYPE_STRING, &uri)) { + goto done; + } + } + if (activation_token) { if (!SDL_DBus_AppendDictWithKeyValue(&iterInit, "activation_token", activation_token)) { goto done; @@ -525,6 +549,12 @@ bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activa done: dbus.message_unref(msg); + + // The file descriptor is duplicated by D-Bus, so it can be closed on this end. + if (fd >= 0) { + close(fd); + } + return ret; } From aeb4309c0eea875686bc488c44e22b58b783e205 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 6 Apr 2026 09:54:57 -0700 Subject: [PATCH 078/407] GPU: Fix memory leak in Vulkan command buffer --- src/gpu/vulkan/SDL_gpu_vulkan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index af4f265643..e565bcf3a8 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -3179,7 +3179,9 @@ static void VULKAN_INTERNAL_DestroyCommandPool( SDL_free(commandBuffer->waitSemaphores); SDL_free(commandBuffer->signalSemaphores); SDL_free(commandBuffer->usedBuffers); + SDL_free(commandBuffer->buffersUsedInPendingTransfers); SDL_free(commandBuffer->usedTextures); + SDL_free(commandBuffer->texturesUsedInPendingTransfers); SDL_free(commandBuffer->usedSamplers); SDL_free(commandBuffer->usedGraphicsPipelines); SDL_free(commandBuffer->usedComputePipelines); From f8b7e22d7d1d143f085a1b355e674b05025ef114 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 6 Apr 2026 14:38:52 -0700 Subject: [PATCH 079/407] GPU: Fix Vulkan backend segfault --- src/gpu/vulkan/SDL_gpu_vulkan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index e565bcf3a8..259fbecb06 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -10589,7 +10589,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( commandBuffer->usedBufferCount = 0; for (Sint32 i = 0; i < commandBuffer->buffersUsedInPendingTransfersCount; i += 1) { - (void)SDL_AtomicDecRef(&commandBuffer->usedBuffers[i]->usedRegion->allocation->referenceCount); + (void)SDL_AtomicDecRef(&commandBuffer->buffersUsedInPendingTransfers[i]->usedRegion->allocation->referenceCount); } commandBuffer->buffersUsedInPendingTransfersCount = 0; @@ -10599,7 +10599,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( commandBuffer->usedTextureCount = 0; for (Sint32 i = 0; i < commandBuffer->texturesUsedInPendingTransfersCount; i += 1){ - (void)SDL_AtomicDecRef(&commandBuffer->usedTextures[i]->usedRegion->allocation->referenceCount); + (void)SDL_AtomicDecRef(&commandBuffer->texturesUsedInPendingTransfers[i]->usedRegion->allocation->referenceCount); } commandBuffer->texturesUsedInPendingTransfersCount = 0; From d1977bbf5e1cf777046c1ca52a166643fac30156 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 6 Apr 2026 21:22:31 +0200 Subject: [PATCH 080/407] cmake: emscripten/clang does not support -Wformat* (anymore) --- cmake/PreseedEmscriptenCache.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/PreseedEmscriptenCache.cmake b/cmake/PreseedEmscriptenCache.cmake index 1d75a4aca4..a28337c006 100644 --- a/cmake/PreseedEmscriptenCache.cmake +++ b/cmake/PreseedEmscriptenCache.cmake @@ -185,8 +185,8 @@ if(EMSCRIPTEN) set(HAVE_GETRESUID "1" CACHE INTERNAL "Have symbol getresuid") set(HAVE_GETRESGID "1" CACHE INTERNAL "Have symbol getresgid") set(HAVE_LIBUDEV_H "" CACHE INTERNAL "Have include libudev.h") - set(HAVE_WFORMAT "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT") - set(HAVE_WFORMAT_OVERFLOW "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT_OVERFLOW") + set(HAVE_WFORMAT "" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT") + set(HAVE_WFORMAT_OVERFLOW "" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT_OVERFLOW") set(HAVE_WFORMAT_EXTRA_ARGS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_WFORMAT_EXTRA_ARGS") set(COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS") endfunction() From 928cfef4b70bc4b57c61e9a1f8e9037b9dfb64de Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 6 Apr 2026 23:37:05 +0200 Subject: [PATCH 081/407] ci: bump workflows --- .github/actions/setup-gdk-desktop/action.yml | 4 +- .../setup-loongarch64-toolchain/action.yml | 4 +- .github/actions/setup-msvc-libusb/action.yml | 4 +- .github/actions/setup-ngage-sdk/action.yml | 6 +- .github/actions/setup-ninja/action.yml | 4 +- .github/actions/setup-vita-gles/action.yml | 4 +- .github/workflows/generic.yml | 22 +++---- .github/workflows/release.yml | 66 +++++++++---------- 8 files changed, 57 insertions(+), 57 deletions(-) diff --git a/.github/actions/setup-gdk-desktop/action.yml b/.github/actions/setup-gdk-desktop/action.yml index 10427ace3c..2834cdc424 100644 --- a/.github/actions/setup-gdk-desktop/action.yml +++ b/.github/actions/setup-gdk-desktop/action.yml @@ -30,7 +30,7 @@ runs: echo "cache-key=gdk-${{ inputs.ref }}-${{ inputs.edition }}" >> $Env:GITHUB_OUTPUT - name: 'Restore cached GDK' id: cache-restore - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: '${{ steps.calc.outputs.gdk-path }}' key: ${{ steps.calc.outputs.cache-key }} @@ -58,7 +58,7 @@ runs: --no-user-props - name: 'Cache GDK' if: ${{ !steps.cache-restore.outputs.cache-hit }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: '${{ steps.calc.outputs.gdk-path }}' key: ${{ steps.calc.outputs.cache-key }} diff --git a/.github/actions/setup-loongarch64-toolchain/action.yml b/.github/actions/setup-loongarch64-toolchain/action.yml index e7f9ddc724..61c1e53ff3 100644 --- a/.github/actions/setup-loongarch64-toolchain/action.yml +++ b/.github/actions/setup-loongarch64-toolchain/action.yml @@ -17,7 +17,7 @@ outputs: runs: using: 'composite' steps: - - uses: actions/cache/restore@v4 + - uses: actions/cache/restore@v5 id: restore-cache with: path: /opt/cross-tools @@ -34,7 +34,7 @@ runs: mkdir -p /opt tar -C /opt -x -f /tmp/toolchain.tar.xz - - uses: actions/cache/save@v4 + - uses: actions/cache/save@v5 if: ${{ !steps.restore-cache.outputs.cache-hit }} with: path: /opt/cross-tools diff --git a/.github/actions/setup-msvc-libusb/action.yml b/.github/actions/setup-msvc-libusb/action.yml index cbbf0980b5..f63939a694 100644 --- a/.github/actions/setup-msvc-libusb/action.yml +++ b/.github/actions/setup-msvc-libusb/action.yml @@ -17,7 +17,7 @@ runs: steps: - name: 'Restore cached libusb-${{ inputs.version }}.7z' id: cache-restore - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: 'C:\temp\libusb-${{ inputs.version }}.7z' key: libusb-msvc-${{ inputs.version }} @@ -28,7 +28,7 @@ runs: Invoke-WebRequest "https://github.com/libusb/libusb/releases/download/v${{ inputs.version }}/libusb-${{ inputs.version }}.7z" -OutFile "C:\temp\libusb-${{ inputs.version }}.7z" - name: 'Cache libusb-${{ inputs.version }}.7z' if: ${{ !steps.cache-restore.outputs.cache-hit }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: 'C:\temp\libusb-${{ inputs.version }}.7z' key: libusb-msvc-${{ inputs.version }} diff --git a/.github/actions/setup-ngage-sdk/action.yml b/.github/actions/setup-ngage-sdk/action.yml index fa83418ba2..e270002044 100644 --- a/.github/actions/setup-ngage-sdk/action.yml +++ b/.github/actions/setup-ngage-sdk/action.yml @@ -7,7 +7,7 @@ inputs: runs: using: 'composite' steps: - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.x' - name: 'Verify platform' @@ -52,7 +52,7 @@ runs: echo "extras-branch=${extras_branch}" >> ${GITHUB_OUTPUT} # - name: 'Restore cached ${{ steps.calc.outputs.archive }}' # id: cache-restore -# uses: actions/cache/restore@v4 +# uses: actions/cache/restore@v5 # with: # path: '${{ runner.temp }}' # key: ${{ steps.calc.outputs.cache-key }} @@ -68,7 +68,7 @@ runs: # - name: 'Cache ${{ steps.calc.outputs.archive }}' # if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} -# uses: actions/cache/save@v4 +# uses: actions/cache/save@v5 # with: # path: | # ${{ runner.temp }}/apps.zip diff --git a/.github/actions/setup-ninja/action.yml b/.github/actions/setup-ninja/action.yml index a1d3ad9834..49cc32db69 100644 --- a/.github/actions/setup-ninja/action.yml +++ b/.github/actions/setup-ninja/action.yml @@ -36,7 +36,7 @@ runs: echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT} - name: 'Restore cached ${{ steps.calc.outputs.archive }}' id: cache-restore - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} @@ -47,7 +47,7 @@ runs: Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v${{ inputs.version }}/${{ steps.calc.outputs.archive }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" - name: 'Cache ${{ steps.calc.outputs.archive }}' if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} diff --git a/.github/actions/setup-vita-gles/action.yml b/.github/actions/setup-vita-gles/action.yml index e263737b31..31ef799e13 100644 --- a/.github/actions/setup-vita-gles/action.yml +++ b/.github/actions/setup-vita-gles/action.yml @@ -33,7 +33,7 @@ runs: exit 1 ;; esac - - uses: actions/cache/restore@v4 + - uses: actions/cache/restore@v5 id: restore-cache with: path: /vita/dependencies @@ -81,7 +81,7 @@ runs: wget https://github.com/SonicMastr/gl4es4vita/releases/download/v$gl4es4vita_version-vita/vitasdk_stubs.zip -P/tmp unzip /tmp/vitasdk_stubs.zip -d/vita/dependencies/lib - - uses: actions/cache/save@v4 + - uses: actions/cache/save@v5 if: ${{ !steps.restore-cache.outputs.cache-hit }} with: path: /vita/dependencies diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 19cf4910ee..183146679b 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -35,7 +35,7 @@ jobs: echo "os=${{ matrix.platform.os }}" echo "" echo "Add [sdl-ci-filter ${{ matrix.platform.key }}] to your commit message to reduce the number of jobs." - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: 'Set up ninja' if: ${{ matrix.platform.setup-ninja }} uses: ./.github/actions/setup-ninja @@ -44,11 +44,11 @@ jobs: uses: ./.github/actions/setup-msvc-libusb with: arch: ${{ matrix.platform.setup-libusb-arch }} - - uses: mymindstorm/setup-emsdk@v14 + - uses: mymindstorm/setup-emsdk@v15 if: ${{ matrix.platform.platform == 'emscripten' }} with: version: 3.1.35 - - uses: browser-actions/setup-chrome@v1 + - uses: browser-actions/setup-chrome@v2 id: setup-chrome if: ${{ matrix.platform.platform == 'emscripten' }} with: @@ -76,7 +76,7 @@ jobs: run: | # We cannot use GitHub expressions in the controller job echo "ANDROID_NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >>$GITHUB_ENV - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 if: ${{ matrix.platform.java }} with: distribution: 'temurin' @@ -171,7 +171,7 @@ jobs: echo "timestamp=$(date -u "+%Y%m%d%H%M_%S")" >> "$GITHUB_OUTPUT" - name: 'Restore ccache' if: ${{ matrix.platform.ccache }} - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 id: restore-ccache with: path: ${{ runner.temp }}/ccache @@ -319,7 +319,7 @@ jobs: - name: 'Build (cross-platform-actions, BSD)' id: cpactions if: ${{ matrix.platform.cpactions }} - uses: cross-platform-actions/action@v0.29.0 + uses: cross-platform-actions/action@v0.32.0 with: operating_system: '${{ matrix.platform.cpactions-os }}' architecture: '${{ matrix.platform.cpactions-arch }}' @@ -349,7 +349,7 @@ jobs: - name: Add msbuild to PATH id: setup-msbuild if: ${{ matrix.platform.msvc-project != '' }} - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 - name: Build msbuild if: ${{ matrix.platform.msvc-project != '' }} run: | @@ -393,7 +393,7 @@ jobs: ccache -s - name: 'Save ccache' if: ${{ matrix.platform.ccache }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: ${{ runner.temp }}/ccache key: ${{ steps.restore-ccache.outputs.cache-primary-key }} @@ -413,7 +413,7 @@ jobs: run: | find ./ -iname '*.so' | xargs -L1 ./build-scripts/check_elf_alignment.sh - name: 'Upload binary package' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }} with: if-no-files-found: error @@ -422,14 +422,14 @@ jobs: build/dist/SDL3* build/include* - name: 'Upload minidumps' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 if: ${{ always() && steps.tests.outcome == 'failure' && (matrix.platform.platform == 'msvc' || matrix.platform.platform == 'msys2') }} with: if-no-files-found: ignore name: '${{ matrix.platform.artifact }}-minidumps' path: build/**/*.dmp - name: "Upload Android test apk's" - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 if: ${{ matrix.platform.enable-artifacts && always() && matrix.platform.artifact != '' && steps.apks.outcome == 'success' }} with: if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb578e6d25..ba43ece625 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,15 +20,15 @@ jobs: src-zip: ${{ steps.releaser.outputs.src-zip }} steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: 'build-scripts/build-release.py' - name: 'Set up SDL sources' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: 'SDL' fetch-depth: 0 @@ -43,7 +43,7 @@ jobs: --github \ --debug - name: 'Store source archives' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: sources path: '${{ github.workspace}}/dist' @@ -61,7 +61,7 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' @@ -114,15 +114,15 @@ jobs: dmg: ${{ steps.releaser.outputs.dmg }} steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: 'build-scripts/build-release.py' - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' @@ -143,7 +143,7 @@ jobs: --github \ --debug - name: 'Store DMG image file' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: dmg path: '${{ github.workspace }}/dist' @@ -153,12 +153,12 @@ jobs: runs-on: macos-latest steps: - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' - name: 'Download ${{ needs.dmg.outputs.dmg }}' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: dmg path: '${{ github.workspace }}' @@ -322,15 +322,15 @@ jobs: VC-devel: ${{ steps.releaser.outputs.VC-devel }} steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: 'build-scripts/build-release.py' - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' @@ -351,7 +351,7 @@ jobs: --github ` --debug - name: 'Store MSVC archives' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: win32 path: '${{ github.workspace }}/dist' @@ -361,16 +361,16 @@ jobs: runs-on: windows-latest steps: - name: 'Fetch .github/actions/setup-ninja/action.yml' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: '.github/actions/setup-ninja/action.yml' - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' - name: 'Download MSVC binaries' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: win32 path: '${{ github.workspace }}' @@ -481,11 +481,11 @@ jobs: mingw-devel-tar-xz: ${{ steps.releaser.outputs.mingw-devel-tar-xz }} steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: 'build-scripts/build-release.py' - name: 'Install Mingw toolchain' @@ -493,7 +493,7 @@ jobs: sudo apt-get update -y sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' @@ -513,7 +513,7 @@ jobs: --github \ --debug - name: 'Store MinGW archives' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: mingw path: '${{ github.workspace }}/dist' @@ -527,12 +527,12 @@ jobs: sudo apt-get update -y sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' - name: 'Download MinGW binaries' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: mingw path: '${{ github.workspace }}' @@ -582,11 +582,11 @@ jobs: android-aar: ${{ steps.releaser.outputs.android-aar }} steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: 'build-scripts/build-release.py' - name: 'Setup Android NDK' @@ -596,7 +596,7 @@ jobs: local-cache: false ndk-version: r28c - name: 'Setup Java JDK' - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '11' @@ -605,7 +605,7 @@ jobs: sudo apt-get update -y sudo apt-get install -y ninja-build - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' @@ -627,7 +627,7 @@ jobs: --github \ --debug - name: 'Store Android archive(s)' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: android path: '${{ github.workspace }}/dist' @@ -637,20 +637,20 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Set up Python' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '17' - name: 'Download source archives' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: sources path: '${{ github.workspace }}' - name: 'Download Android .aar archive' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: android path: '${{ github.workspace }}' From b8e8caf7c57df1d6b86eaa9c70c854a3caaa1603 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 6 Apr 2026 19:22:13 -0400 Subject: [PATCH 082/407] dbus: Better handle local URI paths Decode file URIs before trying to open them, and properly handle non-URI local paths. --- src/SDL_utils.c | 33 +++++++++++++++++++++++++++++++++ src/SDL_utils_c.h | 3 +++ src/core/linux/SDL_dbus.c | 27 +++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/SDL_utils.c b/src/SDL_utils.c index 66b043796e..2667390ac6 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -384,6 +384,39 @@ int SDL_URIToLocal(const char *src, char *dst) return -1; } +bool SDL_IsURI(const char *uri) +{ + /* A valid URI begins with a letter and is followed by any sequence of + * letters, digits, '+', '.', or '-'. + */ + if (!uri) { + return false; + } + + // The first character of the scheme must be a letter. + if (!((*uri >= 'a' && *uri <= 'z') || (*uri >= 'A' && *uri <= 'Z'))) { + return false; + } + + /* If the colon is found before encountering the end of the string or + * any invalid characters, the scheme can be considered valid. + */ + while (*uri) { + if (!((*uri >= 'a' && *uri <= 'z') || + (*uri >= 'A' && *uri <= 'Z') || + (*uri >= '0' && *uri <= '9') || + *uri == '+' || *uri == '-' || *uri == '.')) { + return false; + } + + if (*++uri == ':') { + return true; + } + } + + return false; +} + // This is a set of per-thread persistent strings that we can return from the SDL API. // This is used for short strings that might persist past the lifetime of the object // they are related to. diff --git a/src/SDL_utils_c.h b/src/SDL_utils_c.h index 266eb09249..a49eaa11b6 100644 --- a/src/SDL_utils_c.h +++ b/src/SDL_utils_c.h @@ -48,6 +48,9 @@ extern bool SDL_endswith(const char *string, const char *suffix); */ extern int SDL_URIToLocal(const char *src, char *dst); +/// Determine if a URI is valid by validating the scheme. +extern bool SDL_IsURI(const char *uri); + typedef enum { SDL_OBJECT_TYPE_UNKNOWN, diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 3b1f095a23..9a2bef87e1 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -487,14 +487,31 @@ bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activa return false; } - // The OpenURI method can't open local 'file://' URIs, so OpenFile must be used instead. DBusMessageIter iterInit; DBusMessage *msg = NULL; int fd = -1; bool ret = false; + const bool has_file_scheme = SDL_strncasecmp(uri, "file:/", 6) == 0; - if (SDL_strncasecmp(uri, "file://", 7) == 0) { - fd = open(uri + 7, O_RDWR | O_CLOEXEC); + // The OpenURI method can't open 'file://' URIs or local paths, so OpenFile must be used instead. + if (has_file_scheme || !SDL_IsURI(uri)) { + char *decoded_path = NULL; + + // Decode the path if it is a URI. + if (has_file_scheme) { + const size_t len = SDL_strlen(uri) + 1; + decoded_path = SDL_malloc(len); + if (!decoded_path) { + goto done; + } + if (SDL_URIToLocal(uri, decoded_path) < 0) { + SDL_free(decoded_path); + goto done; + } + uri = decoded_path; + } + fd = open(uri, O_RDWR | O_CLOEXEC); + SDL_free(decoded_path); if (fd >= 0) { msg = dbus.message_new_method_call(bus_name, path, interface, "OpenFile"); } @@ -548,7 +565,9 @@ bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activa } done: - dbus.message_unref(msg); + if (msg) { + dbus.message_unref(msg); + } // The file descriptor is duplicated by D-Bus, so it can be closed on this end. if (fd >= 0) { From f61a22e10f3272ba8f06ec3b2b5a2160097b2031 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Apr 2026 08:55:10 +0300 Subject: [PATCH 083/407] SDL_hidapi_zuiki.c: silence bogus -Warray-bounds warnings from gcc-4.9 --- src/joystick/hidapi/SDL_hidapi_zuiki.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_zuiki.c b/src/joystick/hidapi/SDL_hidapi_zuiki.c index ad7f3d80be..d5958be09d 100644 --- a/src/joystick/hidapi/SDL_hidapi_zuiki.c +++ b/src/joystick/hidapi/SDL_hidapi_zuiki.c @@ -62,8 +62,8 @@ static float median_filter_update(MedianFilter_t* mf, float input) { if (mf->count < FILTER_SIZE) mf->count++; float temp[FILTER_SIZE]; SDL_memcpy(temp, mf->buffer, sizeof(temp)); - for (int i = 0; i < mf->count - 1; i++) { - for (int j = i + 1; j < mf->count; j++) { + for (uint8_t i = 0; i < mf->count - 1; i++) { + for (uint8_t j = i + 1; j < mf->count; j++) { if (temp[i] > temp[j]) { float t = temp[i]; temp[i] = temp[j]; From 7f23f09ee80730225139d9f8b839abb6546d06c4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 7 Apr 2026 12:22:33 -0700 Subject: [PATCH 084/407] Fixed crash if SDL_SYS_CreateThread() fails (thanks @capehill!) Fixes https://github.com/libsdl-org/SDL/issues/15340 --- src/thread/SDL_thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 9ffba9592c..efa1b72d4e 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -411,7 +411,7 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props, SDL_DestroySemaphore(thread->ready_sem); SDL_free(thread->name); SDL_free(thread); - thread = NULL; + return NULL; } SDL_WaitSemaphore(thread->ready_sem); From cf71571c962659eea17aa33131fd8bf0e41961a2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 7 Apr 2026 13:31:16 -0700 Subject: [PATCH 085/407] testcolorspace: use the SDL main callbacks --- test/testcolorspace.c | 155 ++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 88 deletions(-) diff --git a/test/testcolorspace.c b/test/testcolorspace.c index 5c28e1e6db..36be78fde4 100644 --- a/test/testcolorspace.c +++ b/test/testcolorspace.c @@ -10,14 +10,11 @@ freely. */ +#define SDL_MAIN_USE_CALLBACKS 1 #include #include #include -#ifdef SDL_PLATFORM_EMSCRIPTEN -#include -#endif - #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 @@ -33,7 +30,6 @@ static const char *colorspace_name = "sRGB"; static int renderer_count = 0; static int renderer_index = 0; static int stage_index = 0; -static int done; static float HDR_headroom = 1.0f; enum @@ -584,80 +580,73 @@ static void RenderGradientTexture(void) y += 64.0f; } -static void loop(void) +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { - SDL_Event event; - /* Check for events */ - while (SDL_PollEvent(&event)) { - if (event.type == SDL_EVENT_KEY_DOWN) { - switch (event.key.key) { - case SDLK_ESCAPE: - done = 1; - break; - case SDLK_SPACE: - case SDLK_RIGHT: - NextStage(); - break; - case SDLK_LEFT: - PrevStage(); - break; - case SDLK_DOWN: - NextRenderer(); - break; - case SDLK_UP: - PrevRenderer(); - break; - default: - break; - } - } else if (event.type == SDL_EVENT_WINDOW_HDR_STATE_CHANGED) { - UpdateHDRState(); - } else if (event.type == SDL_EVENT_QUIT) { - done = 1; - } - } - - if (renderer) { - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - - switch (stage_index) { - case StageClearBackground: - RenderClearBackground(); + if (event->type == SDL_EVENT_KEY_DOWN) { + switch (event->key.key) { + case SDLK_ESCAPE: + return SDL_APP_SUCCESS; + case SDLK_SPACE: + case SDLK_RIGHT: + NextStage(); break; - case StageDrawBackground: - RenderDrawBackground(); + case SDLK_LEFT: + PrevStage(); break; - case StageTextureBackground: - RenderTextureBackground(); + case SDLK_DOWN: + NextRenderer(); break; - case StageTargetBackground: - RenderTargetBackground(); + case SDLK_UP: + PrevRenderer(); break; - case StageBlendDrawing: - RenderBlendDrawing(); - break; - case StageBlendTexture: - RenderBlendTexture(); - break; - case StageGradientDrawing: - RenderGradientDrawing(); - break; - case StageGradientTexture: - RenderGradientTexture(); + default: break; } - - SDL_RenderPresent(renderer); + } else if (event->type == SDL_EVENT_WINDOW_HDR_STATE_CHANGED) { + UpdateHDRState(); + } else if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + switch (stage_index) { + case StageClearBackground: + RenderClearBackground(); + break; + case StageDrawBackground: + RenderDrawBackground(); + break; + case StageTextureBackground: + RenderTextureBackground(); + break; + case StageTargetBackground: + RenderTargetBackground(); + break; + case StageBlendDrawing: + RenderBlendDrawing(); + break; + case StageBlendTexture: + RenderBlendTexture(); + break; + case StageGradientDrawing: + RenderGradientDrawing(); + break; + case StageGradientTexture: + RenderGradientTexture(); + break; + } + + SDL_RenderPresent(renderer); SDL_Delay(100); -#ifdef SDL_PLATFORM_EMSCRIPTEN - if (done) { - emscripten_cancel_main_loop(); - } -#endif + return SDL_APP_CONTINUE; } static void LogUsage(const char *argv0) @@ -665,9 +654,8 @@ static void LogUsage(const char *argv0) SDL_Log("Usage: %s [--renderer renderer] [--colorspace colorspace]", argv0); } -int main(int argc, char *argv[]) +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) { - int return_code = 1; int i; for (i = 1; i < argc; ++i) { @@ -677,7 +665,7 @@ int main(int argc, char *argv[]) ++i; } else { LogUsage(argv[0]); - goto quit; + return SDL_APP_FAILURE; } } else if (SDL_strcmp(argv[i], "--colorspace") == 0) { if (argv[i + 1]) { @@ -692,24 +680,23 @@ int main(int argc, char *argv[]) */ } else { SDL_Log("Unknown colorspace %s", argv[i + 1]); - goto quit; + return SDL_APP_FAILURE; } ++i; } else { LogUsage(argv[0]); - goto quit; + return SDL_APP_FAILURE; } } else { LogUsage(argv[0]); - goto quit; + return SDL_APP_FAILURE; } } window = SDL_CreateWindow("SDL colorspace test", WINDOW_WIDTH, WINDOW_HEIGHT, 0); if (!window) { SDL_Log("Couldn't create window: %s", SDL_GetError()); - return_code = 2; - goto quit; + return SDL_APP_FAILURE; } renderer_count = SDL_GetNumRenderDrivers(); @@ -724,20 +711,12 @@ int main(int argc, char *argv[]) } CreateRenderer(); - /* Main render loop */ - done = 0; + return SDL_APP_CONTINUE; +} -#ifdef SDL_PLATFORM_EMSCRIPTEN - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - return_code = 0; -quit: +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); - return return_code; } From 51aeebd8893c37438e389d1678de524cc5e261d0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 7 Apr 2026 13:32:42 -0700 Subject: [PATCH 086/407] testcolorspace: fixed color check when output is linear colorspace with 8-bit precision --- test/testcolorspace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/testcolorspace.c b/test/testcolorspace.c index 36be78fde4..e2bfeb400f 100644 --- a/test/testcolorspace.c +++ b/test/testcolorspace.c @@ -365,7 +365,8 @@ static void RenderBlendDrawing(void) y += TEXT_LINE_ADVANCE; DrawText(x, y, "Test: Draw Blending"); y += TEXT_LINE_ADVANCE; - if (cr.r == 199 && cr.g == 193 && cr.b == 121) { + if ((cr.r == 199 && cr.g == 193 && cr.b == 121) || + (cr.r == 199 && cr.g == 193 && cr.b == 120)) { DrawText(x, y, "Correct blend color, blending in linear space"); } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) || (cr.r == 191 && cr.g == 162 && cr.b == 82)) { @@ -425,7 +426,8 @@ static void RenderBlendTexture(void) y += TEXT_LINE_ADVANCE; DrawText(x, y, "Test: Texture Blending"); y += TEXT_LINE_ADVANCE; - if (cr.r == 199 && cr.g == 193 && cr.b == 121) { + if ((cr.r == 199 && cr.g == 193 && cr.b == 121) || + (cr.r == 199 && cr.g == 193 && cr.b == 120)) { DrawText(x, y, "Correct blend color, blending in linear space"); } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) || (cr.r == 191 && cr.g == 162 && cr.b == 82)) { From 5c430f87155deede1743ae2af73e113f8151d4e3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 8 Apr 2026 09:09:29 -0700 Subject: [PATCH 087/407] Fixed SDL_GlobDirectory() on asset paths on Android Make sure we pass the original path back to the directory enumeration callback. --- src/core/android/SDL_android.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index fa559484f9..07f71600e3 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1970,9 +1970,9 @@ bool Android_JNI_EnumerateAssetDirectory(const char *path, SDL_EnumerateDirector } } - path = GetAssetPath(path); + const char *asset_path = GetAssetPath(path); - AAssetDir *adir = AAssetManager_openDir(asset_manager, path); + AAssetDir *adir = AAssetManager_openDir(asset_manager, asset_path); if (!adir) { return SDL_SetError("AAssetManager_openDir failed"); } From 57f3d2ea0aada9131c109aaa0dfda41839997ebf Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 8 Apr 2026 10:08:11 -0700 Subject: [PATCH 088/407] Don't send any commands to the GPU while hidden Previously we weren't doing drawing, but we were enqueuing viewport commands and so forth, which were causing GPU permission errors on iOS. We really don't want to be sending any work to the GPU when we're in the background. --- src/render/SDL_render.c | 69 ++++------------------------------------- 1 file changed, 6 insertions(+), 63 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index fb14aa52af..4d76a7405e 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -320,6 +320,12 @@ static bool FlushRenderCommands(SDL_Renderer *renderer) DebugLogRenderCommands(renderer->render_commands); +#if DONT_DRAW_WHILE_HIDDEN + // Don't send commands to the GPU while we're hidden + if (renderer->hidden) { + result = true; + } else +#endif result = renderer->RunCommandQueue(renderer, renderer->render_commands, renderer->vertex_data, renderer->vertex_data_used); // Move the whole render command queue to the unused pool so we can reuse them next time. @@ -3581,13 +3587,6 @@ bool SDL_RenderPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int coun return true; } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - const SDL_RenderViewState *view = renderer->view; if ((view->current_scale.x != 1.0f) || (view->current_scale.y != 1.0f)) { result = RenderPointsWithRects(renderer, points, count); @@ -3788,13 +3787,6 @@ bool SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count return true; } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - SDL_RenderViewState *view = renderer->view; const bool islogical = (view->logical_presentation_mode != SDL_LOGICAL_PRESENTATION_DISABLED); @@ -3970,13 +3962,6 @@ bool SDL_RenderRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count) return true; } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - for (i = 0; i < count; ++i) { if (!SDL_RenderRect(renderer, &rects[i])) { return false; @@ -4016,13 +4001,6 @@ bool SDL_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int cou return true; } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - frects = SDL_small_alloc(SDL_FRect, count, &isstack); if (!frects) { return false; @@ -4113,13 +4091,6 @@ bool SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_F return SDL_SetError("Texture was not created with this renderer"); } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - SDL_FRect real_srcrect; real_srcrect.x = 0.0f; real_srcrect.y = 0.0f; @@ -4167,13 +4138,6 @@ bool SDL_RenderTextureAffine(SDL_Renderer *renderer, SDL_Texture *texture, return SDL_SetError("Renderer does not support RenderCopyEx"); } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - real_srcrect.x = 0.0f; real_srcrect.y = 0.0f; real_srcrect.w = (float)texture->w; @@ -4294,13 +4258,6 @@ bool SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture, return SDL_SetError("Renderer does not support RenderCopyEx"); } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - real_srcrect.x = 0.0f; real_srcrect.y = 0.0f; real_srcrect.w = (float)texture->w; @@ -4555,13 +4512,6 @@ bool SDL_RenderTextureTiled(SDL_Renderer *renderer, SDL_Texture *texture, const return SDL_InvalidParamError("scale"); } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - real_srcrect.x = 0.0f; real_srcrect.y = 0.0f; real_srcrect.w = (float)texture->w; @@ -5341,13 +5291,6 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer, return SDL_Unsupported(); } -#if DONT_DRAW_WHILE_HIDDEN - // Don't draw while we're hidden - if (renderer->hidden) { - return true; - } -#endif - if (num_vertices < 3) { return true; } From c2d0b59f29e7c4ad7729d9268b5b5ccd437fbc0f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 10 Apr 2026 00:03:55 -0500 Subject: [PATCH 089/407] kmsdrm: Fix double-free of GBM surface buffer in atomic mode --- src/video/kmsdrm/SDL_kmsdrmvideo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 0c061b9d29..7b5c10f92c 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1708,7 +1708,9 @@ static void KMSDRM_DestroySurfaces(SDL_VideoDevice *_this, SDL_Window *window) /***************************/ if (windata->bo) { - KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); + if (windata->bo != windata->next_bo) { + KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); + } windata->bo = NULL; } From ccf688c9215a08bbba4b09c528ff82f9d67589c9 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Fri, 10 Apr 2026 12:51:07 +0200 Subject: [PATCH 090/407] Android: fix lint warning "unneed cast to Activity" --- .../app/src/main/java/org/libsdl/app/SDLActivity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 9eb003da23..c5777dccc4 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -570,7 +570,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static int getNaturalOrientation() { int result = SDL_ORIENTATION_UNKNOWN; - Activity activity = (Activity)getContext(); + Activity activity = getContext(); if (activity != null) { Configuration config = activity.getResources().getConfiguration(); Display display = activity.getWindowManager().getDefaultDisplay(); @@ -590,7 +590,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static int getCurrentRotation() { int result = 0; - Activity activity = (Activity)getContext(); + Activity activity = getContext(); if (activity != null) { Display display = activity.getWindowManager().getDefaultDisplay(); switch (display.getRotation()) { @@ -1292,7 +1292,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static double getDiagonal() { DisplayMetrics metrics = new DisplayMetrics(); - Activity activity = (Activity)getContext(); + Activity activity = getContext(); if (activity == null) { return 0.0; } @@ -1940,7 +1940,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh return; } - Activity activity = (Activity)getContext(); + Activity activity = getContext(); if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { activity.requestPermissions(new String[]{permission}, requestCode); } else { From 0fc9db9b82c318b44562778cd4709e9638a57087 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 10 Apr 2026 11:23:49 -0400 Subject: [PATCH 091/407] x11: Ignore slave button presses on non-focused windows When a window has the pointer grabbed, the X server will grab all master device events, and XInput2 will continue to deliver slave events to the window immediately under the pointer, regardless of grab status. Only send slave pointer events to the focused window, and fall back to the core X events to catch button presses missed when the pointer is over another window. --- src/video/x11/SDL_x11events.c | 8 ++++---- src/video/x11/SDL_x11video.h | 1 + src/video/x11/SDL_x11xinput2.c | 10 +++++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 6bfb914273..15af66124f 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1862,8 +1862,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case ButtonPress: { - if (data->xinput2_mouse_enabled) { - // This input is being handled by XInput2 + if (data->xinput2_mouse_enabled && xevent->xbutton.serial == videodata->xinput_last_button_serial) { + // This input event was handled by XInput2. break; } @@ -1873,8 +1873,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case ButtonRelease: { - if (data->xinput2_mouse_enabled) { - // This input is being handled by XInput2 + if (data->xinput2_mouse_enabled && xevent->xbutton.serial == videodata->xinput_last_button_serial) { + // This input event was handled by XInput2. break; } diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 32c3722784..01c2e5b9fb 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -139,6 +139,7 @@ struct SDL_VideoData Uint32 global_mouse_buttons; SDL_XInput2DeviceInfo *mouse_device_info; + unsigned long xinput_last_button_serial; int xinput_master_pointer_device; bool xinput_hierarchy_changed; diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 69b7e21546..4ebba6e0f3 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -607,8 +607,16 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); int x_ticks = 0, y_ticks = 0; - // Slave pointer devices don't have button remapping applied automatically, so do it manually. + // Store the button serial to filter out redundant core button events. + videodata->xinput_last_button_serial = xev->serial; + if (xev->deviceid != videodata->xinput_master_pointer_device) { + // Ignore slave button events on non-focused windows, or focus can be incorrectly set while a grab is active. + if (SDL_GetMouseFocus() != windowdata->window) { + break; + } + + // Slave pointer devices don't have button remapping applied automatically, so do it manually. if (button <= xinput2_pointer_button_map_size) { button = xinput2_pointer_button_map[button - 1]; } From 463b6be13342b0d58bf1cc8674fcee4fc4bcc9c0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 9 Apr 2026 23:26:15 -0500 Subject: [PATCH 092/407] kmsdrm: Fix order of GBM and EGL teardown All locked front buffers must be released prior to destroying the EGL surface to avoid causing a UAF in libnvidia-egl-gbm.so. --- src/video/kmsdrm/SDL_kmsdrmvideo.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 7b5c10f92c..d0910c8a39 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1692,17 +1692,6 @@ static void KMSDRM_DestroySurfaces(SDL_VideoDevice *_this, SDL_Window *window) SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not restore CRTC"); } - /***************************/ - // Destroy the EGL surface - /***************************/ - - SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (windata->egl_surface != EGL_NO_SURFACE) { - SDL_EGL_DestroySurface(_this, windata->egl_surface); - windata->egl_surface = EGL_NO_SURFACE; - } - /***************************/ // Destroy the GBM buffers /***************************/ @@ -1719,6 +1708,17 @@ static void KMSDRM_DestroySurfaces(SDL_VideoDevice *_this, SDL_Window *window) windata->next_bo = NULL; } + /***************************/ + // Destroy the EGL surface + /***************************/ + + SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (windata->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, windata->egl_surface); + windata->egl_surface = EGL_NO_SURFACE; + } + /***************************/ // Destroy the GBM surface /***************************/ From dc16a3514096bd53418bccd5c588b53a76d9c676 Mon Sep 17 00:00:00 2001 From: Mathieu Eyraud <70028899+meyraud705@users.noreply.github.com> Date: Wed, 8 Apr 2026 13:23:11 +0200 Subject: [PATCH 093/407] Don't call function pointer when it is NULL --- src/gpu/d3d12/SDL_gpu_d3d12.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 42bb634c53..75a4c99a76 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -9633,17 +9633,14 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD if (SDL_HasProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_PATH_STRING) && SDL_HasProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_VERSION_NUMBER)) { int d3d12SDKVersion = SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_VERSION_NUMBER, 0); const char *d3d12SDKPath = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_PATH_STRING, ".\\D3D12\\"); + ID3D12SDKConfiguration *sdk_config = NULL; pD3D12GetInterface = (PFN_D3D12_GET_INTERFACE)SDL_LoadFunction( renderer->d3d12_dll, D3D12_GET_INTERFACE_FUNC); if (pD3D12GetInterface == NULL) { SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load D3D12GetInterface, custom D3D12 SDK will not load."); - } - - ID3D12SDKConfiguration *sdk_config = NULL; - - if (SUCCEEDED(pD3D12GetInterface(D3D_GUID(D3D_CLSID_ID3D12SDKConfiguration), D3D_GUID(D3D_IID_ID3D12SDKConfiguration), (void**) &sdk_config))) { + } else if (SUCCEEDED(pD3D12GetInterface(D3D_GUID(D3D_CLSID_ID3D12SDKConfiguration), D3D_GUID(D3D_IID_ID3D12SDKConfiguration), (void**) &sdk_config))) { ID3D12SDKConfiguration1 *sdk_config1 = NULL; if (SUCCEEDED(IUnknown_QueryInterface(sdk_config, &D3D_IID_ID3D12SDKConfiguration1, (void**) &sdk_config1))) { if (SUCCEEDED(ID3D12SDKConfiguration1_CreateDeviceFactory(sdk_config1, d3d12SDKVersion, d3d12SDKPath, &D3D_IID_ID3D12DeviceFactory, (void**) &factory))) { From 4aa0a6e2bf53f49aeecb0747836a2112620a53e6 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Sun, 5 Apr 2026 00:06:34 +0500 Subject: [PATCH 094/407] Fix Oklick W-2 support This PR maps buttons 7 and 8 to paddles 2 (left) and 1 (right) respectively, and it also duplicates the mapping but for crc 0x2004, since the CRC of this controller changes if it was hotplugged. --- src/joystick/SDL_gamepad_db.h | 3 ++- src/joystick/SDL_joystick.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/joystick/SDL_gamepad_db.h b/src/joystick/SDL_gamepad_db.h index 89bfe56624..5d52ca9d33 100644 --- a/src/joystick/SDL_gamepad_db.h +++ b/src/joystick/SDL_gamepad_db.h @@ -212,7 +212,8 @@ static const char *s_GamepadMappings[] = { "03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,", "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,", - "03000000ff1100003133000000000000,Oklick W-2,crc:faf6,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a1,leftx:a0,rightshoulder:b5,rightstick:b11,righttrigger:-a1,start:b9,x:b0,y:b1,", + "03000000ff1100003133000000000000,Oklick W-2,crc:faf6,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a1,leftx:a0,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b11,righttrigger:-a1,start:b9,x:b0,y:b1,", + "03000000ff1100003133000000000000,Oklick W-2,crc:2004,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a1,leftx:a0,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b11,righttrigger:-a1,start:b9,x:b0,y:b1,", "03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,", "03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,", diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index c9b15f6097..414fffad39 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3427,7 +3427,7 @@ bool SDL_IsJoystickVIRTUAL(SDL_GUID guid) bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id, Uint16 crc) { - if (vendor_id == 0x11FF && product_id == 0x3331 && crc == 0xFAF6) { + if (vendor_id == 0x11FF && product_id == 0x3331 && (crc == 0xFAF6 || crc == 0x2004)) { // Oklick W-2 racing wheel controller (on Windows via DirectInput). return true; } From 8c024f4f3ad72e87384935d8a311f08a05d5c52a Mon Sep 17 00:00:00 2001 From: eafton Date: Sat, 11 Apr 2026 00:11:38 +0300 Subject: [PATCH 095/407] SNI/DBus tray support (#15189) --- src/SDL_list.c | 87 +++ src/SDL_list.h | 3 + src/SDL_menu.h | 64 ++ src/core/linux/SDL_dbus.c | 1088 ++++++++++++++++++++++++++++++- src/core/linux/SDL_dbus.h | 28 +- src/tray/SDL_tray_utils.c | 8 +- src/tray/SDL_tray_utils.h | 1 + src/tray/unix/SDL_dbustray.c | 1177 ++++++++++++++++++++++++++++++++++ src/tray/unix/SDL_tray.c | 706 ++++---------------- src/tray/unix/SDL_unixtray.h | 81 +++ 10 files changed, 2659 insertions(+), 584 deletions(-) create mode 100644 src/SDL_menu.h create mode 100644 src/tray/unix/SDL_dbustray.c create mode 100644 src/tray/unix/SDL_unixtray.h diff --git a/src/SDL_list.c b/src/SDL_list.c index a17c40787a..558a38d823 100644 --- a/src/SDL_list.c +++ b/src/SDL_list.c @@ -22,6 +22,82 @@ #include "./SDL_list.h" +// Append +bool SDL_ListAppend(SDL_ListNode **head, void *ent) +{ + SDL_ListNode *cursor; + SDL_ListNode *node; + + if (!head) { + return false; + } + + node = (SDL_ListNode *)SDL_malloc(sizeof(*node)); + if (!node) { + return false; + } + node->entry = ent; + node->next = NULL; + + if (*head) { + cursor = *head; + while (cursor->next) { + cursor = cursor->next; + } + cursor->next = node; + } else { + *head = node; + } + + return true; +} + +bool SDL_ListInsertAtPosition(SDL_ListNode **head, int pos, void *ent) +{ + SDL_ListNode *cursor; + SDL_ListNode *node; + int i; + + if (pos == -1) { + return SDL_ListAppend(head, ent); + } + + if (!pos) { + node = (SDL_ListNode *)SDL_malloc(sizeof(*node)); + if (!node) { + return false; + } + node->entry = ent; + + if (*head) { + node->next = *head; + } else { + node->next = NULL; + } + + *head = node; + } + + cursor = *head; + for (i = 1; i < pos - 1 && cursor; i++) { + cursor = cursor->next; + } + + if (!cursor) { + return SDL_ListAppend(head, ent); + } + + node = (SDL_ListNode *)SDL_malloc(sizeof(*node)); + if (!node) { + return false; + } + node->entry = ent; + node->next = cursor->next; + cursor->next = node; + + return true; +} + // Push bool SDL_ListAdd(SDL_ListNode **head, void *ent) { @@ -84,3 +160,14 @@ void SDL_ListClear(SDL_ListNode **head) SDL_free(tmp); } } + +int SDL_ListCountEntries(SDL_ListNode **head) +{ + SDL_ListNode *node; + int count = 0; + + for (node = *head; node; node = node->next) { + ++count; + } + return count; +} diff --git a/src/SDL_list.h b/src/SDL_list.h index bdfbc35160..b1e6fdbfea 100644 --- a/src/SDL_list.h +++ b/src/SDL_list.h @@ -28,9 +28,12 @@ typedef struct SDL_ListNode struct SDL_ListNode *next; } SDL_ListNode; +bool SDL_ListAppend(SDL_ListNode **head, void *ent); +bool SDL_ListInsertAtPosition(SDL_ListNode **head, int pos, void *ent); bool SDL_ListAdd(SDL_ListNode **head, void *ent); void SDL_ListPop(SDL_ListNode **head, void **ent); void SDL_ListRemove(SDL_ListNode **head, void *ent); void SDL_ListClear(SDL_ListNode **head); +int SDL_ListCountEntries(SDL_ListNode **head); #endif // SDL_list_h_ diff --git a/src/SDL_menu.h b/src/SDL_menu.h new file mode 100644 index 0000000000..2f0d0bd5ea --- /dev/null +++ b/src/SDL_menu.h @@ -0,0 +1,64 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_menu_h_ +#define SDL_menu_h_ + +#include "./SDL_list.h" + +typedef enum SDL_MenuItemType +{ + SDL_MENU_ITEM_TYPE_NORMAL, + SDL_MENU_ITEM_TYPE_SEPERATOR, + SDL_MENU_ITEM_TYPE_CHECKBOX +} SDL_MenuItemType; + +typedef enum SDL_MenuItemFlags +{ + SDL_MENU_ITEM_FLAGS_NONE = 0, + SDL_MENU_ITEM_FLAGS_DISABLED = 1 << 0, + SDL_MENU_ITEM_FLAGS_CHECKED = 1 << 1, + SDL_MENU_ITEM_FLAGS_BAR_ITEM = 1 << 2 +} SDL_MenuItemFlags; + +/* Do not create this struct directly, users of this structure like the DBUSMENU layer use extended versions of it which need to be allocated by specfic functions. */ +/* This struct is meant to be in an SDL_List just like sub_menu */ +typedef struct SDL_MenuItem +{ + /* Basic properties */ + const char *utf8; + SDL_MenuItemType type; + SDL_MenuItemFlags flags; + + /* Callback */ + void *cb_data; + void (*cb)(struct SDL_MenuItem *, void *); + + /* Submenu, set to NULL if none */ + SDL_ListNode *sub_menu; + + /* User data slots */ + void *udata; + void *udata2; + void *udata3; +} SDL_MenuItem; + +#endif // SDL_menu_h_ diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 9a2bef87e1..0532fb87c9 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -18,14 +18,31 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #include "SDL_internal.h" #include "SDL_dbus.h" +#include "../../SDL_list.h" +#include "../../SDL_menu.h" #include "../../stdlib/SDL_vacopy.h" #include #include #ifdef SDL_USE_LIBDBUS + +typedef struct SDL_DBusMenuItem +{ + SDL_MenuItem _parent; + + SDL_DBusContext *dbus; + dbus_int32_t id; + dbus_uint32_t revision; + + /* Right click event handler */ + void *cbdata; + bool (*cb)(SDL_ListNode *, void *); +} SDL_DBusMenuItem; + // we never link directly to libdbus. #define SDL_DRIVER_DBUS_DYNAMIC "libdbus-1.so.3" static const char *dbus_library = SDL_DRIVER_DBUS_DYNAMIC; @@ -34,6 +51,11 @@ static char *inhibit_handle = NULL; static unsigned int screensaver_cookie = 0; static SDL_DBusContext dbus; +#define DBUS_MENU_INTERFACE "com.canonical.dbusmenu" +#define DBUS_MENU_OBJECT_PATH "/Menu" +#define SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE (1 << 0) +static const char *menu_introspect = ""; + SDL_ELF_NOTE_DLOPEN( "core-libdbus", "Support for D-Bus IPC", @@ -43,12 +65,12 @@ SDL_ELF_NOTE_DLOPEN( static bool LoadDBUSSyms(void) { -#define SDL_DBUS_SYM2_OPTIONAL(TYPE, x, y) \ +#define SDL_DBUS_SYM2_OPTIONAL(TYPE, x, y) \ dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y) #define SDL_DBUS_SYM2(TYPE, x, y) \ if (!(dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y))) \ - return false + return false #define SDL_DBUS_SYM_OPTIONAL(TYPE, x) \ SDL_DBUS_SYM2_OPTIONAL(TYPE, x, dbus_##x) @@ -107,6 +129,16 @@ static bool LoadDBUSSyms(void) SDL_DBUS_SYM(void (*)(char **), free_string_array); SDL_DBUS_SYM(void (*)(void), shutdown); + /* New symbols for SNI and menu export */ + SDL_DBUS_SYM(int (*)(DBusConnection *, const char *, unsigned int, DBusError *), bus_request_name); + SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *, const char *), message_is_method_call); + SDL_DBUS_SYM(DBusMessage *(*)(DBusMessage *, const char *, const char *), message_new_error); + SDL_DBUS_SYM(DBusMessage *(*)(DBusMessage *), message_new_method_return); + SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessageIter *, int, const void *, int), message_iter_append_fixed_array); + SDL_DBUS_SYM(void (*)(DBusMessageIter *, void *, int *), message_iter_get_fixed_array); + SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, const char *, void **), connection_get_object_path_data); + SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, const char *), connection_unregister_object_path); + #undef SDL_DBUS_SYM #undef SDL_DBUS_SYM2 @@ -466,12 +498,12 @@ failed: static bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const char *key, const char *value) { - const char *keys[1]; - const char *values[1]; + const char *keys[1]; + const char *values[1]; - keys[0] = key; - values[0] = value; - return SDL_DBus_AppendDictWithKeysAndValues(iterInit, keys, values, 1); + keys[0] = key; + values[0] = value; + return SDL_DBus_AppendDictWithKeysAndValues(iterInit, keys, values, 1); } bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token) @@ -753,7 +785,7 @@ char **SDL_DBus_DocumentsPortalRetrieveFiles(const char *key, int *path_count) * The spec doesn't define any entries yet so it's empty. */ dbus.message_iter_init_append(msg, &iter); if (!dbus.message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &iterDict) || - !dbus.message_iter_close_container(&iter, &iterDict)) { + !dbus.message_iter_close_container(&iter, &iterDict)) { SDL_OutOfMemory(); dbus.message_unref(msg); goto failed; @@ -797,10 +829,10 @@ static DBusHandlerResult SDL_DBus_CameraPortalMessageHandler(DBusConnection *con if (dbus.message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) { if (!dbus.message_get_args(msg, data->err, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &old, - DBUS_TYPE_STRING, &new, - DBUS_TYPE_INVALID)) { + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, + DBUS_TYPE_INVALID)) { data->done = true; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -962,4 +994,1036 @@ failed: return -1; } +/* DBUSMENU LAYER BEGINS HERE */ + +/* Special thanks to the kind Hayden Gray (thag_iceman/A1029384756) from the SDL community for his help! */ + +static SDL_DBusMenuItem *MenuGetItemById(SDL_ListNode *menu, dbus_int32_t id) +{ + SDL_ListNode *cursor; + + cursor = menu; + while (cursor) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + + item = cursor->entry; + dbus_item = cursor->entry; + + if (dbus_item->id == id) { + return dbus_item; + } + + if (item->sub_menu) { + SDL_DBusMenuItem *found; + + found = MenuGetItemById(item->sub_menu, id); + if (found) { + return found; + } + } + + cursor = cursor->next; + } + return NULL; +} + +static void MenuAppendItemProperties(SDL_DBusContext *ctx, SDL_DBusMenuItem *dbus_item, DBusMessageIter *dict_iter) +{ + SDL_MenuItem *item; + DBusMessageIter entry_iter; + DBusMessageIter variant_iter; + const char *key; + const char *value; + int value_int; + dbus_bool_t value_bool; + + item = (SDL_MenuItem *)dbus_item; + + key = "label"; + value = item->utf8 ? item->utf8 : ""; + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "type"; + if (item->type == SDL_MENU_ITEM_TYPE_SEPERATOR) { + value = "separator"; + } else { + value = "standard"; + } + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "enabled"; + value_bool = !(item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &value_bool); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "visible"; + value_bool = TRUE; + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &value_bool); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "toggle-type"; + value = (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) ? "checkmark" : ""; + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "toggle-state"; + value_int = (item->flags & SDL_MENU_ITEM_FLAGS_CHECKED) ? 1 : 0; + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "i", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &value_int); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); + + key = "children-display"; + value = item->sub_menu ? "submenu" : ""; + ctx->message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(dict_iter, &entry_iter); +} + +static void MenuAppendItem(SDL_DBusContext *ctx, SDL_DBusMenuItem *dbus_item, DBusMessageIter *array_iter, int depth) +{ + SDL_MenuItem *item; + DBusMessageIter struct_iter, dict_iter, children_iter; + + item = (SDL_MenuItem *)dbus_item; + + ctx->message_iter_open_container(array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + ctx->message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32, &dbus_item->id); + ctx->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + MenuAppendItemProperties(ctx, dbus_item, &dict_iter); + ctx->message_iter_close_container(&struct_iter, &dict_iter); + ctx->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "v", &children_iter); + + if (item->sub_menu && depth > 0) { + SDL_ListNode *cursor; + + cursor = item->sub_menu; + while (cursor) { + SDL_DBusMenuItem *child; + DBusMessageIter variant_iter; + + child = cursor->entry; + ctx->message_iter_open_container(&children_iter, DBUS_TYPE_VARIANT, "(ia{sv}av)", &variant_iter); + MenuAppendItem(ctx, child, &variant_iter, depth - 1); + ctx->message_iter_close_container(&children_iter, &variant_iter); + cursor = cursor->next; + } + } + + ctx->message_iter_close_container(&struct_iter, &children_iter); + ctx->message_iter_close_container(array_iter, &struct_iter); +} + +static DBusHandlerResult MenuHandleGetLayout(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) +{ + DBusMessage *reply; + DBusMessageIter reply_iter, struct_iter, dict_iter, children_iter; + DBusMessageIter entry_iter, variant_iter; + DBusMessageIter args; + const char *key; + const char *val; + dbus_int32_t parent_id; + dbus_int32_t recursion_depth; + dbus_int32_t root_id; + dbus_uint32_t revision; + + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_get_basic(&args, &parent_id); + ctx->message_iter_next(&args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_get_basic(&args, &recursion_depth); + if (recursion_depth == -1) { + recursion_depth = 100; + } + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &reply_iter); + + revision = 0; + if (menu) { + if (menu->entry) { + revision = ((SDL_DBusMenuItem *)menu->entry)->revision; + } + } + ctx->message_iter_append_basic(&reply_iter, DBUS_TYPE_UINT32, &revision); + + ctx->message_iter_open_container(&reply_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + + root_id = 0; + ctx->message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32, &root_id); + + key = "children-display"; + val = "submenu"; + ctx->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + ctx->message_iter_close_container(&struct_iter, &dict_iter); + + ctx->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "v", &children_iter); + if (!parent_id && menu) { + SDL_ListNode *cursor; + + cursor = menu; + while (cursor) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + DBusMessageIter cvariant_iter, item_struct, item_dict, item_children; + + item = cursor->entry; + dbus_item = cursor->entry; + ctx->message_iter_open_container(&children_iter, DBUS_TYPE_VARIANT, "(ia{sv}av)", &cvariant_iter); + ctx->message_iter_open_container(&cvariant_iter, DBUS_TYPE_STRUCT, NULL, &item_struct); + ctx->message_iter_append_basic(&item_struct, DBUS_TYPE_INT32, &dbus_item->id); + ctx->message_iter_open_container(&item_struct, DBUS_TYPE_ARRAY, "{sv}", &item_dict); + MenuAppendItemProperties(ctx, dbus_item, &item_dict); + ctx->message_iter_close_container(&item_struct, &item_dict); + ctx->message_iter_open_container(&item_struct, DBUS_TYPE_ARRAY, "v", &item_children); + if (item->sub_menu && recursion_depth) { + SDL_ListNode *child_cursor; + + child_cursor = item->sub_menu; + while (child_cursor) { + SDL_DBusMenuItem *child; + DBusMessageIter child_variant; + + child = child_cursor->entry; + ctx->message_iter_open_container(&item_children, DBUS_TYPE_VARIANT, "(ia{sv}av)", &child_variant); + MenuAppendItem(ctx, child, &child_variant, recursion_depth - 1); + ctx->message_iter_close_container(&item_children, &child_variant); + child_cursor = child_cursor->next; + } + } + ctx->message_iter_close_container(&item_struct, &item_children); + ctx->message_iter_close_container(&cvariant_iter, &item_struct); + + ctx->message_iter_close_container(&children_iter, &cvariant_iter); + cursor = cursor->next; + } + } else if (parent_id) { + SDL_DBusMenuItem *parent; + SDL_MenuItem *parent_item; + + parent = MenuGetItemById(menu, parent_id); + parent_item = (SDL_MenuItem *)parent; + if (parent_item && parent_item->sub_menu) { + SDL_ListNode *cursor; + + cursor = parent_item->sub_menu; + while (cursor) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + DBusMessageIter cvariant_iter, item_struct, item_dict, item_children; + + item = cursor->entry; + dbus_item = cursor->entry; + ctx->message_iter_open_container(&children_iter, DBUS_TYPE_VARIANT, "(ia{sv}av)", &cvariant_iter); + ctx->message_iter_open_container(&cvariant_iter, DBUS_TYPE_STRUCT, NULL, &item_struct); + ctx->message_iter_append_basic(&item_struct, DBUS_TYPE_INT32, &dbus_item->id); + ctx->message_iter_open_container(&item_struct, DBUS_TYPE_ARRAY, "{sv}", &item_dict); + MenuAppendItemProperties(ctx, dbus_item, &item_dict); + ctx->message_iter_close_container(&item_struct, &item_dict); + ctx->message_iter_open_container(&item_struct, DBUS_TYPE_ARRAY, "v", &item_children); + if (item->sub_menu && recursion_depth) { + SDL_ListNode *child_cursor; + + child_cursor = item->sub_menu; + while (child_cursor) { + SDL_DBusMenuItem *child; + DBusMessageIter child_variant; + + child = child_cursor->entry; + ctx->message_iter_open_container(&item_children, DBUS_TYPE_VARIANT, "(ia{sv}av)", &child_variant); + MenuAppendItem(ctx, child, &child_variant, recursion_depth - 1); + ctx->message_iter_close_container(&item_children, &child_variant); + child_cursor = child_cursor->next; + } + } + ctx->message_iter_close_container(&item_struct, &item_children); + ctx->message_iter_close_container(&cvariant_iter, &item_struct); + + ctx->message_iter_close_container(&children_iter, &cvariant_iter); + + cursor = cursor->next; + } + } + } + ctx->message_iter_close_container(&struct_iter, &children_iter); + ctx->message_iter_close_container(&reply_iter, &struct_iter); + + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult MenuHandleEvent(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) +{ + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + DBusMessage *reply; + const char *event_id; + DBusMessageIter args; + Uint32 id; + + ctx->message_iter_init(msg, &args); + ctx->message_iter_get_basic(&args, &id); + ctx->message_iter_next(&args); + ctx->message_iter_get_basic(&args, &event_id); + + item = NULL; + dbus_item = NULL; + if (!SDL_strcmp(event_id, "clicked")) { + dbus_item = MenuGetItemById(menu, id); + item = (SDL_MenuItem *)dbus_item; + } + + reply = ctx->message_new_method_return(msg); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + + if (item) { + if (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { + item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + SDL_DBus_UpdateMenu(ctx, conn, menu, NULL, NULL, NULL, SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE); + } + + if (item->cb) { + item->cb(item, item->cb_data); + } + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult MenuHandleEventGroup(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) +{ + DBusMessage *reply; + DBusMessageIter reply_iter, id_errors_iter; + DBusMessageIter args, array_iter; + + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) == DBUS_TYPE_ARRAY) { + ctx->message_iter_recurse(&args, &array_iter); + while (ctx->message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT) { + DBusMessageIter struct_iter; + const char *event_id; + dbus_int32_t id; + + ctx->message_iter_recurse(&array_iter, &struct_iter); + if (ctx->message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_INT32) { + ctx->message_iter_get_basic(&struct_iter, &id); + ctx->message_iter_next(&struct_iter); + if (ctx->message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_STRING) { + ctx->message_iter_get_basic(&struct_iter, &event_id); + + if (!SDL_strcmp(event_id, "clicked")) { + SDL_DBusMenuItem *dbus_item; + SDL_MenuItem *item; + + dbus_item = MenuGetItemById(menu, id); + item = (SDL_MenuItem *)dbus_item; + + if (item) { + if (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { + item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + SDL_DBus_UpdateMenu(ctx, conn, menu, NULL, NULL, NULL, SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE); + } + + if (item->cb) { + item->cb(item, item->cb_data); + } + } + } + } + } + ctx->message_iter_next(&array_iter); + } + } + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &reply_iter); + ctx->message_iter_open_container(&reply_iter, DBUS_TYPE_ARRAY, "i", &id_errors_iter); + ctx->message_iter_close_container(&reply_iter, &id_errors_iter); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult MenuHandleGetProperty(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) +{ + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + DBusMessage *reply; + const char *property; + const char *val; + DBusMessageIter args; + DBusMessageIter iter, variant_iter; + dbus_int32_t id; + int int_val; + dbus_bool_t bool_val; + + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_get_basic(&args, &id); + ctx->message_iter_next(&args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_get_basic(&args, &property); + + dbus_item = MenuGetItemById(menu, id); + item = (SDL_MenuItem *)dbus_item; + if (!item) { + DBusMessage *error; + + error = ctx->message_new_error(msg, "com.canonical.dbusmenu.Error", "Item not found"); + ctx->connection_send(conn, error, NULL); + ctx->message_unref(error); + return DBUS_HANDLER_RESULT_HANDLED; + } + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &iter); + if (!SDL_strcmp(property, "label")) { + val = item->utf8 ? item->utf8 : ""; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "enabled")) { + bool_val = !(item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "visible")) { + bool_val = 1; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "type")) { + if (item->type == SDL_MENU_ITEM_TYPE_SEPERATOR) { + val = "separator"; + } else { + val = "standard"; + } + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "toggle-type")) { + if (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { + val = "checkmark"; + } else { + val = ""; + } + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "toggle-state")) { + int_val = (item->flags & SDL_MENU_ITEM_FLAGS_CHECKED) ? 1 : 0; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "i", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &int_val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "children-display")) { + val = item->sub_menu ? "submenu" : ""; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else { + val = ""; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&iter, &variant_iter); + } + + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult MenuHandleGetGroupProperties(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) +{ + #define FILTER_PROPS_SZ 32 + DBusMessage *reply; + DBusMessageIter args, array_iter, prop_iter; + DBusMessageIter iter, reply_array_iter; + const char *filter_props[FILTER_PROPS_SZ]; + dbus_int32_t *ids; + int ids_sz; + int filter_sz; + int i; + int j; + + ids_sz = 0; + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_recurse(&args, &array_iter); + if (ctx->message_iter_get_arg_type(&array_iter) == DBUS_TYPE_INT32) { + ctx->message_iter_get_fixed_array(&array_iter, &ids, &ids_sz); + } + + ctx->message_iter_next(&args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ctx->message_iter_recurse(&args, &prop_iter); + filter_sz = 0; + while (ctx->message_iter_get_arg_type(&prop_iter) == DBUS_TYPE_STRING) { + if (filter_sz < FILTER_PROPS_SZ) { + ctx->message_iter_get_basic(&prop_iter, &filter_props[filter_sz]); + filter_sz++; + } + ctx->message_iter_next(&prop_iter); + } + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &iter); + ctx->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ia{sv})", &reply_array_iter); + + for (i = 0; i < ids_sz; i++) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + + dbus_item = MenuGetItemById(menu, ids[i]); + item = (SDL_MenuItem *)dbus_item; + if (item) { + DBusMessageIter struct_iter, dict_iter; + + ctx->message_iter_open_container(&reply_array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + ctx->message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32, &ids[i]); + ctx->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + + if (filter_sz == 0) { + MenuAppendItemProperties(ctx, dbus_item, &dict_iter); + } else { + for (j = 0; j < filter_sz; j++) { + DBusMessageIter entry_iter, variant_iter; + const char *prop; + const char *val; + int int_val; + dbus_bool_t bool_val; + + prop = filter_props[j]; + if (!SDL_strcmp(prop, "label")) { + val = (item->utf8) ? item->utf8 : ""; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "type")) { + val = (item->type == SDL_MENU_ITEM_TYPE_SEPERATOR) ? "separator" : "standard"; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "enabled")) { + bool_val = !(item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "visible")) { + bool_val = 1; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "toggle-type")) { + val = (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) ? "checkmark" : ""; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "toggle-state")) { + int_val = (item->flags & SDL_MENU_ITEM_FLAGS_CHECKED) ? 1 : 0; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "i", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &int_val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } else if (!SDL_strcmp(prop, "children-display")) { + val = (item->sub_menu) ? "submenu" : ""; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &prop); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + } + } + } + + ctx->message_iter_close_container(&struct_iter, &dict_iter); + ctx->message_iter_close_container(&reply_array_iter, &struct_iter); + } + } + + ctx->message_iter_close_container(&iter, &reply_array_iter); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static dbus_int32_t MenuGetMaxItemId(SDL_ListNode *menu) +{ + SDL_ListNode *cursor; + dbus_int32_t max_id; + + max_id = 0; + cursor = menu; + while (cursor) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + + dbus_item = cursor->entry; + item = cursor->entry; + if (item) { + if (dbus_item->id > max_id) { + max_id = dbus_item->id; + } + + if (item->sub_menu) { + dbus_int32_t sub_max; + + sub_max = MenuGetMaxItemId(item->sub_menu); + if (sub_max > max_id) { + max_id = sub_max; + } + } + } + cursor = cursor->next; + } + return max_id; +} + +static void MenuAssignItemIds(SDL_ListNode *menu, dbus_int32_t *next_id) +{ + SDL_ListNode *cursor; + + cursor = menu; + while (cursor) { + SDL_MenuItem *item; + SDL_DBusMenuItem *dbus_item; + + dbus_item = cursor->entry; + item = cursor->entry; + if (item) { + if (!dbus_item->id) { + dbus_item->id = (*next_id)++; + } + + if (item->sub_menu) { + MenuAssignItemIds(item->sub_menu, next_id); + } + } + cursor = cursor->next; + } +} + +SDL_MenuItem *SDL_DBus_CreateMenuItem(void) +{ + SDL_DBusMenuItem *item; + item = SDL_malloc(sizeof(SDL_DBusMenuItem)); + item->id = 0; + item->revision = 0; + item->cb = NULL; + item->cbdata = NULL; + return (SDL_MenuItem *)item; +} + +static DBusHandlerResult MenuMessageHandler(DBusConnection *conn, DBusMessage *msg, void *user_data) +{ + SDL_ListNode *menu; + SDL_DBusMenuItem *item; + SDL_DBusContext *ctx; + + menu = user_data; + if (!menu) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!menu->entry) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + item = (SDL_DBusMenuItem *)menu->entry; + ctx = item->dbus; + + if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "GetLayout")) { + return MenuHandleGetLayout(ctx, menu, conn, msg); + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "Event")) { + return MenuHandleEvent(ctx, menu, conn, msg); + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "EventGroup")) { + return MenuHandleEventGroup(ctx, menu, conn, msg); + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "AboutToShow")) { + DBusMessage *reply; + dbus_bool_t need_update; + + if (item->cb) { + item->cb(menu, item->cbdata); + } + + need_update = FALSE; + reply = ctx->message_new_method_return(msg); + ctx->message_append_args(reply, DBUS_TYPE_BOOLEAN, &need_update, DBUS_TYPE_INVALID); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "AboutToShowGroup")) { + DBusMessage *reply; + DBusMessageIter iter, arr_iter; + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &iter); + ctx->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "i", &arr_iter); + ctx->message_iter_close_container(&iter, &arr_iter); + ctx->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "i", &arr_iter); + ctx->message_iter_close_container(&iter, &arr_iter); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "GetGroupProperties")) { + return MenuHandleGetGroupProperties(ctx, menu, conn, msg); + } else if (ctx->message_is_method_call(msg, DBUS_MENU_INTERFACE, "GetProperty")) { + return MenuHandleGetProperty(ctx, menu, conn, msg); + } else if (ctx->message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) { + DBusMessage *reply; + const char *interface_name; + const char *property_name; + const char *str_val; + DBusMessageIter args, iter, variant_iter; + dbus_uint32_t version; + + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + ctx->message_iter_get_basic(&args, &interface_name); + ctx->message_iter_next(&args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + ctx->message_iter_get_basic(&args, &property_name); + + if (!SDL_strcmp(interface_name, DBUS_MENU_INTERFACE)) { + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &iter); + if (!SDL_strcmp(property_name, "Version")) { + version = 3; + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_UINT32, &version); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property_name, "Status")) { + str_val = "normal"; + + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property_name, "TextDirection")) { + str_val = "ltr"; + + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); + ctx->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property_name, "IconThemePath")) { + DBusMessageIter array_iter; + + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "as", &variant_iter); + ctx->message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "s", &array_iter); + ctx->message_iter_close_container(&variant_iter, &array_iter); + ctx->message_iter_close_container(&iter, &variant_iter); + } else { + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + } else if (ctx->message_is_method_call(msg, "org.freedesktop.DBus.Properties", "GetAll")) { + DBusMessage *reply; + const char *interface_name; + const char *key; + DBusMessageIter args, iter, dict_iter, entry_iter, variant_iter; + dbus_uint32_t version; + + ctx->message_iter_init(msg, &args); + if (ctx->message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + ctx->message_iter_get_basic(&args, &interface_name); + + if (!SDL_strcmp(interface_name, DBUS_MENU_INTERFACE)) { + DBusMessageIter array_iter; + const char *str_val; + + reply = ctx->message_new_method_return(msg); + ctx->message_iter_init_append(reply, &iter); + ctx->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + + key = "Version"; + version = 3; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "u", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_UINT32, &version); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + + key = "Status"; + str_val = "normal"; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + + key = "TextDirection"; + str_val = "ltr"; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + + key = "IconThemePath"; + ctx->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + ctx->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + ctx->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "as", &variant_iter); + ctx->message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "s", &array_iter); + ctx->message_iter_close_container(&variant_iter, &array_iter); + ctx->message_iter_close_container(&entry_iter, &variant_iter); + ctx->message_iter_close_container(&dict_iter, &entry_iter); + + ctx->message_iter_close_container(&iter, &dict_iter); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + } else if (ctx->message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { + DBusMessage *reply; + + reply = ctx->message_new_method_return(msg); + ctx->message_append_args(reply, DBUS_TYPE_STRING, &menu_introspect, DBUS_TYPE_INVALID); + ctx->connection_send(conn, reply, NULL); + ctx->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +const char *SDL_DBus_ExportMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNode *menu) +{ + DBusObjectPathVTable vtable; + dbus_int32_t next_id; + + if (!ctx || !menu) { + return NULL; + } + + next_id = 1; + MenuAssignItemIds(menu, &next_id); + + if (menu->entry) { + SDL_DBusMenuItem *item; + + item = menu->entry; + item->dbus = ctx; + item->revision++; + } + + vtable.message_function = MenuMessageHandler; + vtable.unregister_function = NULL; + if (!ctx->connection_try_register_object_path(conn, DBUS_MENU_OBJECT_PATH, &vtable, menu, NULL)) { + return NULL; + } + + return DBUS_MENU_OBJECT_PATH; +} + +void SDL_DBus_UpdateMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNode *menu, const char *path, void (*cb)(SDL_ListNode *, const char *, void *), void *cbdata, unsigned char flags) +{ + DBusMessage *signal; + dbus_uint32_t revision; + dbus_int32_t next_id; + + if (!ctx) { + return; + } + + if (!menu) { + goto REPLACE_MENU; + } + + next_id = MenuGetMaxItemId(menu) + 1; + MenuAssignItemIds(menu, &next_id); + + revision = 0; + if (menu->entry) { + SDL_DBusMenuItem *item; + + item = menu->entry; + item->revision++; + item->dbus = ctx; + revision = item->revision; + } + + if (flags & SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE) { + goto SEND_SIGNAL; + } + +REPLACE_MENU: + if (path) { + void *udata; + + ctx->connection_get_object_path_data(conn, path, &udata); + + if (udata != menu) { + DBusObjectPathVTable vtable; + + vtable.message_function = MenuMessageHandler; + vtable.unregister_function = NULL; + ctx->connection_unregister_object_path(conn, path); + ctx->connection_try_register_object_path(conn, path, &vtable, menu, NULL); + ctx->connection_flush(conn); + + if (cb) { + cb(menu, NULL, cbdata); + } + } + } else { + DBusObjectPathVTable vtable; + SDL_DBusMenuItem *item; + + if (!menu) { + goto SEND_SIGNAL; + } + + next_id = MenuGetMaxItemId(menu) + 1; + MenuAssignItemIds(menu, &next_id); + revision = 0; + if (menu->entry) { + item = menu->entry; + item->dbus = ctx; + item->revision++; + revision = item->revision; + } + + vtable.message_function = MenuMessageHandler; + vtable.unregister_function = NULL; + ctx->connection_try_register_object_path(conn, DBUS_MENU_OBJECT_PATH, &vtable, menu, NULL); + ctx->connection_flush(conn); + + if (cb) { + cb(menu, DBUS_MENU_OBJECT_PATH, cbdata); + } + ctx->connection_flush(conn); + } + +SEND_SIGNAL: + if (path) { + signal = ctx->message_new_signal(path, DBUS_MENU_INTERFACE, "LayoutUpdated"); + } else { + signal = ctx->message_new_signal(DBUS_MENU_OBJECT_PATH, DBUS_MENU_INTERFACE, "LayoutUpdated"); + } + + if (signal) { + dbus_int32_t parent; + + parent = 0; + ctx->message_append_args(signal, DBUS_TYPE_UINT32, &revision, DBUS_TYPE_INT32, &parent, DBUS_TYPE_INVALID); + ctx->connection_send(conn, signal, NULL); + ctx->message_unref(signal); + ctx->connection_flush(conn); + } +} + +void SDL_DBus_RegisterMenuOpenCallback(SDL_ListNode *menu, bool (*cb)(SDL_ListNode *, void *), void *cbdata) +{ + SDL_DBusMenuItem *item; + + item = (SDL_DBusMenuItem *)menu->entry; + item->cb = cb; + item->cbdata = cbdata; +} + +void SDL_DBus_TransferMenuItemProperties(SDL_MenuItem *src, SDL_MenuItem *dst) +{ + SDL_DBusMenuItem *src_dbus; + SDL_DBusMenuItem *dst_dbus; + + src_dbus = (SDL_DBusMenuItem *)src; + dst_dbus = (SDL_DBusMenuItem *)dst; + dst_dbus->dbus = src_dbus->dbus; + dst_dbus->revision = src_dbus->revision; + dst_dbus->cb = src_dbus->cb; + dst_dbus->cbdata = src_dbus->cbdata; +} + +void SDL_DBus_RetractMenu(SDL_DBusContext *ctx, DBusConnection *conn, const char **path) +{ + ctx->connection_unregister_object_path(conn, *path); + *path = NULL; +} + #endif + diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index 568dd74bb2..7a70b5e787 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -28,14 +28,20 @@ #define SDL_USE_LIBDBUS 1 #include +#include "../../SDL_list.h" +#include "../../SDL_menu.h" + #ifndef DBUS_TIMEOUT_USE_DEFAULT #define DBUS_TIMEOUT_USE_DEFAULT -1 #endif #ifndef DBUS_TIMEOUT_INFINITE -#define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff) +#define DBUS_TIMEOUT_INFINITE ((int)0x7fffffff) #endif #ifndef DBUS_TYPE_UNIX_FD -#define DBUS_TYPE_UNIX_FD ((int) 'h') +#define DBUS_TYPE_UNIX_FD ((int)'h') +#endif +#ifndef DBUS_ERROR_UNKNOWN_PROPERTY +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" #endif typedef struct SDL_DBusContext @@ -95,6 +101,15 @@ typedef struct SDL_DBusContext void (*free_string_array)(char **); void (*shutdown)(void); + /* New symbols for SNI and menu export */ + int (*bus_request_name)(DBusConnection *, const char *, unsigned int, DBusError *); + dbus_bool_t (*message_is_method_call)(DBusMessage *, const char *, const char *); + DBusMessage *(*message_new_error)(DBusMessage *, const char *, const char *); + DBusMessage *(*message_new_method_return)(DBusMessage *); + dbus_bool_t (*message_iter_append_fixed_array)(DBusMessageIter *, int, const void *, int); + void (*message_iter_get_fixed_array)(DBusMessageIter *, void *, int *); + dbus_bool_t (*connection_unregister_object_path)(DBusConnection *, const char *); + dbus_bool_t (*connection_get_object_path_data)(DBusConnection *, const char *, void **); } SDL_DBusContext; extern void SDL_DBus_Init(void); @@ -128,6 +143,15 @@ extern char **SDL_DBus_DocumentsPortalRetrieveFiles(const char *key, int *files_ extern int SDL_DBus_CameraPortalRequestAccess(void); +// Menu export functions +#define SDL_DBUS_UPDATE_MENU_FLAGS_NONE 0 +extern SDL_MenuItem *SDL_DBus_CreateMenuItem(void); +extern const char *SDL_DBus_ExportMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNode *menu); +extern void SDL_DBus_UpdateMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNode *menu, const char *path, void (*cb)(SDL_ListNode *, const char *, void *), void *cbdata, unsigned char flags); +extern void SDL_DBus_RegisterMenuOpenCallback(SDL_ListNode *menu, bool (*cb)(SDL_ListNode *, void *), void *cbdata); +extern void SDL_DBus_TransferMenuItemProperties(SDL_MenuItem *src, SDL_MenuItem *dst); +extern void SDL_DBus_RetractMenu(SDL_DBusContext *ctx, DBusConnection *conn, const char **path); + #endif // HAVE_DBUS_DBUS_H #endif // SDL_dbus_h_ diff --git a/src/tray/SDL_tray_utils.c b/src/tray/SDL_tray_utils.c index 0b5eb04715..d265eecccb 100644 --- a/src/tray/SDL_tray_utils.c +++ b/src/tray/SDL_tray_utils.c @@ -20,11 +20,10 @@ */ #include "SDL_internal.h" -#include "../video/SDL_sysvideo.h" #include "../events/SDL_events_c.h" +#include "../video/SDL_sysvideo.h" #include "SDL_tray_utils.h" - static int active_trays = 0; void SDL_RegisterTray(SDL_Tray *tray) @@ -91,3 +90,8 @@ bool SDL_HasActiveTrays(void) { return (active_trays > 0); } + +int SDL_GetActiveTrayCount(void) +{ + return active_trays; +} diff --git a/src/tray/SDL_tray_utils.h b/src/tray/SDL_tray_utils.h index 49c1c05452..1aacf18146 100644 --- a/src/tray/SDL_tray_utils.h +++ b/src/tray/SDL_tray_utils.h @@ -26,3 +26,4 @@ extern void SDL_RegisterTray(SDL_Tray *tray); extern void SDL_UnregisterTray(SDL_Tray *tray); extern void SDL_CleanupTrays(void); extern bool SDL_HasActiveTrays(void); +extern int SDL_GetActiveTrayCount(void); diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c new file mode 100644 index 0000000000..b84525a130 --- /dev/null +++ b/src/tray/unix/SDL_dbustray.c @@ -0,0 +1,1177 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ + +/* Special thanks to the kind Hayden Gray (thag_iceman/A1029384756) from the SDL community for his help! */ + +#include "SDL_internal.h" +#include "../../core/linux/SDL_dbus.h" + +#ifdef SDL_USE_LIBDBUS + +#include "../../video/SDL_surface_c.h" +#include "../SDL_tray_utils.h" +#include "SDL_unixtray.h" +#include + +typedef struct SDL_TrayDriverDBus +{ + SDL_TrayDriver _parent; + + SDL_DBusContext *dbus; +} SDL_TrayDriverDBus; + +typedef struct SDL_TrayDBus +{ + SDL_Tray _parent; + + DBusConnection *connection; + char *service_name; + + char *tooltip; + SDL_Surface *surface; + + SDL_TrayClickCallback l_cb; + SDL_TrayClickCallback r_cb; + SDL_TrayClickCallback m_cb; + void *udata; + + bool block; +} SDL_TrayDBus; + +typedef struct SDL_TrayMenuDBus +{ + SDL_TrayMenu _parent; + + SDL_ListNode *menu; + const char *menu_path; + + SDL_TrayEntry **array_representation; +} SDL_TrayMenuDBus; + +typedef struct SDL_TrayEntryDBus +{ + SDL_TrayEntry _parent; + + SDL_MenuItem *item; + SDL_TrayMenuDBus *sub_menu; +} SDL_TrayEntryDBus; + +#define SNI_INTERFACE "org.kde.StatusNotifierItem" +#define SNI_WATCHER_SERVICE "org.kde.StatusNotifierWatcher" +#define SNI_WATCHER_PATH "/StatusNotifierWatcher" +#define SNI_WATCHER_INTERFACE "org.kde.StatusNotifierWatcher" +#define SNI_OBJECT_PATH "/StatusNotifierItem" +static const char *sni_introspect = "\r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n\r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n"; + +static DBusHandlerResult TrayHandleGetAllProps(SDL_Tray *tray, SDL_TrayDBus *tray_dbus, SDL_TrayDriverDBus *driver, DBusMessage *msg) +{ + SDL_TrayMenuDBus *menu_dbus; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + DBusMessageIter struct_iter, array_iter; + DBusMessage *reply; + const char *interface; + const char *key; + const char *value; + const char *empty; + dbus_uint32_t uint32_val; + dbus_bool_t bool_value; + + menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + empty = ""; + driver->dbus->message_iter_init(msg, &iter); + driver->dbus->message_iter_get_basic(&iter, &interface); + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->message_iter_init_append(reply, &iter); + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + + key = "Category"; + value = "ApplicationStatus"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "Id"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &tray_dbus->service_name); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "Title"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "Status"; + value = "Active"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "IconName"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "WindowId"; + uint32_val = 0; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "i", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &uint32_val); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + key = "ItemIsMenu"; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + if (menu_dbus && menu_dbus->menu_path) { + bool_value = TRUE; + } else { + bool_value = FALSE; + } + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_value); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + + if (menu_dbus && menu_dbus->menu_path) { + key = "Menu"; + value = menu_dbus->menu_path; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "o", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_OBJECT_PATH, &value); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + } else { + key = "Menu"; + value = "/NO_DBUSMENU"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "o", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_OBJECT_PATH, &value); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + } + + if (tray_dbus->surface) { + DBusMessageIter pixmap_array_iter, pixmap_struct_iter, pixmap_byte_array_iter; + + key = "IconPixmap"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "a(iiay)", &variant_iter); + driver->dbus->message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "(iiay)", &pixmap_array_iter); + driver->dbus->message_iter_open_container(&pixmap_array_iter, DBUS_TYPE_STRUCT, NULL, &pixmap_struct_iter); + driver->dbus->message_iter_append_basic(&pixmap_struct_iter, DBUS_TYPE_INT32, &tray_dbus->surface->w); + driver->dbus->message_iter_append_basic(&pixmap_struct_iter, DBUS_TYPE_INT32, &tray_dbus->surface->h); + driver->dbus->message_iter_open_container(&pixmap_struct_iter, DBUS_TYPE_ARRAY, "y", &pixmap_byte_array_iter); + driver->dbus->message_iter_append_fixed_array(&pixmap_byte_array_iter, DBUS_TYPE_BYTE, &tray_dbus->surface->pixels, tray_dbus->surface->pitch * tray_dbus->surface->h); + driver->dbus->message_iter_close_container(&pixmap_struct_iter, &pixmap_byte_array_iter); + driver->dbus->message_iter_close_container(&pixmap_array_iter, &pixmap_struct_iter); + driver->dbus->message_iter_close_container(&variant_iter, &pixmap_array_iter); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + } + + if (tray_dbus->tooltip) { + key = "ToolTip"; + driver->dbus->message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter); + driver->dbus->message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key); + driver->dbus->message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, "(sa(iiay)ss)", &variant_iter); + driver->dbus->message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(iiay)", &array_iter); + driver->dbus->message_iter_close_container(&struct_iter, &array_iter); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &tray_dbus->tooltip); + driver->dbus->message_iter_close_container(&variant_iter, &struct_iter); + driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); + driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); + driver->dbus->message_iter_close_container(&iter, &dict_iter); + } + + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult TrayHandleGetProp(SDL_Tray *tray, SDL_TrayDBus *tray_dbus, SDL_TrayDriverDBus *driver, DBusMessage *msg) +{ + SDL_TrayMenuDBus *menu_dbus; + DBusMessageIter iter, variant_iter; + DBusMessage *reply; + const char *interface, *property; + const char *value; + const char *empty; + dbus_bool_t bool_value; + + menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + empty = ""; + driver->dbus->message_iter_init(msg, &iter); + driver->dbus->message_iter_get_basic(&iter, &interface); + driver->dbus->message_iter_next(&iter); + driver->dbus->message_iter_get_basic(&iter, &property); + + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->message_iter_init_append(reply, &iter); + + if (!SDL_strcmp(property, "Category")) { + value = "ApplicationStatus"; + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "Id")) { + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &tray_dbus->service_name); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "Title")) { + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "Status")) { + value = "Active"; + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "IconName")) { + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "ItemIsMenu")) { + if (menu_dbus && menu_dbus->menu_path) { + bool_value = TRUE; + } else { + bool_value = FALSE; + } + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "b", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &bool_value); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "Menu")) { + if (menu_dbus && menu_dbus->menu_path) { + value = menu_dbus->menu_path; + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "o", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_OBJECT_PATH, &value); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else { + value = "/NO_DBUSMENU"; + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "o", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_OBJECT_PATH, &value); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } + } else if (!SDL_strcmp(property, "IconPixmap") && tray_dbus->surface) { + DBusMessageIter array_iter, struct_iter; + DBusMessageIter byte_array_iter; + + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "a(iiay)", &variant_iter); + driver->dbus->message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "(iiay)", &array_iter); + driver->dbus->message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32, &tray_dbus->surface->w); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32, &tray_dbus->surface->h); + driver->dbus->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "y", &byte_array_iter); + driver->dbus->message_iter_append_fixed_array(&byte_array_iter, DBUS_TYPE_BYTE, &tray_dbus->surface->pixels, tray_dbus->surface->pitch * tray_dbus->surface->h); + driver->dbus->message_iter_close_container(&struct_iter, &byte_array_iter); + driver->dbus->message_iter_close_container(&array_iter, &struct_iter); + driver->dbus->message_iter_close_container(&variant_iter, &array_iter); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "ToolTip") && tray_dbus->tooltip) { + DBusMessageIter struct_iter, array_iter; + + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "(sa(iiay)ss)", &variant_iter); + driver->dbus->message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(iiay)", &array_iter); + driver->dbus->message_iter_close_container(&struct_iter, &array_iter); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &tray_dbus->tooltip); + driver->dbus->message_iter_close_container(&variant_iter, &struct_iter); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else if (!SDL_strcmp(property, "WindowId")) { + dbus_uint32_t uint32_val; + + uint32_val = 0; + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "i", &variant_iter); + driver->dbus->message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &uint32_val); + driver->dbus->message_iter_close_container(&iter, &variant_iter); + } else { + driver->dbus->message_unref(reply); + reply = driver->dbus->message_new_error(msg, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + } + + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult TrayMessageHandler(DBusConnection *connection, DBusMessage *msg, void *user_data) +{ + SDL_Tray *tray; + SDL_TrayDBus *tray_dbus; + SDL_TrayDriverDBus *driver; + DBusMessage *reply; + + tray = user_data; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + + if (driver->dbus->message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) { + return TrayHandleGetProp(tray, tray_dbus, driver, msg); + } else if (driver->dbus->message_is_method_call(msg, "org.freedesktop.DBus.Properties", "GetAll")) { + return TrayHandleGetAllProps(tray, tray_dbus, driver, msg); + } else if (driver->dbus->message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->message_append_args(reply, DBUS_TYPE_STRING, &sni_introspect, DBUS_TYPE_INVALID); + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (driver->dbus->message_is_method_call(msg, SNI_INTERFACE, "ContextMenu")) { + if (tray_dbus->r_cb) { + tray_dbus->r_cb(tray_dbus->udata, tray); + } + + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (driver->dbus->message_is_method_call(msg, SNI_INTERFACE, "Activate")) { + if (tray_dbus->l_cb) { + tray_dbus->l_cb(tray_dbus->udata, tray); + } + + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (driver->dbus->message_is_method_call(msg, SNI_INTERFACE, "SecondaryActivate")) { + if (tray_dbus->m_cb) { + tray_dbus->m_cb(tray_dbus->udata, tray); + } + + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (driver->dbus->message_is_method_call(msg, SNI_INTERFACE, "Scroll")) { + DBusError err; + char *orientation; + Sint32 delta; + + driver->dbus->error_init(&err); + driver->dbus->message_get_args(msg, &err, DBUS_TYPE_INT32, &delta, DBUS_TYPE_STRING, &orientation, DBUS_TYPE_INVALID); + if (!driver->dbus->error_is_set(&err)) { + /* Scroll callback support will come later :) */ + } else { + driver->dbus->error_free(&err); + } + + reply = driver->dbus->message_new_method_return(msg); + driver->dbus->connection_send(tray_dbus->connection, reply, NULL); + driver->dbus->message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) +{ + SDL_TrayDriverDBus *dbus_driver; + SDL_TrayDBus *tray_dbus; + SDL_Tray *tray; + SDL_Surface *icon; + const char *tooltip; + const char *object_path; + char *register_name; + DBusObjectPathVTable vtable; + DBusError err; + int status; + dbus_bool_t bool_status; +#define CLEANUP() \ + SDL_free(tray_dbus->tooltip); \ + SDL_DestroySurface(tray_dbus->surface); \ + SDL_free(tray_dbus) +#define CLEANUP2() \ + dbus_driver->dbus->connection_close(tray_dbus->connection); \ + CLEANUP() + + /* Get properties */ + tooltip = SDL_GetStringProperty(props, SDL_PROP_TRAY_CREATE_TOOLTIP_STRING, NULL); + icon = (SDL_Surface *)SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_ICON_POINTER, NULL); + + /* Allocate the tray structure */ + tray_dbus = SDL_malloc(sizeof(SDL_TrayDBus)); + tray = (SDL_Tray *)tray_dbus; + if (!tray_dbus) { + return NULL; + } + + /* Populate */ + tray->menu = NULL; + tray->driver = driver; + if (tooltip) { + tray_dbus->tooltip = SDL_strdup(tooltip); + } else { + tray_dbus->tooltip = NULL; + } + tray_dbus->surface = SDL_ConvertSurface(icon, SDL_PIXELFORMAT_ARGB32); + tray_dbus->block = false; + + /* Connect */ + dbus_driver = (SDL_TrayDriverDBus *)driver; + dbus_driver->dbus->error_init(&err); + tray_dbus->connection = dbus_driver->dbus->bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_driver->dbus->error_is_set(&err)) { + SDL_SetError("Unable to create tray: %s", err.message); + dbus_driver->dbus->error_free(&err); + CLEANUP(); + return NULL; + } + if (!tray_dbus->connection) { + SDL_SetError("Unable to create tray: unable to get connection!"); + CLEANUP(); + return NULL; + } + + /* Request name */ + driver->count++; + SDL_asprintf(&tray_dbus->service_name, "org.kde.StatusNotifierItem-%d-%d", getpid(), driver->count); + status = dbus_driver->dbus->bus_request_name(tray_dbus->connection, tray_dbus->service_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_driver->dbus->error_is_set(&err)) { + SDL_SetError("Unable to create tray: %s", err.message); + dbus_driver->dbus->error_free(&err); + CLEANUP2(); + return NULL; + } + if (status != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + SDL_SetError("Unable to create tray: unable to request a unique name!"); + CLEANUP2(); + return NULL; + } + + /* Create object */ + object_path = SNI_OBJECT_PATH; + vtable.message_function = TrayMessageHandler; + bool_status = dbus_driver->dbus->connection_try_register_object_path(tray_dbus->connection, object_path, &vtable, tray_dbus, &err); + if (dbus_driver->dbus->error_is_set(&err)) { + SDL_SetError("Unable to create tray: %s", err.message); + dbus_driver->dbus->error_free(&err); + CLEANUP2(); + return NULL; + } + if (!bool_status) { + SDL_SetError("Unable to create tray: unable to register object path!"); + CLEANUP2(); + return NULL; + } + + /* Register */ + register_name = tray_dbus->service_name; + if (!SDL_DBus_CallVoidMethodOnConnection(tray_dbus->connection, SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, SNI_WATCHER_INTERFACE, "RegisterStatusNotifierItem", DBUS_TYPE_STRING, ®ister_name, DBUS_TYPE_INVALID)) { + SDL_SetError("Unable to create tray: unable to register status notifier item!"); + CLEANUP2(); + return NULL; + } + + /* Icon mouse event callbacks */ + tray_dbus->l_cb = (SDL_TrayClickCallback)SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_LEFTCLICK_CALLBACK_POINTER, NULL); + tray_dbus->r_cb = (SDL_TrayClickCallback)SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_RIGHTCLICK_CALLBACK_POINTER, NULL); + tray_dbus->m_cb = (SDL_TrayClickCallback)SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_MIDDLECLICK_CALLBACK_POINTER, NULL); + tray_dbus->udata = SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_USERDATA_POINTER, NULL); + + return tray; +} + +void DestroyDriver(SDL_TrayDriver *driver) +{ + SDL_DBus_Quit(); + SDL_free(driver); +} + +void DestroyMenu(SDL_TrayMenu *menu) +{ + SDL_TrayMenuDBus *menu_dbus; + + if (!menu) { + return; + } + + menu_dbus = (SDL_TrayMenuDBus *)menu; + + if (menu_dbus->menu) { + SDL_ListNode *cursor; + + cursor = menu_dbus->menu; + while (cursor) { + SDL_MenuItem *item; + SDL_TrayEntryDBus *entry; + + item = cursor->entry; + entry = item->udata; + + if (entry->sub_menu) { + DestroyMenu((SDL_TrayMenu *)entry->sub_menu); + entry->sub_menu = NULL; + } + SDL_free(item); + SDL_free(entry); + + cursor = cursor->next; + } + SDL_ListClear(&menu_dbus->menu); + } + + if (menu_dbus->array_representation) { + SDL_free(menu_dbus->array_representation); + } + + SDL_free(menu_dbus); +} + +void DestroyTray(SDL_Tray *tray) +{ + SDL_TrayDBus *tray_dbus; + SDL_TrayDriverDBus *driver; + + driver = (SDL_TrayDriverDBus *)tray->driver; + tray_dbus = (SDL_TrayDBus *)tray; + + /* Destroy connection */ + driver->dbus->connection_flush(tray_dbus->connection); + tray_dbus->block = true; + driver->dbus->connection_close(tray_dbus->connection); + tray_dbus->connection = NULL; + + /* Destroy icon and tooltip */ + SDL_free(tray_dbus->tooltip); + SDL_DestroySurface(tray_dbus->surface); + + /* Destroy the menus and entries */ + if (tray->menu) { + DestroyMenu(tray->menu); + tray->menu = NULL; + } + + /* Free the tray */ + SDL_free(tray); +} + +void UpdateTray(SDL_Tray *tray) +{ + SDL_TrayDBus *tray_dbus; + SDL_TrayDriverDBus *driver; + + driver = (SDL_TrayDriverDBus *)tray->driver; + tray_dbus = (SDL_TrayDBus *)tray; + + if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { + return; + } + + if (tray_dbus->block) { + return; + } + + driver->dbus->connection_read_write(tray_dbus->connection, 0); + while (driver->dbus->connection_dispatch(tray_dbus->connection) == DBUS_DISPATCH_DATA_REMAINS) { + if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { + break; + } + + if (tray_dbus->block) { + break; + } + + SDL_DelayNS(SDL_US_TO_NS(10)); + } +} + +void SetTrayIcon(SDL_Tray *tray, SDL_Surface *surface) +{ + SDL_TrayDBus *tray_dbus; + SDL_TrayDriverDBus *driver; + DBusMessage *signal; + + driver = (SDL_TrayDriverDBus *)tray->driver; + tray_dbus = (SDL_TrayDBus *)tray; + + if (tray_dbus->surface) { + SDL_DestroySurface(tray_dbus->surface); + } + tray_dbus->surface = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB32); + + signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, SNI_INTERFACE, "NewIcon"); + driver->dbus->connection_send(tray_dbus->connection, signal, NULL); + driver->dbus->connection_flush(tray_dbus->connection); + driver->dbus->message_unref(signal); +} + +void SetTrayTooltip(SDL_Tray *tray, const char *text) +{ + SDL_TrayDBus *tray_dbus; + SDL_TrayDriverDBus *driver; + DBusMessage *signal; + + driver = (SDL_TrayDriverDBus *)tray->driver; + tray_dbus = (SDL_TrayDBus *)tray; + + if (tray_dbus->tooltip) { + SDL_free(tray_dbus->tooltip); + } + + if (text) { + tray_dbus->tooltip = SDL_strdup(text); + } else { + tray_dbus->tooltip = NULL; + } + + signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, SNI_INTERFACE, "NewToolTip"); + driver->dbus->connection_send(tray_dbus->connection, signal, NULL); + driver->dbus->connection_flush(tray_dbus->connection); + driver->dbus->message_unref(signal); +} + +SDL_TrayMenu *CreateTrayMenu(SDL_Tray *tray) +{ + SDL_TrayMenuDBus *menu_dbus; + + menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); + tray->menu = (SDL_TrayMenu *)menu_dbus; + if (!menu_dbus) { + SDL_SetError("Unable to create tray menu: allocation failure!"); + return NULL; + } + + menu_dbus->menu = NULL; + menu_dbus->menu_path = NULL; + tray->menu->parent_tray = tray; + tray->menu->parent_entry = NULL; + menu_dbus->array_representation = NULL; + + return tray->menu; +} + +SDL_TrayMenu *CreateTraySubmenu(SDL_TrayEntry *entry) +{ + SDL_TrayMenuDBus *menu_dbus; + SDL_TrayMenu *menu; + SDL_TrayEntryDBus *entry_dbus; + + entry_dbus = (SDL_TrayEntryDBus *)entry; + menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); + menu = (SDL_TrayMenu *)menu_dbus; + if (!menu_dbus) { + SDL_SetError("Unable to create tray submenu: allocation failure!"); + return NULL; + } + + menu_dbus->menu = NULL; + menu_dbus->menu_path = NULL; + menu->parent_tray = entry->parent->parent_tray; + menu->parent_entry = entry; + entry_dbus->sub_menu = menu_dbus; + menu_dbus->array_representation = NULL; + + return menu; +} + +SDL_TrayMenu *GetTraySubmenu(SDL_TrayEntry *entry) +{ + SDL_TrayEntryDBus *entry_dbus; + + entry_dbus = (SDL_TrayEntryDBus *)entry; + + return (SDL_TrayMenu *)entry_dbus->sub_menu; +} + +bool TrayRightClickHandler(SDL_ListNode *menu, void *udata) +{ + SDL_TrayDBus *tray_dbus; + + tray_dbus = (SDL_TrayDBus *)udata; + + return tray_dbus->r_cb(tray_dbus->udata, (SDL_Tray *)tray_dbus); +} + +void TraySendNewMenu(SDL_Tray *tray, const char *new_path) { + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *menu_dbus; + DBusMessage *signal; + + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + driver->dbus->connection_flush(tray_dbus->connection); + + signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, "org.freedesktop.DBus.Properties", "PropertiesChanged"); + if (signal) { + DBusMessageIter iter, dict, ientry, value; + const char *iface; + const char *prop; + const char *path; + dbus_bool_t bool_val; + + iface = SNI_INTERFACE; + prop = "Menu"; + if (new_path) { + path = menu_dbus->menu_path = new_path; + } else { + path = menu_dbus->menu_path; + } + bool_val = TRUE; + driver->dbus->message_iter_init_append(signal, &iter); + driver->dbus->message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface); + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict); + driver->dbus->message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &ientry); + driver->dbus->message_iter_append_basic(&ientry, DBUS_TYPE_STRING, &prop); + driver->dbus->message_iter_open_container(&ientry, DBUS_TYPE_VARIANT, "o", &value); + driver->dbus->message_iter_append_basic(&value, DBUS_TYPE_OBJECT_PATH, &path); + driver->dbus->message_iter_close_container(&ientry, &value); + driver->dbus->message_iter_close_container(&dict, &ientry); + prop = "ItemIsMenu"; + driver->dbus->message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &ientry); + driver->dbus->message_iter_append_basic(&ientry, DBUS_TYPE_STRING, &prop); + driver->dbus->message_iter_open_container(&ientry, DBUS_TYPE_VARIANT, "b", &value); + driver->dbus->message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &bool_val); + driver->dbus->message_iter_close_container(&ientry, &value); + driver->dbus->message_iter_close_container(&dict, &ientry); + driver->dbus->message_iter_close_container(&iter, &dict); + driver->dbus->message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &dict); + driver->dbus->message_iter_close_container(&iter, &dict); + driver->dbus->connection_send(tray_dbus->connection, signal, NULL); + driver->dbus->connection_flush(tray_dbus->connection); + driver->dbus->message_unref(signal); + } + + signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, SNI_INTERFACE, "NewMenu"); + if (signal) { + driver->dbus->connection_send(tray_dbus->connection, signal, NULL); + driver->dbus->connection_flush(tray_dbus->connection); + driver->dbus->message_unref(signal); + } + + driver->dbus->connection_flush(tray_dbus->connection); +} + + +void TrayNewMenuOnMenuUpdateCallback(SDL_ListNode *menu, const char *path, void *cbdata) { + TraySendNewMenu((SDL_Tray *)cbdata, path); +} + +SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, SDL_TrayEntryFlags flags) +{ + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayMenuDBus *menu_dbus; + SDL_TrayDBus *tray_dbus; + SDL_TrayEntry *entry; + SDL_TrayEntryDBus *entry_dbus; + bool update; + + tray = menu->parent_tray; + menu_dbus = (SDL_TrayMenuDBus *)menu; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + + entry_dbus = SDL_malloc(sizeof(SDL_TrayEntryDBus)); + entry = (SDL_TrayEntry *)entry_dbus; + if (!entry_dbus) { + SDL_SetError("Unable to create tray entry: allocation failure!"); + return NULL; + } + + entry->parent = menu; + entry_dbus->item = SDL_DBus_CreateMenuItem(); + entry_dbus->item->utf8 = label; + if (!label) { + entry_dbus->item->type = SDL_MENU_ITEM_TYPE_SEPERATOR; + } else if (flags & SDL_TRAYENTRY_CHECKBOX) { + entry_dbus->item->type = SDL_MENU_ITEM_TYPE_CHECKBOX; + } else { + entry_dbus->item->type = SDL_MENU_ITEM_TYPE_NORMAL; + } + entry_dbus->item->flags = SDL_MENU_ITEM_FLAGS_NONE; + entry_dbus->item->cb_data = NULL; + entry_dbus->item->cb = NULL; + entry_dbus->item->sub_menu = NULL; + entry_dbus->item->udata = entry_dbus; + entry_dbus->sub_menu = NULL; + + if (menu_dbus->menu) { + update = true; + } else { + update = false; + } + + if (menu->parent_entry) { + update = true; + } + + SDL_ListInsertAtPosition(&menu_dbus->menu, pos, entry_dbus->item); + + if (menu->parent_entry) { + SDL_TrayEntryDBus *parent_entry_dbus; + + parent_entry_dbus = (SDL_TrayEntryDBus *)menu->parent_entry; + parent_entry_dbus->item->sub_menu = menu_dbus->menu; + } + + if (update) { + SDL_TrayMenuDBus *main_menu_dbus; + + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); + } else { + menu_dbus->menu_path = SDL_DBus_ExportMenu(driver->dbus, tray_dbus->connection, menu_dbus->menu); + + if (menu_dbus->menu_path) { + TraySendNewMenu(tray, NULL); + } + } + + if (menu->parent_tray && !menu->parent_entry && tray_dbus->r_cb) { + SDL_DBus_RegisterMenuOpenCallback(menu_dbus->menu, TrayRightClickHandler, tray); + } + + return entry; +} + +SDL_TrayEntry **GetTrayEntries(SDL_TrayMenu *menu, int *count) +{ + SDL_TrayEntry **array_representation; + SDL_TrayMenuDBus *menu_dbus; + SDL_ListNode *cursor; + int sz; + int i; + + menu_dbus = (SDL_TrayMenuDBus *)menu; + + if (menu_dbus->array_representation) { + SDL_free(menu_dbus->array_representation); + } + + sz = SDL_ListCountEntries(&menu_dbus->menu); + array_representation = SDL_calloc(sz + 1, sizeof(SDL_TrayEntry *)); + if (!array_representation) { + SDL_SetError("Memory allocation failure!"); + return NULL; + } + + i = 0; + cursor = menu_dbus->menu; + while (cursor) { + SDL_MenuItem *item; + + item = cursor->entry; + array_representation[i] = item->udata; + cursor = cursor->next; + i++; + } + array_representation[sz] = NULL; + + *count = sz; + return array_representation; +} + +void RemoveTrayEntry(SDL_TrayEntry *entry) +{ + SDL_TrayEntryDBus *entry_dbus; + SDL_TrayMenuDBus *menu_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + const char *old_path; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + entry_dbus = (SDL_TrayEntryDBus *)entry; + menu_dbus = (SDL_TrayMenuDBus *)entry->parent; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + tray_dbus->block = true; + if (menu_dbus->menu->entry == entry_dbus->item && menu_dbus->menu->next) { + SDL_DBus_TransferMenuItemProperties(entry_dbus->item, (SDL_MenuItem *)menu_dbus->menu->next->entry); + } + + old_path = NULL; + if (!main_menu_dbus->menu->next) { + old_path = main_menu_dbus->menu_path; + } + + driver->dbus->connection_flush(tray_dbus->connection); + DestroyMenu((SDL_TrayMenu *)entry_dbus->sub_menu); + SDL_ListRemove(&menu_dbus->menu, entry_dbus->item); + SDL_free(entry_dbus->item); + SDL_free(entry); + + if (old_path) { + SDL_DBus_RetractMenu(driver->dbus, tray_dbus->connection, &main_menu_dbus->menu_path); + } + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); + driver->dbus->connection_flush(tray_dbus->connection); + tray_dbus->block = false; +} + +void EntryCallback(SDL_MenuItem *item, void *udata) +{ + SDL_TrayCallback entry_cb; + + entry_cb = item->udata2; + entry_cb(udata, item->udata); +} + +void SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata) +{ + SDL_TrayEntryDBus *entry_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + entry_dbus = (SDL_TrayEntryDBus *)entry; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + entry_dbus->item->cb = EntryCallback; + entry_dbus->item->cb_data = userdata; + entry_dbus->item->udata2 = callback; + + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); +} + +void SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) +{ + SDL_TrayEntryDBus *entry_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + entry_dbus = (SDL_TrayEntryDBus *)entry; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + entry_dbus->item->utf8 = label; + + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); +} + +const char *GetTrayEntryLabel(SDL_TrayEntry *entry) +{ + return ((SDL_TrayEntryDBus *)entry)->item->utf8; +} + +void SetTrayEntryChecked(SDL_TrayEntry *entry, bool val) +{ + SDL_TrayEntryDBus *entry_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + entry_dbus = (SDL_TrayEntryDBus *)entry; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + if (val) { + entry_dbus->item->flags |= SDL_MENU_ITEM_FLAGS_CHECKED; + } else { + entry_dbus->item->flags &= ~(SDL_MENU_ITEM_FLAGS_CHECKED); + } + + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); +} + +bool GetTrayEntryChecked(SDL_TrayEntry *entry) +{ + return ((SDL_TrayEntryDBus *)entry)->item->flags & SDL_MENU_ITEM_FLAGS_CHECKED; +} + +void SetTrayEntryEnabled(SDL_TrayEntry *entry, bool val) +{ + SDL_TrayEntryDBus *entry_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + entry_dbus = (SDL_TrayEntryDBus *)entry; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + if (!val) { + entry_dbus->item->flags |= SDL_MENU_ITEM_FLAGS_DISABLED; + } else { + entry_dbus->item->flags &= ~(SDL_MENU_ITEM_FLAGS_DISABLED); + } + + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); +} + +bool GetTrayEntryEnabled(SDL_TrayEntry *entry) +{ + return !(((SDL_TrayEntryDBus *)entry)->item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); +} + +void ClickTrayEntry(SDL_TrayEntry *entry) +{ + SDL_TrayEntryDBus *dbus_entry; + SDL_TrayCallback entry_cb; + + dbus_entry = (SDL_TrayEntryDBus *)entry; + if (dbus_entry->item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; + + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + + dbus_entry->item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); + } + entry_cb = dbus_entry->item->udata2; + entry_cb(dbus_entry->item->cb_data, dbus_entry->item->udata); +} + +SDL_TrayDriver *SDL_Tray_CreateDBusDriver(void) +{ + SDL_TrayDriverDBus *dbus_driver; + SDL_TrayDriver *driver; + SDL_DBusContext *ctx; + DBusMessage *saved; + char **paths; + int count; + int i; + bool sni_supported; + + /* Init DBus and get context */ + SDL_DBus_Init(); + ctx = SDL_DBus_GetContext(); + if (!ctx) { + return NULL; + } + + /* SNI support detection */ + sni_supported = false; + paths = NULL; + count = 0; + + if (SDL_DBus_CallMethod(&saved, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", DBUS_TYPE_INVALID, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &paths, &count, DBUS_TYPE_INVALID)) { + SDL_DBus_FreeReply(&saved); + + if (paths) { + bool watcher_found; + + watcher_found = false; + for (i = 0; i < count; i++) { + if (!SDL_strcmp(paths[i], SNI_WATCHER_SERVICE)) { + watcher_found = true; + } + } + ctx->free_string_array(paths); + + if (watcher_found) { + dbus_bool_t host_registered; + + host_registered = FALSE; + SDL_DBus_QueryProperty(&saved, SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, SNI_WATCHER_INTERFACE, "IsStatusNotifierHostRegistered", DBUS_TYPE_BOOLEAN, &host_registered); + SDL_DBus_FreeReply(&saved); + if (host_registered) { + sni_supported = true; + } + } + } + } + + if (!sni_supported) { + SDL_SetError("Unable to create tray: no SNI support!"); + SDL_DBus_Quit(); + return NULL; + } + + /* Allocate the driver struct */ + dbus_driver = SDL_malloc(sizeof(SDL_TrayDriverDBus)); + driver = (SDL_TrayDriver *)dbus_driver; + if (!dbus_driver) { + return NULL; + } + + /* Populate */ + dbus_driver->dbus = ctx; + driver->name = "dbus"; + driver->count = 0; + driver->CreateTray = CreateTray; + driver->DestroyTray = DestroyTray; + driver->UpdateTray = UpdateTray; + driver->SetTrayIcon = SetTrayIcon; + driver->SetTrayTooltip = SetTrayTooltip; + driver->CreateTrayMenu = CreateTrayMenu; + driver->InsertTrayEntryAt = InsertTrayEntryAt; + driver->CreateTraySubmenu = CreateTraySubmenu; + driver->GetTraySubmenu = GetTraySubmenu; + driver->GetTrayEntries = GetTrayEntries; + driver->RemoveTrayEntry = RemoveTrayEntry; + driver->SetTrayEntryCallback = SetTrayEntryCallback; + driver->SetTrayEntryLabel = SetTrayEntryLabel; + driver->GetTrayEntryLabel = GetTrayEntryLabel; + driver->SetTrayEntryChecked = SetTrayEntryChecked; + driver->GetTrayEntryChecked = GetTrayEntryChecked; + driver->SetTrayEntryEnabled = SetTrayEntryEnabled; + driver->GetTrayEntryEnabled = GetTrayEntryEnabled; + driver->ClickTrayEntry = ClickTrayEntry; + driver->DestroyDriver = DestroyDriver; + + return driver; +} + +#endif diff --git a/src/tray/unix/SDL_tray.c b/src/tray/unix/SDL_tray.c index d932dd3754..607c24df46 100644 --- a/src/tray/unix/SDL_tray.c +++ b/src/tray/unix/SDL_tray.c @@ -22,326 +22,87 @@ #include "SDL_internal.h" #include "../SDL_tray_utils.h" -#include "../../video/SDL_stb_c.h" +#include "SDL_unixtray.h" -#include -#include - -/* getpid() */ -#include - -/* APPINDICATOR_HEADER is not exposed as a build setting, but the code has been - written nevertheless to make future maintenance easier. */ -#ifdef APPINDICATOR_HEADER -#include APPINDICATOR_HEADER -#else -#include "../../core/unix/SDL_gtk.h" - -/* ------------------------------------------------------------------------- */ -/* BEGIN THIRD-PARTY HEADER CONTENT */ -/* ------------------------------------------------------------------------- */ -/* AppIndicator */ - -typedef enum { - APP_INDICATOR_CATEGORY_APPLICATION_STATUS, - APP_INDICATOR_CATEGORY_COMMUNICATIONS, - APP_INDICATOR_CATEGORY_SYSTEM_SERVICES, - APP_INDICATOR_CATEGORY_HARDWARE, - APP_INDICATOR_CATEGORY_OTHER -} AppIndicatorCategory; - -typedef enum { - APP_INDICATOR_STATUS_PASSIVE, - APP_INDICATOR_STATUS_ACTIVE, - APP_INDICATOR_STATUS_ATTENTION -} AppIndicatorStatus; - -typedef struct _AppIndicator AppIndicator; - -static AppIndicator *(*app_indicator_new)(const gchar *id, const gchar *icon_name, AppIndicatorCategory category); -static void (*app_indicator_set_status)(AppIndicator *self, AppIndicatorStatus status); -static void (*app_indicator_set_icon)(AppIndicator *self, const gchar *icon_name); -static void (*app_indicator_set_menu)(AppIndicator *self, GtkMenu *menu); - -/* ------------------------------------------------------------------------- */ -/* END THIRD-PARTY HEADER CONTENT */ -/* ------------------------------------------------------------------------- */ -#endif - -static void *libappindicator = NULL; - -static void quit_appindicator(void) -{ - if (libappindicator) { - dlclose(libappindicator); - libappindicator = NULL; - } -} - -const char *appindicator_names[] = { -#ifdef SDL_PLATFORM_OPENBSD - "libayatana-appindicator3.so", - "libappindicator3.so", -#else - "libayatana-appindicator3.so.1", - "libappindicator3.so.1", -#endif - NULL -}; - -static void *find_lib(const char **names) -{ - const char **name_ptr = names; - void *handle = NULL; - - do { - handle = dlopen(*name_ptr, RTLD_LAZY); - } while (*++name_ptr && !handle); - - return handle; -} - -static bool init_appindicator(void) -{ - if (libappindicator) { - return true; - } - - libappindicator = find_lib(appindicator_names); - - if (!libappindicator) { - quit_appindicator(); - return SDL_SetError("Could not load AppIndicator libraries"); - } - - app_indicator_new = dlsym(libappindicator, "app_indicator_new"); - app_indicator_set_status = dlsym(libappindicator, "app_indicator_set_status"); - app_indicator_set_icon = dlsym(libappindicator, "app_indicator_set_icon"); - app_indicator_set_menu = dlsym(libappindicator, "app_indicator_set_menu"); - - if (!app_indicator_new || - !app_indicator_set_status || - !app_indicator_set_icon || - !app_indicator_set_menu) { - quit_appindicator(); - return SDL_SetError("Could not load AppIndicator functions"); - } - - return true; -} - -struct SDL_TrayMenu { - GtkMenuShell *menu; - - int nEntries; - SDL_TrayEntry **entries; - - SDL_Tray *parent_tray; - SDL_TrayEntry *parent_entry; -}; - -struct SDL_TrayEntry { - SDL_TrayMenu *parent; - GtkWidget *item; - - /* Checkboxes are "activated" when programmatically checked/unchecked; this - is a workaround. */ - bool ignore_signal; - - SDL_TrayEntryFlags flags; - SDL_TrayCallback callback; - void *userdata; - SDL_TrayMenu *submenu; -}; - -struct SDL_Tray { - AppIndicator *indicator; - SDL_TrayMenu *menu; - char *icon_dir; - char *icon_path; - - GtkMenuShell *menu_cached; -}; - -static void call_callback(GtkMenuItem *item, gpointer ptr) -{ - SDL_TrayEntry *entry = ptr; - - /* Not needed with AppIndicator, may be needed with other frameworks */ - /* if (entry->flags & SDL_TRAYENTRY_CHECKBOX) { - SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry)); - } */ - - if (entry->ignore_signal) { - return; - } - - if (entry->callback) { - entry->callback(entry->userdata, entry); - } -} - -static bool new_tmp_filename(SDL_Tray *tray) -{ - static int count = 0; - - int would_have_written = SDL_asprintf(&tray->icon_path, "%s/%d.png", tray->icon_dir, count++); - - if (would_have_written >= 0) { - return true; - } - - tray->icon_path = NULL; - SDL_SetError("Failed to format new temporary filename"); - return false; -} - -static const char *get_appindicator_id(void) -{ - static int count = 0; - static char buffer[256]; - - int would_have_written = SDL_snprintf(buffer, sizeof(buffer), "sdl-appindicator-%d-%d", getpid(), count++); - - if (would_have_written <= 0 || would_have_written >= sizeof(buffer) - 1) { - SDL_SetError("Couldn't fit %d bytes in buffer of size %d", would_have_written, (int) sizeof(buffer)); - return NULL; - } - - return buffer; -} - -static void DestroySDLMenu(SDL_TrayMenu *menu) -{ - for (int i = 0; i < menu->nEntries; i++) { - if (menu->entries[i] && menu->entries[i]->submenu) { - DestroySDLMenu(menu->entries[i]->submenu); - } - SDL_free(menu->entries[i]); - } - - if (menu->menu) { - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - gtk->g.object_unref(menu->menu); - SDL_Gtk_ExitContext(gtk); - } - } - - SDL_free(menu->entries); - SDL_free(menu); -} +static SDL_TrayDriver *driver = NULL; void SDL_UpdateTrays(void) { - if (SDL_HasActiveTrays()) { - SDL_UpdateGtk(); + SDL_Tray **trays; + int active_trays; + int count; + int i; + + active_trays = SDL_GetActiveTrayCount(); + if (!active_trays) { + return; } + + trays = SDL_calloc(active_trays, sizeof(SDL_Tray *)); + if (!trays) { + return; + } + + count = SDL_GetObjects(SDL_OBJECT_TYPE_TRAY, (void **)trays, active_trays); + SDL_assert(count == active_trays); + for (i = 0; i < count; i++) { + if (trays[i]) { + if (SDL_ObjectValid(trays[i], SDL_OBJECT_TYPE_TRAY)) { + trays[i]->driver->UpdateTray(trays[i]); + } + } + } + + SDL_free(trays); } SDL_Tray *SDL_CreateTrayWithProperties(SDL_PropertiesID props) { + SDL_Tray *tray; + if (!SDL_IsMainThread()) { SDL_SetError("This function should be called on the main thread"); return NULL; } - - if (!init_appindicator()) { - return NULL; + + if (!driver) { +#ifdef SDL_USE_LIBDBUS + driver = SDL_Tray_CreateDBusDriver(); +#endif } - SDL_Surface *icon = (SDL_Surface *)SDL_GetPointerProperty(props, SDL_PROP_TRAY_CREATE_ICON_POINTER, NULL); + if (driver) { + tray = driver->CreateTray(driver, props); - SDL_Tray *tray = NULL; - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (!gtk) { - goto tray_error; - } - - tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray)); - if (!tray) { - goto tray_error; - } - - const gchar *cache_dir = gtk->g.get_user_cache_dir(); - if (!cache_dir) { - SDL_SetError("Cannot get user cache directory: %s", strerror(errno)); - goto tray_error; - } - - char *sdl_dir; - SDL_asprintf(&sdl_dir, "%s/SDL", cache_dir); - if (!SDL_GetPathInfo(sdl_dir, NULL)) { - if (!SDL_CreateDirectory(sdl_dir)) { - SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno)); - goto sdl_dir_error; + if (tray) { + SDL_RegisterTray(tray); } - } - - /* On success, g_mkdtemp edits its argument in-place to replace the Xs - * with a random directory name, which it creates safely and atomically. - * On failure, it sets errno. */ - SDL_asprintf(&tray->icon_dir, "%s/tray-XXXXXX", sdl_dir); - if (!gtk->g.mkdtemp(tray->icon_dir)) { - SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno)); - goto icon_dir_error; - } - - if (icon) { - if (!new_tmp_filename(tray)) { - goto icon_dir_error; - } - - SDL_SavePNG(icon, tray->icon_path); } else { - // allocate a dummy icon path - SDL_asprintf(&tray->icon_path, " "); + tray = NULL; } - tray->indicator = app_indicator_new(get_appindicator_id(), tray->icon_path, - APP_INDICATOR_CATEGORY_APPLICATION_STATUS); - - app_indicator_set_status(tray->indicator, APP_INDICATOR_STATUS_ACTIVE); - - // The tray icon isn't shown before a menu is created; create one early. - tray->menu_cached = (GtkMenuShell *)gtk->g.object_ref_sink(gtk->gtk.menu_new()); - app_indicator_set_menu(tray->indicator, GTK_MENU(tray->menu_cached)); - - SDL_RegisterTray(tray); - SDL_Gtk_ExitContext(gtk); - SDL_free(sdl_dir); - return tray; - -icon_dir_error: - SDL_free(tray->icon_dir); - -sdl_dir_error: - SDL_free(sdl_dir); - -tray_error: - SDL_free(tray); - - if (gtk) { - SDL_Gtk_ExitContext(gtk); - } - - return NULL; } SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) { SDL_Tray *tray; - SDL_PropertiesID props = SDL_CreateProperties(); + SDL_PropertiesID props; + + props = SDL_CreateProperties(); + if (!props) { return NULL; } + if (icon) { SDL_SetPointerProperty(props, SDL_PROP_TRAY_CREATE_ICON_POINTER, icon); } + if (tooltip) { SDL_SetStringProperty(props, SDL_PROP_TRAY_CREATE_TOOLTIP_STRING, tooltip); } + tray = SDL_CreateTrayWithProperties(props); SDL_DestroyProperties(props); return tray; @@ -349,65 +110,41 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon) { - if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { + CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) + { + SDL_InvalidParamError("tray"); return; } - if (tray->icon_path) { - SDL_RemovePath(tray->icon_path); - SDL_free(tray->icon_path); - tray->icon_path = NULL; - } - - /* AppIndicator caches the icon files; always change filename to avoid caching */ - - if (icon && new_tmp_filename(tray)) { - SDL_SavePNG(icon, tray->icon_path); - app_indicator_set_icon(tray->indicator, tray->icon_path); - } else { - SDL_free(tray->icon_path); - tray->icon_path = NULL; - app_indicator_set_icon(tray->indicator, NULL); - } + tray->driver->SetTrayIcon(tray, icon); } void SDL_SetTrayTooltip(SDL_Tray *tray, const char *tooltip) { - /* AppIndicator provides no tooltip support. */ + CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) + { + SDL_InvalidParamError("tray"); + return; + } + + tray->driver->SetTrayTooltip(tray, tooltip); } SDL_TrayMenu *SDL_CreateTrayMenu(SDL_Tray *tray) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { + CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) + { SDL_InvalidParamError("tray"); return NULL; } - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (!gtk) { - return NULL; - } - - tray->menu = (SDL_TrayMenu *)SDL_calloc(1, sizeof(*tray->menu)); - if (!tray->menu) { - SDL_Gtk_ExitContext(gtk); - return NULL; - } - - tray->menu->menu = gtk->g.object_ref(tray->menu_cached); - tray->menu->parent_tray = tray; - tray->menu->parent_entry = NULL; - tray->menu->nEntries = 0; - tray->menu->entries = NULL; - - SDL_Gtk_ExitContext(gtk); - - return tray->menu; + return tray->driver->CreateTrayMenu(tray); } SDL_TrayMenu *SDL_GetTrayMenu(SDL_Tray *tray) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { + CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) + { SDL_InvalidParamError("tray"); return NULL; } @@ -417,314 +154,163 @@ SDL_TrayMenu *SDL_GetTrayMenu(SDL_Tray *tray) SDL_TrayMenu *SDL_CreateTraySubmenu(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) { + CHECK_PARAM(!entry) + { SDL_InvalidParamError("entry"); return NULL; } - if (entry->submenu) { - SDL_SetError("Tray entry submenu already exists"); - return NULL; - } - - if (!(entry->flags & SDL_TRAYENTRY_SUBMENU)) { - SDL_SetError("Cannot create submenu for entry not created with SDL_TRAYENTRY_SUBMENU"); - return NULL; - } - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (!gtk) { - return NULL; - } - - entry->submenu = (SDL_TrayMenu *)SDL_calloc(1, sizeof(*entry->submenu)); - if (!entry->submenu) { - SDL_Gtk_ExitContext(gtk); - return NULL; - } - - entry->submenu->menu = gtk->g.object_ref_sink(gtk->gtk.menu_new()); - entry->submenu->parent_tray = NULL; - entry->submenu->parent_entry = entry; - entry->submenu->nEntries = 0; - entry->submenu->entries = NULL; - - gtk->gtk.menu_item_set_submenu(GTK_MENU_ITEM(entry->item), GTK_WIDGET(entry->submenu->menu)); - - SDL_Gtk_ExitContext(gtk); - - return entry->submenu; + return entry->parent->parent_tray->driver->CreateTraySubmenu(entry); } SDL_TrayMenu *SDL_GetTraySubmenu(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) { + CHECK_PARAM(!entry) + { SDL_InvalidParamError("entry"); return NULL; } - return entry->submenu; + return entry->parent->parent_tray->driver->GetTraySubmenu(entry); } const SDL_TrayEntry **SDL_GetTrayEntries(SDL_TrayMenu *menu, int *count) { - CHECK_PARAM(!menu) { + CHECK_PARAM(!menu) + { SDL_InvalidParamError("menu"); return NULL; } - if (count) { - *count = menu->nEntries; + CHECK_PARAM(!count) + { + SDL_InvalidParamError("count"); + return NULL; } - return (const SDL_TrayEntry **)menu->entries; + + return (const SDL_TrayEntry **)menu->parent_tray->driver->GetTrayEntries(menu, count); } void SDL_RemoveTrayEntry(SDL_TrayEntry *entry) { - if (!entry) { + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); return; } - SDL_TrayMenu *menu = entry->parent; - - bool found = false; - for (int i = 0; i < menu->nEntries - 1; i++) { - if (menu->entries[i] == entry) { - found = true; - } - - if (found) { - menu->entries[i] = menu->entries[i + 1]; - } - } - - if (entry->submenu) { - DestroySDLMenu(entry->submenu); - } - - menu->nEntries--; - SDL_TrayEntry **new_entries = (SDL_TrayEntry **)SDL_realloc(menu->entries, (menu->nEntries + 1) * sizeof(*new_entries)); - - /* Not sure why shrinking would fail, but even if it does, we can live with a "too big" array */ - if (new_entries) { - menu->entries = new_entries; - menu->entries[menu->nEntries] = NULL; - } - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - gtk->gtk.widget_destroy(entry->item); - SDL_Gtk_ExitContext(gtk); - } - SDL_free(entry); + entry->parent->parent_tray->driver->RemoveTrayEntry(entry); } SDL_TrayEntry *SDL_InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, SDL_TrayEntryFlags flags) { - CHECK_PARAM(!menu) { + CHECK_PARAM(!menu) + { SDL_InvalidParamError("menu"); return NULL; } - CHECK_PARAM(pos < -1 || pos > menu->nEntries) { - SDL_InvalidParamError("pos"); - return NULL; - } - - if (pos == -1) { - pos = menu->nEntries; - } - - SDL_TrayEntry *entry = NULL; - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (!gtk) { - goto error; - } - - entry = (SDL_TrayEntry *)SDL_calloc(1, sizeof(*entry)); - if (!entry) { - goto error; - } - - entry->parent = menu; - entry->item = NULL; - entry->ignore_signal = false; - entry->flags = flags; - entry->callback = NULL; - entry->userdata = NULL; - entry->submenu = NULL; - - if (label == NULL) { - entry->item = gtk->gtk.separator_menu_item_new(); - } else if (flags & SDL_TRAYENTRY_CHECKBOX) { - entry->item = gtk->gtk.check_menu_item_new_with_label(label); - gboolean active = ((flags & SDL_TRAYENTRY_CHECKED) != 0); - gtk->gtk.check_menu_item_set_active(GTK_CHECK_MENU_ITEM(entry->item), active); - } else { - entry->item = gtk->gtk.menu_item_new_with_label(label); - } - - gboolean sensitive = ((flags & SDL_TRAYENTRY_DISABLED) == 0); - gtk->gtk.widget_set_sensitive(entry->item, sensitive); - - SDL_TrayEntry **new_entries = (SDL_TrayEntry **)SDL_realloc(menu->entries, (menu->nEntries + 2) * sizeof(*new_entries)); - - if (!new_entries) { - goto error; - } - - menu->entries = new_entries; - menu->nEntries++; - - for (int i = menu->nEntries - 1; i > pos; i--) { - menu->entries[i] = menu->entries[i - 1]; - } - - new_entries[pos] = entry; - new_entries[menu->nEntries] = NULL; - - gtk->gtk.widget_show(entry->item); - gtk->gtk.menu_shell_insert(menu->menu, entry->item, (pos == menu->nEntries) ? -1 : pos); - - gtk->g.signal_connect(entry->item, "activate", call_callback, entry); - - SDL_Gtk_ExitContext(gtk); - - return entry; - -error: - if (entry) { - SDL_free(entry); - } - - if (gtk) { - SDL_Gtk_ExitContext(gtk); - } - - return NULL; + return menu->parent_tray->driver->InsertTrayEntryAt(menu, pos, label, flags); } void SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) { - if (!entry) { + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); return; } - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - gtk->gtk.menu_item_set_label(GTK_MENU_ITEM(entry->item), label); - SDL_Gtk_ExitContext(gtk); - } + entry->parent->parent_tray->driver->SetTrayEntryLabel(entry, label); } const char *SDL_GetTrayEntryLabel(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) { + CHECK_PARAM(!entry) + { SDL_InvalidParamError("entry"); return NULL; } - const char *label = NULL; - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - label = gtk->gtk.menu_item_get_label(GTK_MENU_ITEM(entry->item)); - SDL_Gtk_ExitContext(gtk); - } - - return label; + return entry->parent->parent_tray->driver->GetTrayEntryLabel(entry); } void SDL_SetTrayEntryChecked(SDL_TrayEntry *entry, bool checked) { - if (!entry || !(entry->flags & SDL_TRAYENTRY_CHECKBOX)) { + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); return; } - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - entry->ignore_signal = true; - gtk->gtk.check_menu_item_set_active(GTK_CHECK_MENU_ITEM(entry->item), checked); - entry->ignore_signal = false; - SDL_Gtk_ExitContext(gtk); - } + entry->parent->parent_tray->driver->SetTrayEntryChecked(entry, checked); } bool SDL_GetTrayEntryChecked(SDL_TrayEntry *entry) { - if (!entry || !(entry->flags & SDL_TRAYENTRY_CHECKBOX)) { - return false; + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); + return NULL; } - bool checked = false; - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - checked = gtk->gtk.check_menu_item_get_active(GTK_CHECK_MENU_ITEM(entry->item)); - SDL_Gtk_ExitContext(gtk); - } - - return checked; + return entry->parent->parent_tray->driver->GetTrayEntryChecked(entry); } void SDL_SetTrayEntryEnabled(SDL_TrayEntry *entry, bool enabled) { - if (!entry) { + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); return; } - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - gtk->gtk.widget_set_sensitive(entry->item, enabled); - SDL_Gtk_ExitContext(gtk); - } + entry->parent->parent_tray->driver->SetTrayEntryEnabled(entry, enabled); } bool SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry) { - if (!entry) { - return false; + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); + return NULL; } - bool enabled = false; - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - enabled = gtk->gtk.widget_get_sensitive(entry->item); - SDL_Gtk_ExitContext(gtk); - } - - return enabled; + return entry->parent->parent_tray->driver->GetTrayEntryEnabled(entry); } void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata) { - if (!entry) { + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); return; } - entry->callback = callback; - entry->userdata = userdata; + CHECK_PARAM(!callback) + { + SDL_InvalidParamError("callback"); + return; + } + + entry->parent->parent_tray->driver->SetTrayEntryCallback(entry, callback, userdata); } void SDL_ClickTrayEntry(SDL_TrayEntry *entry) { - if (!entry) { - return; - } + CHECK_PARAM(!entry) + { + SDL_InvalidParamError("entry"); + return; + } - if (entry->flags & SDL_TRAYENTRY_CHECKBOX) { - SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry)); - } - - if (entry->callback) { - entry->callback(entry->userdata, entry); - } + entry->parent->parent_tray->driver->GetTrayEntryEnabled(entry); } SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) { + CHECK_PARAM(!entry) + { SDL_InvalidParamError("entry"); return NULL; } @@ -734,12 +320,19 @@ SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayEntry *SDL_GetTrayMenuParentEntry(SDL_TrayMenu *menu) { + CHECK_PARAM(!menu) + { + SDL_InvalidParamError("menu"); + return NULL; + } + return menu->parent_entry; } SDL_Tray *SDL_GetTrayMenuParentTray(SDL_TrayMenu *menu) { - CHECK_PARAM(!menu) { + CHECK_PARAM(!menu) + { SDL_InvalidParamError("menu"); return NULL; } @@ -754,33 +347,10 @@ void SDL_DestroyTray(SDL_Tray *tray) } SDL_UnregisterTray(tray); + tray->driver->DestroyTray(tray); - if (tray->menu) { - DestroySDLMenu(tray->menu); + if (!SDL_GetActiveTrayCount()) { + driver->DestroyDriver(driver); + driver = NULL; } - - if (tray->icon_path) { - SDL_RemovePath(tray->icon_path); - SDL_free(tray->icon_path); - } - - if (tray->icon_dir) { - SDL_RemovePath(tray->icon_dir); - SDL_free(tray->icon_dir); - } - - SDL_GtkContext *gtk = SDL_Gtk_EnterContext(); - if (gtk) { - if (tray->menu_cached) { - gtk->g.object_unref(tray->menu_cached); - } - - if (tray->indicator) { - gtk->g.object_unref(tray->indicator); - } - - SDL_Gtk_ExitContext(gtk); - } - - SDL_free(tray); } diff --git a/src/tray/unix/SDL_unixtray.h b/src/tray/unix/SDL_unixtray.h new file mode 100644 index 0000000000..1a31ffc1b5 --- /dev/null +++ b/src/tray/unix/SDL_unixtray.h @@ -0,0 +1,81 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifndef SDL_unixtray_h_ +#define SDL_unixtray_h_ + +#include "../../core/linux/SDL_dbus.h" +#include "../SDL_tray_utils.h" + +typedef struct SDL_TrayDriver +{ + const char *name; + + unsigned int count; + + SDL_Tray *(*CreateTray)(struct SDL_TrayDriver *, SDL_PropertiesID); + void (*DestroyTray)(SDL_Tray *); + void (*UpdateTray)(SDL_Tray *); + void (*SetTrayIcon)(SDL_Tray *, SDL_Surface *); + void (*SetTrayTooltip)(SDL_Tray *, const char *); + SDL_TrayMenu *(*CreateTrayMenu)(SDL_Tray *); + SDL_TrayEntry *(*InsertTrayEntryAt)(SDL_TrayMenu *, int, const char *, SDL_TrayEntryFlags); + SDL_TrayMenu *(*CreateTraySubmenu)(SDL_TrayEntry *); + SDL_TrayMenu *(*GetTraySubmenu)(SDL_TrayEntry *); + SDL_TrayEntry **(*GetTrayEntries)(SDL_TrayMenu *, int *); + void (*RemoveTrayEntry)(SDL_TrayEntry *); + void (*SetTrayEntryLabel)(SDL_TrayEntry *, const char *); + const char *(*GetTrayEntryLabel)(SDL_TrayEntry *); + void (*SetTrayEntryChecked)(SDL_TrayEntry *, bool); + void (*ClickTrayEntry)(SDL_TrayEntry *); + bool (*GetTrayEntryChecked)(SDL_TrayEntry *); + void (*SetTrayEntryEnabled)(SDL_TrayEntry *, bool); + bool (*GetTrayEntryEnabled)(SDL_TrayEntry *); + void (*SetTrayEntryCallback)(SDL_TrayEntry *, SDL_TrayCallback, void *); + + void (*DestroyDriver)(struct SDL_TrayDriver *); +} SDL_TrayDriver; + +struct SDL_TrayMenu +{ + SDL_Tray *parent_tray; + SDL_TrayEntry *parent_entry; +}; + +struct SDL_TrayEntry +{ + SDL_TrayMenu *parent; +}; + +struct SDL_Tray +{ + SDL_TrayDriver *driver; + + SDL_TrayMenu *menu; +}; + +#ifdef SDL_USE_LIBDBUS +extern SDL_TrayDriver *SDL_Tray_CreateDBusDriver(void); +#endif + +#endif // SDL_unixtray_h_ From ce90105cf8d1ee55c076033d5fd28c62cc312b06 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 10 Apr 2026 20:38:56 -0400 Subject: [PATCH 096/407] Clean up the tray D-Bus code Run clang-format to clean up whitespace issues, and remove some unused struct members. --- src/tray/unix/SDL_dbustray.c | 106 +++++++++++++++++------------------ src/tray/unix/SDL_tray.c | 70 ++++++++--------------- 2 files changed, 74 insertions(+), 102 deletions(-) diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index b84525a130..5089fd2326 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -22,6 +22,7 @@ /* Special thanks to the kind Hayden Gray (thag_iceman/A1029384756) from the SDL community for his help! */ #include "SDL_internal.h" + #include "../../core/linux/SDL_dbus.h" #ifdef SDL_USE_LIBDBUS @@ -33,15 +34,11 @@ typedef struct SDL_TrayDriverDBus { - SDL_TrayDriver _parent; - SDL_DBusContext *dbus; } SDL_TrayDriverDBus; typedef struct SDL_TrayDBus { - SDL_Tray _parent; - DBusConnection *connection; char *service_name; @@ -58,8 +55,6 @@ typedef struct SDL_TrayDBus typedef struct SDL_TrayMenuDBus { - SDL_TrayMenu _parent; - SDL_ListNode *menu; const char *menu_path; @@ -68,8 +63,6 @@ typedef struct SDL_TrayMenuDBus typedef struct SDL_TrayEntryDBus { - SDL_TrayEntry _parent; - SDL_MenuItem *item; SDL_TrayMenuDBus *sub_menu; } SDL_TrayEntryDBus; @@ -387,18 +380,18 @@ static DBusHandlerResult TrayMessageHandler(DBusConnection *connection, DBusMess driver->dbus->message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } else if (driver->dbus->message_is_method_call(msg, SNI_INTERFACE, "Scroll")) { - DBusError err; - char *orientation; - Sint32 delta; - - driver->dbus->error_init(&err); + DBusError err; + char *orientation; + Sint32 delta; + + driver->dbus->error_init(&err); driver->dbus->message_get_args(msg, &err, DBUS_TYPE_INT32, &delta, DBUS_TYPE_STRING, &orientation, DBUS_TYPE_INVALID); if (!driver->dbus->error_is_set(&err)) { - /* Scroll callback support will come later :) */ + /* Scroll callback support will come later :) */ } else { driver->dbus->error_free(&err); - } - + } + reply = driver->dbus->message_new_method_return(msg); driver->dbus->connection_send(tray_dbus->connection, reply, NULL); driver->dbus->message_unref(reply); @@ -450,7 +443,7 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) } tray_dbus->surface = SDL_ConvertSurface(icon, SDL_PIXELFORMAT_ARGB32); tray_dbus->block = false; - + /* Connect */ dbus_driver = (SDL_TrayDriverDBus *)driver; dbus_driver->dbus->error_init(&err); @@ -529,7 +522,7 @@ void DestroyMenu(SDL_TrayMenu *menu) if (!menu) { return; } - + menu_dbus = (SDL_TrayMenuDBus *)menu; if (menu_dbus->menu) { @@ -601,7 +594,7 @@ void UpdateTray(SDL_Tray *tray) if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { return; } - + if (tray_dbus->block) { return; } @@ -609,11 +602,11 @@ void UpdateTray(SDL_Tray *tray) driver->dbus->connection_read_write(tray_dbus->connection, 0); while (driver->dbus->connection_dispatch(tray_dbus->connection) == DBUS_DISPATCH_DATA_REMAINS) { if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { - break; + break; } - + if (tray_dbus->block) { - break; + break; } SDL_DelayNS(SDL_US_TO_NS(10)); @@ -727,7 +720,8 @@ bool TrayRightClickHandler(SDL_ListNode *menu, void *udata) return tray_dbus->r_cb(tray_dbus->udata, (SDL_Tray *)tray_dbus); } -void TraySendNewMenu(SDL_Tray *tray, const char *new_path) { +void TraySendNewMenu(SDL_Tray *tray, const char *new_path) +{ SDL_TrayDriverDBus *driver; SDL_TrayDBus *tray_dbus; SDL_TrayMenuDBus *menu_dbus; @@ -750,10 +744,10 @@ void TraySendNewMenu(SDL_Tray *tray, const char *new_path) { iface = SNI_INTERFACE; prop = "Menu"; if (new_path) { - path = menu_dbus->menu_path = new_path; - } else { - path = menu_dbus->menu_path; - } + path = menu_dbus->menu_path = new_path; + } else { + path = menu_dbus->menu_path; + } bool_val = TRUE; driver->dbus->message_iter_init_append(signal, &iter); driver->dbus->message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface); @@ -777,21 +771,21 @@ void TraySendNewMenu(SDL_Tray *tray, const char *new_path) { driver->dbus->connection_send(tray_dbus->connection, signal, NULL); driver->dbus->connection_flush(tray_dbus->connection); driver->dbus->message_unref(signal); - } + } - signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, SNI_INTERFACE, "NewMenu"); - if (signal) { + signal = driver->dbus->message_new_signal(SNI_OBJECT_PATH, SNI_INTERFACE, "NewMenu"); + if (signal) { driver->dbus->connection_send(tray_dbus->connection, signal, NULL); driver->dbus->connection_flush(tray_dbus->connection); driver->dbus->message_unref(signal); - } - + } + driver->dbus->connection_flush(tray_dbus->connection); } - -void TrayNewMenuOnMenuUpdateCallback(SDL_ListNode *menu, const char *path, void *cbdata) { - TraySendNewMenu((SDL_Tray *)cbdata, path); +void TrayNewMenuOnMenuUpdateCallback(SDL_ListNode *menu, const char *path, void *cbdata) +{ + TraySendNewMenu((SDL_Tray *)cbdata, path); } SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, SDL_TrayEntryFlags flags) @@ -861,7 +855,7 @@ SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, menu_dbus->menu_path = SDL_DBus_ExportMenu(driver->dbus, tray_dbus->connection, menu_dbus->menu); if (menu_dbus->menu_path) { - TraySendNewMenu(tray, NULL); + TraySendNewMenu(tray, NULL); } } @@ -918,7 +912,7 @@ void RemoveTrayEntry(SDL_TrayEntry *entry) SDL_TrayDBus *tray_dbus; SDL_TrayMenuDBus *main_menu_dbus; const char *old_path; - + tray = entry->parent->parent_tray; tray_dbus = (SDL_TrayDBus *)tray; driver = (SDL_TrayDriverDBus *)tray->driver; @@ -928,20 +922,20 @@ void RemoveTrayEntry(SDL_TrayEntry *entry) tray_dbus->block = true; if (menu_dbus->menu->entry == entry_dbus->item && menu_dbus->menu->next) { - SDL_DBus_TransferMenuItemProperties(entry_dbus->item, (SDL_MenuItem *)menu_dbus->menu->next->entry); - } - + SDL_DBus_TransferMenuItemProperties(entry_dbus->item, (SDL_MenuItem *)menu_dbus->menu->next->entry); + } + old_path = NULL; if (!main_menu_dbus->menu->next) { - old_path = main_menu_dbus->menu_path; - } - + old_path = main_menu_dbus->menu_path; + } + driver->dbus->connection_flush(tray_dbus->connection); DestroyMenu((SDL_TrayMenu *)entry_dbus->sub_menu); SDL_ListRemove(&menu_dbus->menu, entry_dbus->item); SDL_free(entry_dbus->item); SDL_free(entry); - + if (old_path) { SDL_DBus_RetractMenu(driver->dbus, tray_dbus->connection, &main_menu_dbus->menu_path); } @@ -965,7 +959,7 @@ void SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void SDL_TrayDriverDBus *driver; SDL_TrayDBus *tray_dbus; SDL_TrayMenuDBus *main_menu_dbus; - + tray = entry->parent->parent_tray; tray_dbus = (SDL_TrayDBus *)tray; driver = (SDL_TrayDriverDBus *)tray->driver; @@ -1066,18 +1060,18 @@ void ClickTrayEntry(SDL_TrayEntry *entry) dbus_entry = (SDL_TrayEntryDBus *)entry; if (dbus_entry->item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { - SDL_Tray *tray; - SDL_TrayDriverDBus *driver; - SDL_TrayDBus *tray_dbus; - SDL_TrayMenuDBus *main_menu_dbus; + SDL_Tray *tray; + SDL_TrayDriverDBus *driver; + SDL_TrayDBus *tray_dbus; + SDL_TrayMenuDBus *main_menu_dbus; - tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray = entry->parent->parent_tray; + tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; - dbus_entry->item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; - SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); + dbus_entry->item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); } entry_cb = dbus_entry->item->udata2; entry_cb(dbus_entry->item->cb_data, dbus_entry->item->udata); @@ -1174,4 +1168,4 @@ SDL_TrayDriver *SDL_Tray_CreateDBusDriver(void) return driver; } -#endif +#endif // SDL_USE_LIBDBUS diff --git a/src/tray/unix/SDL_tray.c b/src/tray/unix/SDL_tray.c index 607c24df46..9d91036c4b 100644 --- a/src/tray/unix/SDL_tray.c +++ b/src/tray/unix/SDL_tray.c @@ -59,12 +59,12 @@ void SDL_UpdateTrays(void) SDL_Tray *SDL_CreateTrayWithProperties(SDL_PropertiesID props) { SDL_Tray *tray; - + if (!SDL_IsMainThread()) { SDL_SetError("This function should be called on the main thread"); return NULL; } - + if (!driver) { #ifdef SDL_USE_LIBDBUS driver = SDL_Tray_CreateDBusDriver(); @@ -110,8 +110,7 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) - { + CHECK_PARAM (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { SDL_InvalidParamError("tray"); return; } @@ -121,8 +120,7 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon) void SDL_SetTrayTooltip(SDL_Tray *tray, const char *tooltip) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) - { + CHECK_PARAM (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { SDL_InvalidParamError("tray"); return; } @@ -132,8 +130,7 @@ void SDL_SetTrayTooltip(SDL_Tray *tray, const char *tooltip) SDL_TrayMenu *SDL_CreateTrayMenu(SDL_Tray *tray) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) - { + CHECK_PARAM (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { SDL_InvalidParamError("tray"); return NULL; } @@ -143,8 +140,7 @@ SDL_TrayMenu *SDL_CreateTrayMenu(SDL_Tray *tray) SDL_TrayMenu *SDL_GetTrayMenu(SDL_Tray *tray) { - CHECK_PARAM(!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) - { + CHECK_PARAM (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { SDL_InvalidParamError("tray"); return NULL; } @@ -154,8 +150,7 @@ SDL_TrayMenu *SDL_GetTrayMenu(SDL_Tray *tray) SDL_TrayMenu *SDL_CreateTraySubmenu(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -165,8 +160,7 @@ SDL_TrayMenu *SDL_CreateTraySubmenu(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTraySubmenu(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -176,14 +170,12 @@ SDL_TrayMenu *SDL_GetTraySubmenu(SDL_TrayEntry *entry) const SDL_TrayEntry **SDL_GetTrayEntries(SDL_TrayMenu *menu, int *count) { - CHECK_PARAM(!menu) - { + CHECK_PARAM (!menu) { SDL_InvalidParamError("menu"); return NULL; } - CHECK_PARAM(!count) - { + CHECK_PARAM (!count) { SDL_InvalidParamError("count"); return NULL; } @@ -193,8 +185,7 @@ const SDL_TrayEntry **SDL_GetTrayEntries(SDL_TrayMenu *menu, int *count) void SDL_RemoveTrayEntry(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } @@ -204,8 +195,7 @@ void SDL_RemoveTrayEntry(SDL_TrayEntry *entry) SDL_TrayEntry *SDL_InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, SDL_TrayEntryFlags flags) { - CHECK_PARAM(!menu) - { + CHECK_PARAM (!menu) { SDL_InvalidParamError("menu"); return NULL; } @@ -215,8 +205,7 @@ SDL_TrayEntry *SDL_InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *la void SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } @@ -226,8 +215,7 @@ void SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) const char *SDL_GetTrayEntryLabel(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -237,8 +225,7 @@ const char *SDL_GetTrayEntryLabel(SDL_TrayEntry *entry) void SDL_SetTrayEntryChecked(SDL_TrayEntry *entry, bool checked) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } @@ -248,8 +235,7 @@ void SDL_SetTrayEntryChecked(SDL_TrayEntry *entry, bool checked) bool SDL_GetTrayEntryChecked(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -259,8 +245,7 @@ bool SDL_GetTrayEntryChecked(SDL_TrayEntry *entry) void SDL_SetTrayEntryEnabled(SDL_TrayEntry *entry, bool enabled) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } @@ -270,8 +255,7 @@ void SDL_SetTrayEntryEnabled(SDL_TrayEntry *entry, bool enabled) bool SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -281,14 +265,12 @@ bool SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry) void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } - CHECK_PARAM(!callback) - { + CHECK_PARAM (!callback) { SDL_InvalidParamError("callback"); return; } @@ -298,8 +280,7 @@ void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, v void SDL_ClickTrayEntry(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return; } @@ -309,8 +290,7 @@ void SDL_ClickTrayEntry(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) { - CHECK_PARAM(!entry) - { + CHECK_PARAM (!entry) { SDL_InvalidParamError("entry"); return NULL; } @@ -320,8 +300,7 @@ SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayEntry *SDL_GetTrayMenuParentEntry(SDL_TrayMenu *menu) { - CHECK_PARAM(!menu) - { + CHECK_PARAM (!menu) { SDL_InvalidParamError("menu"); return NULL; } @@ -331,8 +310,7 @@ SDL_TrayEntry *SDL_GetTrayMenuParentEntry(SDL_TrayMenu *menu) SDL_Tray *SDL_GetTrayMenuParentTray(SDL_TrayMenu *menu) { - CHECK_PARAM(!menu) - { + CHECK_PARAM (!menu) { SDL_InvalidParamError("menu"); return NULL; } From db1506123e4c3b8614b3a1bf8cfbaa8cfbee0099 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 10 Apr 2026 20:47:17 -0400 Subject: [PATCH 097/407] Fix spacing in the D-Bus source --- src/core/linux/SDL_dbus.c | 135 +++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 0532fb87c9..1b3f56e73c 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -20,10 +20,11 @@ */ #include "SDL_internal.h" -#include "SDL_dbus.h" + #include "../../SDL_list.h" #include "../../SDL_menu.h" #include "../../stdlib/SDL_vacopy.h" +#include "SDL_dbus.h" #include #include @@ -53,6 +54,7 @@ static SDL_DBusContext dbus; #define DBUS_MENU_INTERFACE "com.canonical.dbusmenu" #define DBUS_MENU_OBJECT_PATH "/Menu" + #define SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE (1 << 0) static const char *menu_introspect = ""; @@ -60,8 +62,7 @@ SDL_ELF_NOTE_DLOPEN( "core-libdbus", "Support for D-Bus IPC", SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, - SDL_DRIVER_DBUS_DYNAMIC -) + SDL_DRIVER_DBUS_DYNAMIC) static bool LoadDBUSSyms(void) { @@ -1320,11 +1321,11 @@ static DBusHandlerResult MenuHandleEvent(SDL_DBusContext *ctx, SDL_ListNode *men ctx->connection_send(conn, reply, NULL); ctx->message_unref(reply); - if (item) { + if (item) { if (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { - item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; - SDL_DBus_UpdateMenu(ctx, conn, menu, NULL, NULL, NULL, SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE); - } + item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + SDL_DBus_UpdateMenu(ctx, conn, menu, NULL, NULL, NULL, SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE); + } if (item->cb) { item->cb(item, item->cb_data); @@ -1364,10 +1365,10 @@ static DBusHandlerResult MenuHandleEventGroup(SDL_DBusContext *ctx, SDL_ListNode if (item) { if (item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { - item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; + item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; SDL_DBus_UpdateMenu(ctx, conn, menu, NULL, NULL, NULL, SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE); } - + if (item->cb) { item->cb(item, item->cb_data); } @@ -1484,7 +1485,8 @@ static DBusHandlerResult MenuHandleGetProperty(SDL_DBusContext *ctx, SDL_ListNod static DBusHandlerResult MenuHandleGetGroupProperties(SDL_DBusContext *ctx, SDL_ListNode *menu, DBusConnection *conn, DBusMessage *msg) { - #define FILTER_PROPS_SZ 32 +#define FILTER_PROPS_SZ 32 + DBusMessage *reply; DBusMessageIter args, array_iter, prop_iter; DBusMessageIter iter, reply_array_iter; @@ -1701,7 +1703,7 @@ static DBusHandlerResult MenuMessageHandler(DBusConnection *conn, DBusMessage *m if (!menu->entry) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - + item = (SDL_DBusMenuItem *)menu->entry; ctx = item->dbus; @@ -1771,19 +1773,19 @@ static DBusHandlerResult MenuMessageHandler(DBusConnection *conn, DBusMessage *m ctx->message_iter_close_container(&iter, &variant_iter); } else if (!SDL_strcmp(property_name, "Status")) { str_val = "normal"; - + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); ctx->message_iter_close_container(&iter, &variant_iter); } else if (!SDL_strcmp(property_name, "TextDirection")) { str_val = "ltr"; - + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &variant_iter); ctx->message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &str_val); ctx->message_iter_close_container(&iter, &variant_iter); } else if (!SDL_strcmp(property_name, "IconThemePath")) { DBusMessageIter array_iter; - + ctx->message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "as", &variant_iter); ctx->message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "s", &array_iter); ctx->message_iter_close_container(&variant_iter, &array_iter); @@ -1905,14 +1907,14 @@ void SDL_DBus_UpdateMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNod DBusMessage *signal; dbus_uint32_t revision; dbus_int32_t next_id; - + if (!ctx) { return; } - + if (!menu) { - goto REPLACE_MENU; - } + goto REPLACE_MENU; + } next_id = MenuGetMaxItemId(menu) + 1; MenuAssignItemIds(menu, &next_id); @@ -1926,66 +1928,66 @@ void SDL_DBus_UpdateMenu(SDL_DBusContext *ctx, DBusConnection *conn, SDL_ListNod item->dbus = ctx; revision = item->revision; } - + if (flags & SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE) { - goto SEND_SIGNAL; - } - + goto SEND_SIGNAL; + } + REPLACE_MENU: if (path) { void *udata; ctx->connection_get_object_path_data(conn, path, &udata); - + if (udata != menu) { DBusObjectPathVTable vtable; - vtable.message_function = MenuMessageHandler; - vtable.unregister_function = NULL; - ctx->connection_unregister_object_path(conn, path); - ctx->connection_try_register_object_path(conn, path, &vtable, menu, NULL); - ctx->connection_flush(conn); + vtable.message_function = MenuMessageHandler; + vtable.unregister_function = NULL; + ctx->connection_unregister_object_path(conn, path); + ctx->connection_try_register_object_path(conn, path, &vtable, menu, NULL); + ctx->connection_flush(conn); - if (cb) { - cb(menu, NULL, cbdata); - } - } - } else { - DBusObjectPathVTable vtable; - SDL_DBusMenuItem *item; + if (cb) { + cb(menu, NULL, cbdata); + } + } + } else { + DBusObjectPathVTable vtable; + SDL_DBusMenuItem *item; - if (!menu) { - goto SEND_SIGNAL; - } - - next_id = MenuGetMaxItemId(menu) + 1; - MenuAssignItemIds(menu, &next_id); - revision = 0; - if (menu->entry) { - item = menu->entry; - item->dbus = ctx; - item->revision++; - revision = item->revision; - } - - vtable.message_function = MenuMessageHandler; - vtable.unregister_function = NULL; - ctx->connection_try_register_object_path(conn, DBUS_MENU_OBJECT_PATH, &vtable, menu, NULL); - ctx->connection_flush(conn); + if (!menu) { + goto SEND_SIGNAL; + } + + next_id = MenuGetMaxItemId(menu) + 1; + MenuAssignItemIds(menu, &next_id); + revision = 0; + if (menu->entry) { + item = menu->entry; + item->dbus = ctx; + item->revision++; + revision = item->revision; + } + + vtable.message_function = MenuMessageHandler; + vtable.unregister_function = NULL; + ctx->connection_try_register_object_path(conn, DBUS_MENU_OBJECT_PATH, &vtable, menu, NULL); + ctx->connection_flush(conn); if (cb) { - cb(menu, DBUS_MENU_OBJECT_PATH, cbdata); - } - ctx->connection_flush(conn); - } - + cb(menu, DBUS_MENU_OBJECT_PATH, cbdata); + } + ctx->connection_flush(conn); + } + SEND_SIGNAL: if (path) { - signal = ctx->message_new_signal(path, DBUS_MENU_INTERFACE, "LayoutUpdated"); - } else { - signal = ctx->message_new_signal(DBUS_MENU_OBJECT_PATH, DBUS_MENU_INTERFACE, "LayoutUpdated"); - } - + signal = ctx->message_new_signal(path, DBUS_MENU_INTERFACE, "LayoutUpdated"); + } else { + signal = ctx->message_new_signal(DBUS_MENU_OBJECT_PATH, DBUS_MENU_INTERFACE, "LayoutUpdated"); + } + if (signal) { dbus_int32_t parent; @@ -1993,7 +1995,7 @@ SEND_SIGNAL: ctx->message_append_args(signal, DBUS_TYPE_UINT32, &revision, DBUS_TYPE_INT32, &parent, DBUS_TYPE_INVALID); ctx->connection_send(conn, signal, NULL); ctx->message_unref(signal); - ctx->connection_flush(conn); + ctx->connection_flush(conn); } } @@ -2019,11 +2021,10 @@ void SDL_DBus_TransferMenuItemProperties(SDL_MenuItem *src, SDL_MenuItem *dst) dst_dbus->cbdata = src_dbus->cbdata; } -void SDL_DBus_RetractMenu(SDL_DBusContext *ctx, DBusConnection *conn, const char **path) +void SDL_DBus_RetractMenu(SDL_DBusContext *ctx, DBusConnection *conn, const char **path) { ctx->connection_unregister_object_path(conn, *path); *path = NULL; } -#endif - +#endif // SDL_USE_LIBDBUS From 9d97e663d902837b656693af9caec0f83857e989 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 19 Sep 2025 21:56:16 +0200 Subject: [PATCH 098/407] ci: add option to set ctest arguments --- .github/workflows/create-test-plan.py | 21 +++++++++++++++++---- .github/workflows/generic.yml | 2 +- docs/README-contributing.md | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index 4ce15489b7..69dca4e4c5 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -7,6 +7,7 @@ import json import logging import os import re +import shlex from typing import Optional logger = logging.getLogger(__name__) @@ -234,6 +235,7 @@ class JobDetails: pypi_packages: list[str] = dataclasses.field(default_factory=list) setup_gage_sdk_path: str = "" binutils_strings: str = "strings" + ctest_args: str = "" def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]: data = { @@ -303,6 +305,7 @@ class JobDetails: "pypi-packages": my_shlex_join(self.pypi_packages), "setup-ngage-sdk-path": self.setup_gage_sdk_path, "binutils-strings": self.binutils_strings, + "ctest-args": self.ctest_args, } return {k: v for k, v in data.items() if v != ""} @@ -318,7 +321,7 @@ def my_shlex_join(s): return " ".join(escape(s)) -def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDetails: +def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args: list[str]) -> JobDetails: job = JobDetails( name=spec.name, key=key, @@ -828,6 +831,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta "-DCMAKE_C_COMPILER_LAUNCHER=ccache", "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", )) + job.ctest_args = shlex.join(ctest_args) if not build_parallel: job.cmake_build_arguments.append("-j1") if job.cflags or job.cppflags: @@ -850,9 +854,14 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta return job -def spec_to_platform(spec: JobSpec, key: str, enable_artifacts: bool, trackmem_symbol_names: bool) -> dict[str, str|bool]: +def spec_to_platform(spec: JobSpec, key: str, enable_artifacts: bool, trackmem_symbol_names: bool, ctest_args:list[str]) -> dict[str, str|bool]: logger.info("spec=%r", spec) - job = spec_to_job(spec, key=key, trackmem_symbol_names=trackmem_symbol_names) + job = spec_to_job( + spec, + key=key, + trackmem_symbol_names=trackmem_symbol_names, + ctest_args=ctest_args, + ) logger.info("job=%r", job) platform = job.to_workflow(enable_artifacts=enable_artifacts) logger.info("platform=%r", platform) @@ -881,6 +890,7 @@ def main(): ) filters = [] + ctest_args = [] if args.commit_message_file: with open(args.commit_message_file, "r") as f: commit_message = f.read() @@ -893,6 +903,9 @@ def main(): if re.search(r"\[sdl-ci-(full-)?trackmem(-symbol-names)?]", commit_message, flags=re.M): args.trackmem_symbol_names = True + for m in re.finditer(r"\[sdl-ci-ctest-args? (.*)]", commit_message, flags=re.M): + ctest_args.extend(shlex.split(m.group(1))) + if not filters: filters.append("*") @@ -900,7 +913,7 @@ def main(): all_level_platforms = {} - all_platforms = {key: spec_to_platform(spec, key=key, enable_artifacts=args.enable_artifacts, trackmem_symbol_names=args.trackmem_symbol_names) for key, spec in JOB_SPECS.items()} + all_platforms = {key: spec_to_platform(spec, key=key, enable_artifacts=args.enable_artifacts, trackmem_symbol_names=args.trackmem_symbol_names, ctest_args=ctest_args) for key, spec in JOB_SPECS.items()} for level_i, level_keys in enumerate(all_level_keys, 1): level_key = f"level{level_i}" diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 183146679b..82fcbaf156 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -242,7 +242,7 @@ jobs: ${{ matrix.platform.pretest-cmd }} set -eu export SDL_TESTS_QUICK=1 - ctest -VV --test-dir build/ -j2 + ctest --test-dir build/ ${{ matrix.platform.ctest-args || '-VV -j2' }} - name: "Build test apk's (CMake)" id: apks if: ${{ always() && steps.build.outcome == 'success' && matrix.platform.android-apks != '' }} diff --git a/docs/README-contributing.md b/docs/README-contributing.md index 02a37bf756..b926e1d0de 100644 --- a/docs/README-contributing.md +++ b/docs/README-contributing.md @@ -95,6 +95,7 @@ Its behaviour can be influenced slightly by including SDL-specific tags in your - `[sdl-ci-filter GLOB]` limits the platforms for which to run ci. - `[sdl-ci-artifacts]` forces SDL artifacts, which can then be downloaded from the summary page. - `[sdl-ci-trackmem-symbol-names]` makes sure the final report generated by `--trackmem` contains symbol names. +- `[sdl-ci-ctest-args]` allows overriding the ctest arguments. Adding `--repeat-until-fail N` and `-R NAME` is useful. ## Contributing to the documentation From 396eeff350aa89210f6f678353d1cf34963216e8 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 10 Apr 2026 18:28:33 +0200 Subject: [PATCH 099/407] cmake: add SDLTEST_GDB option to run tests under gdb debugger printing stacktraces --- test/CMakeLists.txt | 6 ++++++ test/unix/gdbcmds.txt | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/unix/gdbcmds.txt diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a77c5aa685..81caee0d74 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,6 +54,12 @@ if(WIN32) else() set_property(TARGET sdlprocdump PROPERTY EXCLUDE_FROM_ALL "1") endif() +else() + option(SDLTEST_GDB "Run tests using headless gdb" OFF) + find_program(GDB_BIN NAMES "gdb") + if(SDLTEST_GDB AND GDB_BIN) + set(CMAKE_TEST_LAUNCHER "${GDB_BIN};-batch;-nx;-x;${CMAKE_CURRENT_SOURCE_DIR}/unix/gdbcmds.txt;--args") + endif() endif() if(EMSCRIPTEN) diff --git a/test/unix/gdbcmds.txt b/test/unix/gdbcmds.txt new file mode 100644 index 0000000000..c7a8ff9f08 --- /dev/null +++ b/test/unix/gdbcmds.txt @@ -0,0 +1,36 @@ +# Script to run a headless gdb printing a stacktrace on a fatal signal +# Use it as: `gdb -batch -nx -x gdbcmds.txt --args $PROGRAM_AND_ARGS` +# Configure CMake with -DSDLTEST_GDB=ON to use with within CTest. + +set pagination off +set confirm off +set verbose off + +# Only stop on real crash signals +handle SIGSEGV stop print nopass +handle SIGABRT stop print nopass +handle SIGILL stop print nopass +handle SIGFPE stop print nopass +handle SIGBUS stop print nopass + +# Ignore SIGPIPE and SIGTERM signals +# (SIGTERM is used by testthread) +handle SIGPIPE nostop noprint pass +handle SIGTERM nostop noprint pass + +define hook-stop + if !$_isvoid($_siginfo) + printf "\n=== Crash detected (signal %d) ===\n", $_siginfo.si_signo + bt full + quit 1 + end +end + +run + +# Normal exit path +if !$_isvoid($_exitcode) + quit $_exitcode +end + +quit 0 From 4ab8ecf02de36d0f59e6691ef16b06b99c0938a9 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 10 Apr 2026 18:35:01 +0200 Subject: [PATCH 100/407] ci: run tests on Linux under gdb (if available) --- .github/workflows/create-test-plan.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index 69dca4e4c5..f84ca1b153 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -490,6 +490,8 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args job.shared_lib = SharedLibType.SO_0 job.static_lib = StaticLibType.A fpic = True + job.cmake_arguments.append("-DSDLTEST_GDB=ON") + job.apt_packages.append("gdb") if spec.more_hard_deps: # Some distros prefer to make important dependencies # mandatory, so that SDL won't start up but lack expected From cf4edb73e7335a55a0fa52cca8414b2e2ef4be6c Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 11 Apr 2026 17:32:20 +0800 Subject: [PATCH 101/407] tray:dbus: Re-instate the _parent fields in SDL_dbustray structs The various SDL_Tray*DBus structs are supposed to be backend-specific subclasses of the corresponding SDL_Tray* structs. This is done by making the first member be a 'parent' of that type, so that, e.g., SDL_TrayDriverDBus can be cast into an SDL_TrayDriver. However, these '_parent' members were mistakenly removed in commit ce90105cf8d1 ("Clean up the tray D-Bus code"), as they're never directly referenced. Reinstate these variables, and instead of casting SDL_Tray*DBus to SDL_Tray* on creation, reference the _parent member directly, so that any tooling will know the variable is indeed used. In addition, rename _parent to class_parent, to make its purpose more obvious. Fixes: ce90105cf8d1 ("Clean up the tray D-Bus code") --- src/tray/unix/SDL_dbustray.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index 5089fd2326..f7e8cf54bd 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -34,11 +34,15 @@ typedef struct SDL_TrayDriverDBus { + SDL_TrayDriver class_parent; + SDL_DBusContext *dbus; } SDL_TrayDriverDBus; typedef struct SDL_TrayDBus { + SDL_Tray class_parent; + DBusConnection *connection; char *service_name; @@ -55,6 +59,8 @@ typedef struct SDL_TrayDBus typedef struct SDL_TrayMenuDBus { + SDL_TrayMenu class_parent; + SDL_ListNode *menu; const char *menu_path; @@ -63,6 +69,8 @@ typedef struct SDL_TrayMenuDBus typedef struct SDL_TrayEntryDBus { + SDL_TrayEntry class_parent; + SDL_MenuItem *item; SDL_TrayMenuDBus *sub_menu; } SDL_TrayEntryDBus; @@ -428,7 +436,7 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) /* Allocate the tray structure */ tray_dbus = SDL_malloc(sizeof(SDL_TrayDBus)); - tray = (SDL_Tray *)tray_dbus; + tray = &tray_dbus->class_parent; if (!tray_dbus) { return NULL; } @@ -663,7 +671,7 @@ SDL_TrayMenu *CreateTrayMenu(SDL_Tray *tray) SDL_TrayMenuDBus *menu_dbus; menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); - tray->menu = (SDL_TrayMenu *)menu_dbus; + tray->menu = &menu_dbus->class_parent; if (!menu_dbus) { SDL_SetError("Unable to create tray menu: allocation failure!"); return NULL; @@ -686,7 +694,7 @@ SDL_TrayMenu *CreateTraySubmenu(SDL_TrayEntry *entry) entry_dbus = (SDL_TrayEntryDBus *)entry; menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); - menu = (SDL_TrayMenu *)menu_dbus; + menu = &menu_dbus->class_parent; if (!menu_dbus) { SDL_SetError("Unable to create tray submenu: allocation failure!"); return NULL; @@ -804,7 +812,7 @@ SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, driver = (SDL_TrayDriverDBus *)tray->driver; entry_dbus = SDL_malloc(sizeof(SDL_TrayEntryDBus)); - entry = (SDL_TrayEntry *)entry_dbus; + entry = &entry_dbus->class_parent; if (!entry_dbus) { SDL_SetError("Unable to create tray entry: allocation failure!"); return NULL; @@ -1135,7 +1143,7 @@ SDL_TrayDriver *SDL_Tray_CreateDBusDriver(void) /* Allocate the driver struct */ dbus_driver = SDL_malloc(sizeof(SDL_TrayDriverDBus)); - driver = (SDL_TrayDriver *)dbus_driver; + driver = &dbus_driver->class_parent; if (!dbus_driver) { return NULL; } From f40955cd00b6b8fe93724dd4bff044ce80bf5a05 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sat, 11 Apr 2026 10:11:43 -0400 Subject: [PATCH 102/407] test: Render a blank window in testtray Some platforms require drawing something to the window for it to be mapped, so create a renderer and redraw on exposure events. Additionally, add the license to the testtray.c file and clang-format the source. --- test/testtray.c | 56 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/test/testtray.c b/test/testtray.c index d13793f89c..806aa3b455 100644 --- a/test/testtray.c +++ b/test/testtray.c @@ -1,3 +1,15 @@ +/* + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + #include "testutils.h" #include #include @@ -60,11 +72,12 @@ static bool SDLCALL tray2_middleclick(void *userdata, SDL_Tray *tray) static bool trays_destroyed = false; static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; static SDL_TrayEntry *entry_toggle = NULL; static void SDLCALL tray_close(void *ptr, SDL_TrayEntry *entry) { - SDL_Tray **trays = (SDL_Tray **) ptr; + SDL_Tray **trays = (SDL_Tray **)ptr; trays_destroyed = true; @@ -87,7 +100,7 @@ static void SDLCALL toggle_window(void *ptr, SDL_TrayEntry *entry) } } -static void SDLCALL apply_icon(void *ptr, const char * const *filelist, int filter) +static void SDLCALL apply_icon(void *ptr, const char *const *filelist, int filter) { if (!*filelist) { return; @@ -100,7 +113,7 @@ static void SDLCALL apply_icon(void *ptr, const char * const *filelist, int filt return; } - SDL_Tray *tray = (SDL_Tray *) ptr; + SDL_Tray *tray = (SDL_Tray *)ptr; SDL_SetTrayIcon(tray, icon); SDL_DestroySurface(icon); @@ -123,31 +136,31 @@ static void SDLCALL print_entry(void *ptr, SDL_TrayEntry *entry) static void SDLCALL set_entry_enabled(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayEntry *target = (SDL_TrayEntry *) ptr; + SDL_TrayEntry *target = (SDL_TrayEntry *)ptr; SDL_SetTrayEntryEnabled(target, true); } static void SDLCALL set_entry_disabled(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayEntry *target = (SDL_TrayEntry *) ptr; + SDL_TrayEntry *target = (SDL_TrayEntry *)ptr; SDL_SetTrayEntryEnabled(target, false); } static void SDLCALL set_entry_checked(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayEntry *target = (SDL_TrayEntry *) ptr; + SDL_TrayEntry *target = (SDL_TrayEntry *)ptr; SDL_SetTrayEntryChecked(target, true); } static void SDLCALL set_entry_unchecked(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayEntry *target = (SDL_TrayEntry *) ptr; + SDL_TrayEntry *target = (SDL_TrayEntry *)ptr; SDL_SetTrayEntryChecked(target, false); } static void SDLCALL remove_entry(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayEntry *target = (SDL_TrayEntry *) ptr; + SDL_TrayEntry *target = (SDL_TrayEntry *)ptr; SDL_RemoveTrayEntry(target); SDL_TrayMenu *ctrl_submenu = SDL_GetTrayEntryParent(entry); @@ -163,7 +176,7 @@ static void SDLCALL remove_entry(void *ptr, SDL_TrayEntry *entry) static void SDLCALL append_button_to(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayMenu *menu = (SDL_TrayMenu *) ptr; + SDL_TrayMenu *menu = (SDL_TrayMenu *)ptr; SDL_TrayMenu *submenu; SDL_TrayEntry *new_ctrl; SDL_TrayEntry *new_ctrl_remove; @@ -242,7 +255,7 @@ static void SDLCALL append_button_to(void *ptr, SDL_TrayEntry *entry) static void SDLCALL append_checkbox_to(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayMenu *menu = (SDL_TrayMenu *) ptr; + SDL_TrayMenu *menu = (SDL_TrayMenu *)ptr; SDL_TrayMenu *submenu; SDL_TrayEntry *new_ctrl; SDL_TrayEntry *new_ctrl_remove; @@ -349,7 +362,7 @@ static void SDLCALL append_checkbox_to(void *ptr, SDL_TrayEntry *entry) static void SDLCALL append_separator_to(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayMenu *menu = (SDL_TrayMenu *) ptr; + SDL_TrayMenu *menu = (SDL_TrayMenu *)ptr; SDL_TrayMenu *submenu; SDL_TrayEntry *new_ctrl; SDL_TrayEntry *new_ctrl_remove; @@ -398,7 +411,7 @@ static void SDLCALL append_separator_to(void *ptr, SDL_TrayEntry *entry) static void SDLCALL append_submenu_to(void *ptr, SDL_TrayEntry *entry) { - SDL_TrayMenu *menu = (SDL_TrayMenu *) ptr; + SDL_TrayMenu *menu = (SDL_TrayMenu *)ptr; SDL_TrayMenu *submenu; SDL_TrayMenu *entry_submenu; SDL_TrayEntry *new_ctrl; @@ -579,10 +592,8 @@ int main(int argc, char **argv) return 1; } - window = SDL_CreateWindow("testtray", 640, 480, 0); - - if (!window) { - SDL_Log("Couldn't create window: %s", SDL_GetError()); + if (!SDL_CreateWindowAndRenderer("testtray", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window and renderer: %s", SDL_GetError()); goto quit; } @@ -626,10 +637,10 @@ int main(int argc, char **argv) SDL_DestroySurface(icon); SDL_DestroySurface(icon2); -#define CHECK(name) \ - if (!name) { \ +#define CHECK(name) \ + if (!name) { \ SDL_Log("Couldn't create " #name ": %s", SDL_GetError()); \ - goto clean_all; \ + goto clean_all; \ } SDL_TrayMenu *menu = SDL_CreateTrayMenu(tray); @@ -703,6 +714,10 @@ int main(int argc, char **argv) break; } toggle_window(NULL, entry_toggle); + } else if (e.type == SDL_EVENT_WINDOW_EXPOSED) { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); } } @@ -718,6 +733,9 @@ clean_tray1: SDL_free(trays); clean_window: + if (renderer) { + SDL_DestroyRenderer(renderer); + } if (window) { SDL_DestroyWindow(window); } From 7f12b975bbad1b35f63c1b7090bf3e99575d95df Mon Sep 17 00:00:00 2001 From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> Date: Sat, 11 Apr 2026 20:37:33 +0300 Subject: [PATCH 103/407] Use `singleTop` launchMode for `SDLActivity` on `Android` --- android-project/app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml index ab43f76aef..1111a223dc 100644 --- a/android-project/app/src/main/AndroidManifest.xml +++ b/android-project/app/src/main/AndroidManifest.xml @@ -81,7 +81,7 @@ Date: Sun, 12 Apr 2026 12:55:32 -0400 Subject: [PATCH 104/407] wayland: Enable text input even when the text input protocol is not available. Even without the text input protocol, basic text can still be obtained from individual keys and the composition system. --- src/video/wayland/SDL_waylandkeyboard.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandkeyboard.c b/src/video/wayland/SDL_waylandkeyboard.c index 4478b2b9e3..f604a7e3df 100644 --- a/src/video/wayland/SDL_waylandkeyboard.c +++ b/src/video/wayland/SDL_waylandkeyboard.c @@ -183,11 +183,12 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop Wayland_SeatUpdateTextInput(seat); } } - - return true; } - return SDL_SetError("wayland: cannot enable text input; compositor lacks support for the required zwp_text_input_v3 protocol"); + /* Always return true, even if the text input protocol isn't supported, as basic + * text can still be obtained from individual keys and composition system. + */ + return true; } bool Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) From e4f75bac451230d31695158ed35f459e7a04585c Mon Sep 17 00:00:00 2001 From: eafton Date: Sun, 12 Apr 2026 11:52:10 +0300 Subject: [PATCH 105/407] Remove SDL_gtk --- src/SDL.c | 8 - src/core/unix/SDL_gtk.c | 300 --------------------------- src/core/unix/SDL_gtk.h | 126 ----------- src/video/wayland/SDL_waylandvideo.c | 66 +++++- src/video/x11/SDL_x11modes.c | 2 - 5 files changed, 64 insertions(+), 438 deletions(-) delete mode 100644 src/core/unix/SDL_gtk.c delete mode 100644 src/core/unix/SDL_gtk.h diff --git a/src/SDL.c b/src/SDL.c index cd7ec4b656..2d62cf42c6 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -30,10 +30,6 @@ // this checks for HAVE_DBUS_DBUS_H internally. #include "core/linux/SDL_dbus.h" -#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) -#include "core/unix/SDL_gtk.h" -#endif - #ifdef SDL_PLATFORM_EMSCRIPTEN #include #endif @@ -714,10 +710,6 @@ void SDL_Quit(void) SDL_DBus_Quit(); #endif -#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE) - SDL_Gtk_Quit(); -#endif - SDL_QuitTimers(); SDL_QuitAsyncIO(); diff --git a/src/core/unix/SDL_gtk.c b/src/core/unix/SDL_gtk.c deleted file mode 100644 index 92e8a16ff9..0000000000 --- a/src/core/unix/SDL_gtk.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "SDL_internal.h" -#include "SDL_gtk.h" - -#include -#include -#include - -#define SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym) \ - ctx.sub.fn = (void *)SDL_LoadFunction(lib, #sym) - -#define SDL_GTK_SYM2(ctx, lib, sub, fn, sym) \ - SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym); \ - if (!ctx.sub.fn) { \ - return SDL_SetError("Could not load GTK functions"); \ - } - -#define SDL_GTK_SYM_OPTIONAL(ctx, lib, sub, fn) \ - SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sub##_##fn) - -#define SDL_GTK_SYM(ctx, lib, sub, fn) \ - SDL_GTK_SYM2(ctx, lib, sub, fn, sub##_##fn) - -#ifdef SDL_PLATFORM_OPENBSD -#define GDK3_LIB "libgdk-3.so" -#else -#define GDK3_LIB "libgdk-3.so.0" -#endif - -#ifdef SDL_PLATFORM_OPENBSD -#define GTK3_LIB "libgtk-3.so" -#else -#define GTK3_LIB "libgtk-3.so.0" -#endif - -// we never link directly to gtk -static void *libgdk = NULL; -static void *libgtk = NULL; - -static SDL_GtkContext gtk; -static GMainContext *sdl_main_context; - -static gulong signal_connect(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data) -{ - return gtk.g.signal_connect_data(instance, detailed_signal, SDL_G_CALLBACK(c_handler), data, NULL, (SDL_GConnectFlags)0); -} - -static void QuitGtk(void) -{ - if (sdl_main_context) { - gtk.g.main_context_unref(sdl_main_context); - sdl_main_context = NULL; - } - - SDL_UnloadObject(libgdk); - SDL_UnloadObject(libgtk); - - libgdk = NULL; - libgtk = NULL; -} - -static bool IsGtkInit(void) -{ - return libgdk != NULL && libgtk != NULL; -} - -#ifndef HAVE_GETRESUID -// Non-POSIX, but Linux and some BSDs have it. -// To reduce the number of code paths, if getresuid() isn't available at -// compile-time, we behave as though it existed but failed at runtime. -static inline int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { - errno = ENOSYS; - return -1; -} -#endif - -#ifndef HAVE_GETRESGID -// Same as getresuid() but for the primary group -static inline int getresgid(uid_t *ruid, uid_t *euid, uid_t *suid) { - errno = ENOSYS; - return -1; -} -#endif - -bool SDL_CanUseGtk(void) -{ - // "Real", "effective" and "saved" IDs: see e.g. Linux credentials(7) - uid_t ruid = -1, euid = -1, suid = -1; - gid_t rgid = -1, egid = -1, sgid = -1; - - if (!SDL_GetHintBoolean("SDL_ENABLE_GTK", true)) { - SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to hint"); - return false; - } - - // This is intended to match the check in gtkmain.c, rather than being - // an exhaustive check for having elevated privileges: as a result - // we don't use Linux getauxval() or prctl PR_GET_DUMPABLE, - // BSD issetugid(), or similar OS-specific detection - - if (getresuid(&ruid, &euid, &suid) != 0) { - ruid = suid = getuid(); - euid = geteuid(); - } - - if (getresgid(&rgid, &egid, &sgid) != 0) { - rgid = sgid = getgid(); - egid = getegid(); - } - - // Real ID != effective ID means we are setuid or setgid: - // GTK will refuse to initialize, and instead will call exit(). - if (ruid != euid || rgid != egid) { - SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to setuid/setgid"); - return false; - } - - // Real ID != saved ID means we are setuid or setgid, we previously - // dropped privileges, but we can regain them; this protects against - // accidents but does not protect against arbitrary code execution. - // Again, GTK will refuse to initialize if this is the case. - if (ruid != suid || rgid != sgid) { - SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to saved uid/gid"); - return false; - } - - return true; -} - -static bool InitGtk(void) -{ - if (!SDL_CanUseGtk()) { - return false; - } - - if (IsGtkInit()) { - return true; - } - - // GTK only allows a single version to be loaded into a process at a time, - // so if there is one already loaded ensure it is the version we use. - void *progress_get_type = dlsym(RTLD_DEFAULT, "gtk_progress_get_type"); - void *misc_get_type = dlsym(RTLD_DEFAULT, "gtk_misc_get_type"); - if (progress_get_type || misc_get_type) { - void *libgtk3 = dlopen(GTK3_LIB, RTLD_NOLOAD | RTLD_LAZY); - if (!libgtk3) { - QuitGtk(); - return SDL_SetError("Could not load GTK-3, another GTK version already present"); - } - - dlclose(libgtk3); - } - - libgdk = SDL_LoadObject(GDK3_LIB); - libgtk = SDL_LoadObject(GTK3_LIB); - - if (!libgdk || !libgtk) { - QuitGtk(); - return SDL_SetError("Could not load GTK libraries"); - } - - SDL_GTK_SYM(gtk, libgtk, gtk, init_check); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_new); - SDL_GTK_SYM(gtk, libgtk, gtk, separator_menu_item_new); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_new_with_label); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_submenu); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_get_label); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_label); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append); - SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_insert); - SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_new_with_label); - SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_get_active); - SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_set_active); - SDL_GTK_SYM(gtk, libgtk, gtk, widget_show); - SDL_GTK_SYM(gtk, libgtk, gtk, widget_destroy); - SDL_GTK_SYM(gtk, libgtk, gtk, widget_get_sensitive); - SDL_GTK_SYM(gtk, libgtk, gtk, widget_set_sensitive); - SDL_GTK_SYM(gtk, libgtk, gtk, settings_get_default); - - SDL_GTK_SYM(gtk, libgdk, g, signal_connect_data); - SDL_GTK_SYM(gtk, libgdk, g, mkdtemp); - SDL_GTK_SYM(gtk, libgdk, g, get_user_cache_dir); - SDL_GTK_SYM(gtk, libgdk, g, object_ref); - SDL_GTK_SYM(gtk, libgdk, g, object_ref_sink); - SDL_GTK_SYM(gtk, libgdk, g, object_unref); - SDL_GTK_SYM(gtk, libgdk, g, object_get); - SDL_GTK_SYM(gtk, libgdk, g, signal_handler_disconnect); - SDL_GTK_SYM(gtk, libgdk, g, main_context_push_thread_default); - SDL_GTK_SYM(gtk, libgdk, g, main_context_pop_thread_default); - SDL_GTK_SYM(gtk, libgdk, g, main_context_new); - SDL_GTK_SYM(gtk, libgdk, g, main_context_unref); - SDL_GTK_SYM(gtk, libgdk, g, main_context_acquire); - SDL_GTK_SYM(gtk, libgdk, g, main_context_iteration); - - gtk.g.signal_connect = signal_connect; - - if (gtk.gtk.init_check(NULL, NULL) == GTK_FALSE) { - QuitGtk(); - return SDL_SetError("Could not init GTK"); - } - - sdl_main_context = gtk.g.main_context_new(); - if (!sdl_main_context) { - QuitGtk(); - return SDL_SetError("Could not create GTK context"); - } - - if (!gtk.g.main_context_acquire(sdl_main_context)) { - QuitGtk(); - return SDL_SetError("Could not acquire GTK context"); - } - - return true; -} - -static SDL_InitState gtk_init; - -bool SDL_Gtk_Init(void) -{ - static bool is_gtk_available = true; - - if (!is_gtk_available) { - return false; // don't keep trying if this fails. - } - - if (SDL_ShouldInit(>k_init)) { - if (InitGtk()) { - SDL_SetInitialized(>k_init, true); - } else { - is_gtk_available = false; - SDL_SetInitialized(>k_init, true); - SDL_Gtk_Quit(); - } - } - - return IsGtkInit(); -} - -void SDL_Gtk_Quit(void) -{ - if (!SDL_ShouldQuit(>k_init)) { - return; - } - - QuitGtk(); - SDL_zero(gtk); - - SDL_SetInitialized(>k_init, false); -} - -SDL_GtkContext *SDL_Gtk_GetContext(void) -{ - return IsGtkInit() ? >k : NULL; -} - -SDL_GtkContext *SDL_Gtk_EnterContext(void) -{ - SDL_Gtk_Init(); - - if (IsGtkInit()) { - gtk.g.main_context_push_thread_default(sdl_main_context); - return >k; - } - - return NULL; -} - -void SDL_Gtk_ExitContext(SDL_GtkContext *ctx) -{ - if (ctx) { - ctx->g.main_context_pop_thread_default(sdl_main_context); - } -} - -void SDL_UpdateGtk(void) -{ - if (IsGtkInit()) { - gtk.g.main_context_iteration(sdl_main_context, GTK_FALSE); - gtk.g.main_context_iteration(NULL, GTK_FALSE); - } -} diff --git a/src/core/unix/SDL_gtk.h b/src/core/unix/SDL_gtk.h deleted file mode 100644 index 663b28516d..0000000000 --- a/src/core/unix/SDL_gtk.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "SDL_internal.h" - -#ifndef SDL_gtk_h_ -#define SDL_gtk_h_ - -/* Glib 2.0 */ - -typedef unsigned long gulong; -typedef void *gpointer; -typedef char gchar; -typedef int gint; -typedef unsigned int guint; -typedef double gdouble; -typedef gint gboolean; -typedef void (*GCallback)(void); -typedef struct _GClosure GClosure; -typedef void (*GClosureNotify) (gpointer data, GClosure *closure); -typedef gboolean (*GSourceFunc) (gpointer user_data); - -typedef struct _GParamSpec GParamSpec; -typedef struct _GMainContext GMainContext; - -typedef enum SDL_GConnectFlags -{ - SDL_G_CONNECT_DEFAULT = 0, - SDL_G_CONNECT_AFTER = 1 << 0, - SDL_G_CONNECT_SWAPPED = 1 << 1 -} SDL_GConnectFlags; - -#define SDL_G_CALLBACK(f) ((GCallback) (f)) -#define SDL_G_TYPE_CIC(ip, gt, ct) ((ct*) ip) -#define SDL_G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (SDL_G_TYPE_CIC ((instance), (g_type), c_type)) - -#define GTK_FALSE 0 -#define GTK_TRUE 1 - - -/* GTK 3.0 */ - -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkMenuShell GtkMenuShell; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkCheckMenuItem GtkCheckMenuItem; -typedef struct _GtkSettings GtkSettings; - -#define GTK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem)) -#define GTK_WIDGET(widget) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((widget), GTK_TYPE_WIDGET, GtkWidget)) -#define GTK_CHECK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItem)) -#define GTK_MENU(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU, GtkMenu)) - - -typedef struct SDL_GtkContext -{ - /* Glib 2.0 */ - struct - { - gulong (*signal_connect)(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data); - gulong (*signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, SDL_GConnectFlags connect_flags); - void (*object_unref)(gpointer object); - gchar *(*mkdtemp)(gchar *template); - gchar *(*get_user_cache_dir)(void); - gpointer (*object_ref_sink)(gpointer object); - gpointer (*object_ref)(gpointer object); - void (*object_get)(gpointer object, const gchar *first_property_name, ...); - void (*signal_handler_disconnect)(gpointer instance, gulong handler_id); - void (*main_context_push_thread_default)(GMainContext *context); - void (*main_context_pop_thread_default)(GMainContext *context); - GMainContext *(*main_context_new)(void); - void (*main_context_unref)(GMainContext *context); - gboolean (*main_context_acquire)(GMainContext *context); - gboolean (*main_context_iteration)(GMainContext *context, gboolean may_block); - } g; - - /* GTK 3.0 */ - struct - { - gboolean (*init_check)(int *argc, char ***argv); - GtkWidget *(*menu_new)(void); - GtkWidget *(*separator_menu_item_new)(void); - GtkWidget *(*menu_item_new_with_label)(const gchar *label); - void (*menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu); - GtkWidget *(*check_menu_item_new_with_label)(const gchar *label); - void (*check_menu_item_set_active)(GtkCheckMenuItem *check_menu_item, gboolean is_active); - void (*widget_set_sensitive)(GtkWidget *widget, gboolean sensitive); - void (*widget_show)(GtkWidget *widget); - void (*menu_shell_append)(GtkMenuShell *menu_shell, GtkWidget *child); - void (*menu_shell_insert)(GtkMenuShell *menu_shell, GtkWidget *child, gint position); - void (*widget_destroy)(GtkWidget *widget); - const gchar *(*menu_item_get_label)(GtkMenuItem *menu_item); - void (*menu_item_set_label)(GtkMenuItem *menu_item, const gchar *label); - gboolean (*check_menu_item_get_active)(GtkCheckMenuItem *check_menu_item); - gboolean (*widget_get_sensitive)(GtkWidget *widget); - GtkSettings *(*settings_get_default)(void); - } gtk; -} SDL_GtkContext; - -extern bool SDL_CanUseGtk(void); -extern bool SDL_Gtk_Init(void); -extern void SDL_Gtk_Quit(void); -extern SDL_GtkContext *SDL_Gtk_EnterContext(void); -extern void SDL_Gtk_ExitContext(SDL_GtkContext *ctx); -extern void SDL_UpdateGtk(void); - -#endif // SDL_gtk_h_ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 9474cacc61..3e0ca45679 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -25,7 +25,6 @@ #include "../../core/linux/SDL_system_theme.h" #include "../../core/linux/SDL_progressbar.h" -#include "../../core/unix/SDL_gtk.h" #include "../../events/SDL_events_c.h" #include "SDL_waylandclipboard.h" @@ -1503,6 +1502,69 @@ static int SDLCALL LibdecorNewInThread(void *data) } #endif +#ifndef HAVE_GETRESUID +// Non-POSIX, but Linux and some BSDs have it. +// To reduce the number of code paths, if getresuid() isn't available at +// compile-time, we behave as though it existed but failed at runtime. +static inline int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_GETRESGID +// Same as getresuid() but for the primary group +static inline int getresgid(uid_t *ruid, uid_t *euid, uid_t *suid) { + errno = ENOSYS; + return -1; +} +#endif + +bool CanUseGtk(void) +{ + // "Real", "effective" and "saved" IDs: see e.g. Linux credentials(7) + uid_t ruid = -1, euid = -1, suid = -1; + gid_t rgid = -1, egid = -1, sgid = -1; + + if (!SDL_GetHintBoolean("SDL_ENABLE_GTK", true)) { + SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to hint"); + return false; + } + + // This is intended to match the check in gtkmain.c, rather than being + // an exhaustive check for having elevated privileges: as a result + // we don't use Linux getauxval() or prctl PR_GET_DUMPABLE, + // BSD issetugid(), or similar OS-specific detection + + if (getresuid(&ruid, &euid, &suid) != 0) { + ruid = suid = getuid(); + euid = geteuid(); + } + + if (getresgid(&rgid, &egid, &sgid) != 0) { + rgid = sgid = getgid(); + egid = getegid(); + } + + // Real ID != effective ID means we are setuid or setgid: + // GTK will refuse to initialize, and instead will call exit(). + if (ruid != euid || rgid != egid) { + SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to setuid/setgid"); + return false; + } + + // Real ID != saved ID means we are setuid or setgid, we previously + // dropped privileges, but we can regain them; this protects against + // accidents but does not protect against arbitrary code execution. + // Again, GTK will refuse to initialize if this is the case. + if (ruid != suid || rgid != sgid) { + SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to saved uid/gid"); + return false; + } + + return true; +} + bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg) { #ifdef HAVE_LIBDECOR_H @@ -1510,7 +1572,7 @@ bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg) return true; // Already loaded! } if (should_use_libdecor(data, ignore_xdg)) { - if (SDL_CanUseGtk()) { + if (CanUseGtk()) { LibdecorNew(data); } else { // Intentionally initialize libdecor in a non-main thread diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index 2b7ab0ffef..1fbbc86876 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -27,8 +27,6 @@ #include "edid.h" #include "../../events/SDL_displayevents_c.h" -#include "../../core/unix/SDL_gtk.h" - // #define X11MODES_DEBUG /* Timeout and revert mode switches if the timespan has elapsed without the window becoming fullscreen. From 5e0f721fd4dd98268cdcfcffbc99cce75fae3907 Mon Sep 17 00:00:00 2001 From: David Vanderson Date: Mon, 13 Apr 2026 14:24:27 -0400 Subject: [PATCH 106/407] xinput2: correct horizontal touchpad scrolling direction This fixes testmouse so when fingers move left the green line moves left. --- src/video/x11/SDL_x11xinput2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 4ebba6e0f3..d6c704e3f6 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -180,7 +180,7 @@ static void xinput2_parse_scrollable_valuators(const XIDeviceEvent *xev) const double y = info->scroll_type == XIScrollTypeVertical ? delta : 0; SDL_Mouse *mouse = SDL_GetMouse(); - SDL_SendMouseWheel(xev->time, mouse->focus, (SDL_MouseID)xev->sourceid, (float)x, (float)y, SDL_MOUSEWHEEL_NORMAL); + SDL_SendMouseWheel(xev->time, mouse->focus, (SDL_MouseID)xev->sourceid, (float)-x, (float)y, SDL_MOUSEWHEEL_NORMAL); } info->prev_value = current_val; info->prev_value_valid = true; From 745f9905c1356333ef9d3295296c8a919a74358b Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 13 Apr 2026 23:52:34 +0200 Subject: [PATCH 107/407] test: render name of current active cursor --- test/testcustomcursor.c | 159 ++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/test/testcustomcursor.c b/test/testcustomcursor.c index dabe57a8d1..bf4e136e1d 100644 --- a/test/testcustomcursor.c +++ b/test/testcustomcursor.c @@ -19,6 +19,15 @@ #include +enum +{ + CUSTOM_CURSOR_ARGUMENTS = -1, + CUSTOM_CURSOR_ARROW = -2, + CUSTOM_CURSOR_CROSS = -3, + CUSTOM_ANIMATED_CURSOR = -4, + CUSTOM_ANIMATED_CURSOR_ONE_SHOT = -5, +}; + /* Stolen from the mailing list */ /* Creates a new mouse cursor from an XPM */ @@ -318,6 +327,7 @@ static SDL_Cursor *cursors[5 + SDL_SYSTEM_CURSOR_COUNT]; static SDL_SystemCursor cursor_types[5 + SDL_SYSTEM_CURSOR_COUNT]; static int num_cursors; static int current_cursor; +static bool current_cursor_valid; static bool show_cursor; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ @@ -331,6 +341,67 @@ quit(int rc) } } +static const char *get_active_cursor_name() +{ + // if (!current_cursor_valid) { + // return ""; + // } + switch ((int)cursor_types[current_cursor]) { + case CUSTOM_CURSOR_ARGUMENTS: + return "Custom cursor (arguments)"; + case CUSTOM_CURSOR_ARROW: + return "Custom cursor (arrow)"; + case CUSTOM_CURSOR_CROSS: + return "Custom cursor (cross)"; + case CUSTOM_ANIMATED_CURSOR_ONE_SHOT: + return "Animated custom cursor (one-shot)"; + case CUSTOM_ANIMATED_CURSOR: + return "Animated custom cursor"; + case SDL_SYSTEM_CURSOR_DEFAULT: + return "Default"; + case SDL_SYSTEM_CURSOR_TEXT: + return "Text"; + case SDL_SYSTEM_CURSOR_WAIT: + return "Wait"; + case SDL_SYSTEM_CURSOR_CROSSHAIR: + return "Crosshair"; + case SDL_SYSTEM_CURSOR_PROGRESS: + return "Progress: Small wait cursor (or Wait if not available)"; + case SDL_SYSTEM_CURSOR_NWSE_RESIZE: + return "Double arrow pointing northwest and southeast"; + case SDL_SYSTEM_CURSOR_NESW_RESIZE: + return "Double arrow pointing northeast and southwest"; + case SDL_SYSTEM_CURSOR_EW_RESIZE: + return "Double arrow pointing west and east"; + case SDL_SYSTEM_CURSOR_NS_RESIZE: + return "Double arrow pointing north and south"; + case SDL_SYSTEM_CURSOR_MOVE: + return "Move: Four pointed arrow pointing north, south, east, and west"; + case SDL_SYSTEM_CURSOR_NOT_ALLOWED: + return "Not Allowed: Slashed circle or crossbones"; + case SDL_SYSTEM_CURSOR_POINTER: + return "Pointer: Hand"; + case SDL_SYSTEM_CURSOR_NW_RESIZE: + return "Window resize top-left"; + case SDL_SYSTEM_CURSOR_N_RESIZE: + return "Window resize top"; + case SDL_SYSTEM_CURSOR_NE_RESIZE: + return "Window resize top-right"; + case SDL_SYSTEM_CURSOR_E_RESIZE: + return "Window resize right"; + case SDL_SYSTEM_CURSOR_SE_RESIZE: + return "Window resize bottom-right"; + case SDL_SYSTEM_CURSOR_S_RESIZE: + return "Window resize bottom"; + case SDL_SYSTEM_CURSOR_SW_RESIZE: + return "Window resize bottom-left"; + case SDL_SYSTEM_CURSOR_W_RESIZE: + return "Window resize left"; + default: + return "UNKNOWN CURSOR TYPE, FIX THIS PROGRAM."; + } +} + static void loop(void) { int i; @@ -344,6 +415,7 @@ static void loop(void) continue; } + current_cursor_valid = true; ++current_cursor; if (current_cursor == num_cursors) { current_cursor = 0; @@ -351,80 +423,7 @@ static void loop(void) SDL_SetCursor(cursors[current_cursor]); - switch ((int)cursor_types[current_cursor]) { - case (SDL_SystemCursor)-3: - SDL_Log("Animated custom cursor (one-shot)"); - break; - case (SDL_SystemCursor)-2: - SDL_Log("Animated custom cursor"); - break; - case (SDL_SystemCursor)-1: - SDL_Log("Custom cursor"); - break; - case SDL_SYSTEM_CURSOR_DEFAULT: - SDL_Log("Default"); - break; - case SDL_SYSTEM_CURSOR_TEXT: - SDL_Log("Text"); - break; - case SDL_SYSTEM_CURSOR_WAIT: - SDL_Log("Wait"); - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - SDL_Log("Crosshair"); - break; - case SDL_SYSTEM_CURSOR_PROGRESS: - SDL_Log("Progress: Small wait cursor (or Wait if not available)"); - break; - case SDL_SYSTEM_CURSOR_NWSE_RESIZE: - SDL_Log("Double arrow pointing northwest and southeast"); - break; - case SDL_SYSTEM_CURSOR_NESW_RESIZE: - SDL_Log("Double arrow pointing northeast and southwest"); - break; - case SDL_SYSTEM_CURSOR_EW_RESIZE: - SDL_Log("Double arrow pointing west and east"); - break; - case SDL_SYSTEM_CURSOR_NS_RESIZE: - SDL_Log("Double arrow pointing north and south"); - break; - case SDL_SYSTEM_CURSOR_MOVE: - SDL_Log("Move: Four pointed arrow pointing north, south, east, and west"); - break; - case SDL_SYSTEM_CURSOR_NOT_ALLOWED: - SDL_Log("Not Allowed: Slashed circle or crossbones"); - break; - case SDL_SYSTEM_CURSOR_POINTER: - SDL_Log("Pointer: Hand"); - break; - case SDL_SYSTEM_CURSOR_NW_RESIZE: - SDL_Log("Window resize top-left"); - break; - case SDL_SYSTEM_CURSOR_N_RESIZE: - SDL_Log("Window resize top"); - break; - case SDL_SYSTEM_CURSOR_NE_RESIZE: - SDL_Log("Window resize top-right"); - break; - case SDL_SYSTEM_CURSOR_E_RESIZE: - SDL_Log("Window resize right"); - break; - case SDL_SYSTEM_CURSOR_SE_RESIZE: - SDL_Log("Window resize bottom-right"); - break; - case SDL_SYSTEM_CURSOR_S_RESIZE: - SDL_Log("Window resize bottom"); - break; - case SDL_SYSTEM_CURSOR_SW_RESIZE: - SDL_Log("Window resize bottom-left"); - break; - case SDL_SYSTEM_CURSOR_W_RESIZE: - SDL_Log("Window resize left"); - break; - default: - SDL_Log("UNKNOWN CURSOR TYPE, FIX THIS PROGRAM."); - break; - } + SDL_Log("%s", get_active_cursor_name()); } else { show_cursor = !show_cursor; @@ -463,6 +462,8 @@ static void loop(void) black = !black; } } + SDL_SetRenderDrawColor(renderer, 0xff, 0x00, 0x00, 0xFF); + SDL_RenderDebugText(renderer, 0.0f, 0.0f, get_active_cursor_name()); SDL_RenderPresent(renderer); } #ifdef SDL_PLATFORM_EMSCRIPTEN @@ -526,7 +527,7 @@ int main(int argc, char *argv[]) cursor = init_color_cursor(frames, num_frames); if (cursor) { cursors[num_cursors] = cursor; - cursor_types[num_cursors] = (SDL_SystemCursor)-1; + cursor_types[num_cursors] = (SDL_SystemCursor)CUSTOM_CURSOR_ARGUMENTS; num_cursors++; } } @@ -534,28 +535,28 @@ int main(int argc, char *argv[]) cursor = init_system_cursor(arrow); if (cursor) { cursors[num_cursors] = cursor; - cursor_types[num_cursors] = (SDL_SystemCursor)-1; + cursor_types[num_cursors] = (SDL_SystemCursor)CUSTOM_CURSOR_ARROW; num_cursors++; } cursor = init_system_cursor(cross); if (cursor) { cursors[num_cursors] = cursor; - cursor_types[num_cursors] = (SDL_SystemCursor)-1; + cursor_types[num_cursors] = (SDL_SystemCursor)CUSTOM_CURSOR_CROSS; num_cursors++; } cursor = init_animated_cursor(arrow, false); if (cursor) { cursors[num_cursors] = cursor; - cursor_types[num_cursors] = (SDL_SystemCursor)-2; + cursor_types[num_cursors] = (SDL_SystemCursor)CUSTOM_ANIMATED_CURSOR; num_cursors++; } cursor = init_animated_cursor(arrow, true); if (cursor) { cursors[num_cursors] = cursor; - cursor_types[num_cursors] = (SDL_SystemCursor)-3; + cursor_types[num_cursors] = (SDL_SystemCursor)CUSTOM_ANIMATED_CURSOR_ONE_SHOT; num_cursors++; } From c00e9c991e0c97fa3331431f6bcb56253517e319 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 13 Apr 2026 23:52:59 +0200 Subject: [PATCH 108/407] test: use SDL_test for event handling --- test/testdialog.c | 102 +++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/test/testdialog.c b/test/testdialog.c index 73cebe8137..daeb6b8e37 100644 --- a/test/testdialog.c +++ b/test/testdialog.c @@ -16,7 +16,7 @@ #include #include -const SDL_DialogFileFilter filters[] = { +static const SDL_DialogFileFilter filters[] = { { "All files", "*" }, { "SVI Session Indexes", "index;svi-index;index.pb" }, { "JPG images", "jpg;jpeg" }, @@ -27,7 +27,7 @@ static void SDLCALL callback(void *userdata, const char * const *files, int filt char **saved_path = userdata; if (files) { - const char* filter_name = "(filter fetching unsupported)"; + const char *filter_name = "(filter fetching unsupported)"; if (filter != -1) { if (filter < sizeof(filters) / sizeof(*filters)) { @@ -55,7 +55,7 @@ static void SDLCALL callback(void *userdata, const char * const *files, int filt } } -char *concat_strings(const char *a, const char *b) +static char *concat_strings(const char *a, const char *b) { char *out = NULL; @@ -74,45 +74,27 @@ char *concat_strings(const char *a, const char *b) int main(int argc, char *argv[]) { - SDL_Window *w; - SDL_Renderer *r; - SDLTest_CommonState *state; - const SDL_FRect open_file_rect = { 50, 50, 220, 140 }; - const SDL_FRect save_file_rect = { 50, 290, 220, 140 }; - const SDL_FRect open_folder_rect = { 370, 50, 220, 140 }; - int i; - const char *default_filename = "Untitled.index"; + static const SDL_FRect OPEN_FILE_RECT = { 50, 50, 220, 140 }; + static const SDL_FRect SAVE_FILE_RECT = { 50, 290, 220, 140 }; + static const SDL_FRect OPEN_FOLDER_RECT = { 370, 50, 220, 140 }; + static const char DEFAULT_FILENAME[] = "Untitled.index"; const char *initial_path = NULL; char *last_saved_path = NULL; /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, 0); + SDLTest_CommonState *state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); if (state == NULL) { return 1; } - /* Parse commandline */ - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - - if (consumed <= 0) { - static const char *options[] = { NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - return 1; - } - - i += consumed; - } - - if (!SDL_Init(SDL_INIT_VIDEO)) { - SDL_Log("SDL_Init failed (%s)", SDL_GetError()); + if (!SDLTest_CommonDefaultArgs(state, argc, argv)) { + SDL_Quit(); + SDLTest_CommonDestroyState(state); return 1; } - if (!SDL_CreateWindowAndRenderer("testdialog", 640, 480, 0, &w, &r)) { - SDL_Log("Failed to create window and/or renderer: %s", SDL_GetError()); - SDL_Quit(); + + if (!SDLTest_CommonInit(state)) { + SDL_Log("SDL_Init failed (%s)", SDL_GetError()); return 1; } @@ -123,14 +105,13 @@ int main(int argc, char *argv[]) } while (1) { - int quit = 0; + int done = 0; SDL_Event e; while (SDL_PollEvent(&e)) { - if (e.type == SDL_EVENT_QUIT) { - quit = 1; - break; - } else if (e.type == SDL_EVENT_MOUSE_BUTTON_UP) { + SDLTest_CommonEvent(state, &e, &done); + if (e.type == SDL_EVENT_MOUSE_BUTTON_UP) { const SDL_FPoint p = { e.button.x, e.button.y }; + SDL_Window *w = SDL_GetWindowFromID(e.button.windowID); /* * Arguments, in order: * - A function to call when files are chosen (or dialog is canceled, or error happens) @@ -140,52 +121,53 @@ int main(int argc, char *argv[]) * - The path where the dialog should start. May be a folder or a file * - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog) */ - if (SDL_PointInRectFloat(&p, &open_file_rect)) { + if (SDL_PointInRectFloat(&p, &OPEN_FILE_RECT)) { SDL_ShowOpenFileDialog(callback, NULL, w, filters, SDL_arraysize(filters), initial_path, 1); - } else if (SDL_PointInRectFloat(&p, &open_folder_rect)) { + } else if (SDL_PointInRectFloat(&p, &OPEN_FOLDER_RECT)) { SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1); - } else if (SDL_PointInRectFloat(&p, &save_file_rect)) { + } else if (SDL_PointInRectFloat(&p, &SAVE_FILE_RECT)) { char *save_path = NULL; if (last_saved_path) { save_path = SDL_strdup(last_saved_path); } else { - save_path = concat_strings(initial_path, default_filename); + save_path = concat_strings(initial_path, DEFAULT_FILENAME); } - SDL_ShowSaveFileDialog(callback, &last_saved_path, w, filters, SDL_arraysize(filters), save_path ? save_path : default_filename); + SDL_ShowSaveFileDialog(callback, &last_saved_path, w, filters, SDL_arraysize(filters), save_path ? save_path : DEFAULT_FILENAME); SDL_free(save_path); } } } - if (quit) { + if (done) { break; } SDL_Delay(100); - SDL_SetRenderDrawColor(r, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(r); + for (int i = 0; i < state->num_windows; i++) { + SDL_Renderer *r = state->renderers[i]; - SDL_SetRenderDrawColor(r, 255, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderFillRect(r, &open_file_rect); + SDL_SetRenderDrawColor(r, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(r); - SDL_SetRenderDrawColor(r, 0, 255, 0, SDL_ALPHA_OPAQUE); - SDL_RenderFillRect(r, &save_file_rect); + SDL_SetRenderDrawColor(r, 255, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(r, &OPEN_FILE_RECT); - SDL_SetRenderDrawColor(r, 0, 0, 255, SDL_ALPHA_OPAQUE); - SDL_RenderFillRect(r, &open_folder_rect); + SDL_SetRenderDrawColor(r, 0, 255, 0, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(r, &SAVE_FILE_RECT); - SDL_SetRenderDrawColor(r, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDLTest_DrawString(r, open_file_rect.x+5, open_file_rect.y+open_file_rect.h/2, "Open File..."); - SDLTest_DrawString(r, save_file_rect.x+5, save_file_rect.y+save_file_rect.h/2, "Save File..."); - SDLTest_DrawString(r, open_folder_rect.x+5, open_folder_rect.y+open_folder_rect.h/2, "Open Folder..."); + SDL_SetRenderDrawColor(r, 0, 0, 255, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(r, &OPEN_FOLDER_RECT); - SDL_RenderPresent(r); + SDL_SetRenderDrawColor(r, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDLTest_DrawString(r, OPEN_FILE_RECT.x+5, OPEN_FILE_RECT.y+OPEN_FILE_RECT.h/2, "Open File..."); + SDLTest_DrawString(r, SAVE_FILE_RECT.x+5, SAVE_FILE_RECT.y+SAVE_FILE_RECT.h/2, "Save File..."); + SDLTest_DrawString(r, OPEN_FOLDER_RECT.x+5, OPEN_FOLDER_RECT.y+OPEN_FOLDER_RECT.h/2, "Open Folder..."); + + SDL_RenderPresent(r); + } } SDL_free(last_saved_path); SDLTest_CleanupTextDrawing(); - SDL_DestroyRenderer(r); - SDL_DestroyWindow(w); - SDL_Quit(); - SDLTest_CommonDestroyState(state); + SDLTest_CommonQuit(state); return 0; } From 59ee54d136b59cc0aa4c3c4cce9bc962085ad525 Mon Sep 17 00:00:00 2001 From: rewine Date: Tue, 14 Apr 2026 20:29:57 +0800 Subject: [PATCH 109/407] wayland: bind cursor-shape-v1 at protocol version 2 cursor-shape-v1 version 2 adds dnd_ask and all_resize, but SDL_SystemCursor does not expose matching cursor types yet. Bind the protocol at version 2 now so SDL negotiates the updated interface correctly while keeping the current cursor mapping unchanged. --- src/video/wayland/SDL_waylandvideo.c | 2 +- wayland-protocols/cursor-shape-v1.xml | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 3e0ca45679..2a29d632c9 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -1402,7 +1402,7 @@ static void handle_registry_global(void *data, struct wl_registry *registry, uin d->input_timestamps_manager = wl_registry_bind(d->registry, id, &zwp_input_timestamps_manager_v1_interface, 1); Wayland_DisplayInitInputTimestampManager(d); } else if (SDL_strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) { - d->cursor_shape_manager = wl_registry_bind(d->registry, id, &wp_cursor_shape_manager_v1_interface, 1); + d->cursor_shape_manager = wl_registry_bind(d->registry, id, &wp_cursor_shape_manager_v1_interface, SDL_min(version, 2)); Wayland_DisplayInitCursorShapeManager(d); } else if (SDL_strcmp(interface, zxdg_exporter_v2_interface.name) == 0) { d->zxdg_exporter_v2 = wl_registry_bind(d->registry, id, &zxdg_exporter_v2_interface, 1); diff --git a/wayland-protocols/cursor-shape-v1.xml b/wayland-protocols/cursor-shape-v1.xml index 56f6a1a65b..64b2f9b2c8 100644 --- a/wayland-protocols/cursor-shape-v1.xml +++ b/wayland-protocols/cursor-shape-v1.xml @@ -22,7 +22,7 @@ DEALINGS IN THE SOFTWARE. - + This global offers an alternative, optional way to set cursor images. This new way uses enumerated cursors instead of a wl_surface like @@ -43,6 +43,9 @@ Obtain a wp_cursor_shape_device_v1 for a wl_pointer object. + + When the pointer capability is removed from the wl_seat, the + wp_cursor_shape_device_v1 object becomes inert. @@ -51,16 +54,18 @@ Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object. + + When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1 + object becomes inert. - + - This interface advertises the list of supported cursor shapes for a - device, and allows clients to set the cursor shape. + This interface allows clients to set the cursor shape. @@ -69,6 +74,14 @@ The names are taken from the CSS W3C specification: https://w3c.github.io/csswg-drafts/css-ui/#cursor + with a few additions. + + Note that there are some groups of cursor shapes that are related: + The first group is drag-and-drop cursors which are used to indicate + the selected action during dnd operations. The second group is resize + cursors which are used to indicate resizing and moving possibilities + on window borders. It is recommended that the shapes in these groups + should use visually compatible images and metaphors. @@ -104,6 +117,8 @@ + + From dba9aa147cb7b3d619581726bd1937a42faf342b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 12 Apr 2026 14:43:52 -0500 Subject: [PATCH 110/407] atomic: Switch to SDL_HAS_BUILTIN to detect __atomic_load_n --- src/atomic/SDL_atomic.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index 40d57929ae..0cd67ef936 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -34,19 +34,15 @@ #endif // The __atomic_load_n() intrinsic showed up in different times for different compilers. -#ifdef __clang__ -#if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS) +#if defined(__GNUC__) && (__GNUC__ >= 5) +#define HAVE_ATOMIC_LOAD_N 1 +#elif SDL_HAS_BUILTIN(__atomic_load_n) || (defined(__clang__) && defined(HAVE_GCC_ATOMICS)) /* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have. It might be in a later NDK or we might need an extra library? --ryan. */ #ifndef SDL_PLATFORM_ANDROID #define HAVE_ATOMIC_LOAD_N 1 #endif #endif -#elif defined(__GNUC__) -#if (__GNUC__ >= 5) -#define HAVE_ATOMIC_LOAD_N 1 -#endif -#endif /* If any of the operations are not provided then we must emulate some From 59267ed800661f81b7f89b49e88473acde7ce4bb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 12 Apr 2026 14:44:46 -0500 Subject: [PATCH 111/407] atomic: Use __atomic_load_n on Android --- src/atomic/SDL_atomic.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index 0cd67ef936..e8a013c0aa 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -37,12 +37,8 @@ #if defined(__GNUC__) && (__GNUC__ >= 5) #define HAVE_ATOMIC_LOAD_N 1 #elif SDL_HAS_BUILTIN(__atomic_load_n) || (defined(__clang__) && defined(HAVE_GCC_ATOMICS)) -/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have. - It might be in a later NDK or we might need an extra library? --ryan. */ -#ifndef SDL_PLATFORM_ANDROID #define HAVE_ATOMIC_LOAD_N 1 #endif -#endif /* If any of the operations are not provided then we must emulate some From a49a5e87a9fa41a12da32fca98987beef84964fc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 15 Apr 2026 13:28:52 -0400 Subject: [PATCH 112/407] wikiheaders: Don't escape `.` chars in manpage's brief section. Otherwise, the `apropos` command gets upset. Fixes #15387. --- build-scripts/wikiheaders.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build-scripts/wikiheaders.pl b/build-scripts/wikiheaders.pl index c796b0c245..51e7d7d236 100755 --- a/build-scripts/wikiheaders.pl +++ b/build-scripts/wikiheaders.pl @@ -2912,6 +2912,11 @@ __EOF__ $brief = shift @briefsplit; $brief = dewikify($wikitype, $brief); + # Hack: `apropros` doesn't like escaped character things like `\[char46]` for `.`...since almost every + # manpage will end their Brief section with a period and it won't wordwrap to risk being a groff control + # character, just replace it. + $brief =~ s/\\\[char46\]/./g; + if (defined $remarks) { $remarks = dewikify($wikitype, join("\n", @briefsplit) . $remarks); } From 4870f81d9caf5838e174a88fd4b780b9cc3869f6 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 15 Apr 2026 19:44:24 +0200 Subject: [PATCH 113/407] [N-Gage] Optimize rendering back-end - Remove SDL_Surface member from NGAGE_TextureData structure and update all functions that currently use surface->pixels to instead access bitmap->DataAddress() directly. This eliminates the intermediate copy step (Mem::Copy from surface to bitmap) in rendering operations. - Eliminate per-frame allocations in Copy/CopyEx methods. These buffers are now allocated once and resized only when needed. --- src/render/ngage/SDL_render_ngage.c | 60 ++++--- src/render/ngage/SDL_render_ngage.cpp | 207 +++++++++++++++++------- src/render/ngage/SDL_render_ngage_c.h | 11 +- src/render/ngage/SDL_render_ngage_c.hpp | 8 + src/render/ngage/SDL_render_ops.cpp | 59 +++---- 5 files changed, 222 insertions(+), 123 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.c b/src/render/ngage/SDL_render_ngage.c index 3d8d59c03f..74a4ce5771 100644 --- a/src/render/ngage/SDL_render_ngage.c +++ b/src/render/ngage/SDL_render_ngage.c @@ -160,13 +160,6 @@ static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD return false; } - SDL_Surface *surface = SDL_CreateSurface(texture->w, texture->h, texture->format); - if (!surface) { - SDL_free(data); - return false; - } - - data->surface = surface; texture->internal = data; return true; @@ -447,29 +440,25 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co { NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; - SDL_Surface *surface = phdata->surface; - Uint8 *src, *dst; - int row; - size_t length; - - if (SDL_MUSTLOCK(surface)) { - if (!SDL_LockSurface(surface)) { - return false; - } + if (!phdata) { + return false; } - src = (Uint8 *)pixels; - dst = (Uint8 *)surface->pixels + - rect->y * surface->pitch + - rect->x * surface->fmt->bytes_per_pixel; - length = (size_t)rect->w * surface->fmt->bytes_per_pixel; - for (row = 0; row < rect->h; ++row) { + void *bitmapData = NGAGE_GetBitmapDataAddress(phdata); + int bitmapPitch = NGAGE_GetBitmapPitch(phdata); + + if (!bitmapData || bitmapPitch == 0) { + return false; + } + + Uint8 *src = (Uint8 *)pixels; + Uint8 *dst = (Uint8 *)bitmapData + rect->y * bitmapPitch + rect->x * 2; // 2 bytes per pixel for EColor4K + + size_t length = (size_t)rect->w * 2; // 2 bytes per pixel for EColor4K + for (int row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; - dst += surface->pitch; - } - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); + dst += bitmapPitch; } return true; @@ -478,12 +467,20 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch) { NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; - SDL_Surface *surface = phdata->surface; - *pixels = - (void *)((Uint8 *)surface->pixels + rect->y * surface->pitch + - rect->x * surface->fmt->bytes_per_pixel); - *pitch = surface->pitch; + if (!phdata) { + return false; + } + + void *bitmapData = NGAGE_GetBitmapDataAddress(phdata); + int bitmapPitch = NGAGE_GetBitmapPitch(phdata); + + if (!bitmapData || bitmapPitch == 0) { + return false; + } + + *pixels = (void *)((Uint8 *)bitmapData + rect->y * bitmapPitch + rect->x * 2); // 2 bytes per pixel for EColor4K + *pitch = bitmapPitch; return true; } @@ -512,7 +509,6 @@ static void NGAGE_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { NGAGE_TextureData *data = (NGAGE_TextureData *)texture->internal; if (data) { - SDL_DestroySurface(data->surface); NGAGE_DestroyTextureData(data); SDL_free(data); texture->internal = 0; diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 2198c02b3b..18f5084139 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -72,6 +72,39 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data) } } +void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data) +{ + if (data && data->bitmap) { + return data->bitmap->DataAddress(); + } + return NULL; +} + +int NGAGE_GetBitmapPitch(NGAGE_TextureData *data) +{ + if (data && data->bitmap) { + TSize size = data->bitmap->SizeInPixels(); + return data->bitmap->ScanLineLength(size.iWidth, data->bitmap->DisplayMode()); + } + return 0; +} + +int NGAGE_GetBitmapWidth(NGAGE_TextureData *data) +{ + if (data && data->bitmap) { + return data->bitmap->SizeInPixels().iWidth; + } + return 0; +} + +int NGAGE_GetBitmapHeight(NGAGE_TextureData *data) +{ + if (data && data->bitmap) { + return data->bitmap->SizeInPixels().iHeight; + } + return 0; +} + void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count) { gRenderer->DrawLines(verts, count); @@ -127,12 +160,19 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0) {} CRenderer::~CRenderer() { delete iRenderer; iRenderer = 0; + + // Free work buffers. + SDL_free(iWorkBuffer1); + SDL_free(iWorkBuffer2); + iWorkBuffer1 = 0; + iWorkBuffer2 = 0; + iWorkBufferSize = 0; } void CRenderer::ConstructL() @@ -251,6 +291,36 @@ void CRenderer::Clear(TUint32 iColor) } } +bool CRenderer::EnsureWorkBufferCapacity(TInt aRequiredSize) +{ + if (aRequiredSize <= iWorkBufferSize) { + return true; + } + + // Free old buffers. + SDL_free(iWorkBuffer1); + SDL_free(iWorkBuffer2); + + // Allocate new buffers. + iWorkBuffer1 = SDL_calloc(1, aRequiredSize); + if (!iWorkBuffer1) { + iWorkBuffer2 = 0; + iWorkBufferSize = 0; + return false; + } + + iWorkBuffer2 = SDL_calloc(1, aRequiredSize); + if (!iWorkBuffer2) { + SDL_free(iWorkBuffer1); + iWorkBuffer1 = 0; + iWorkBufferSize = 0; + return false; + } + + iWorkBufferSize = aRequiredSize; + return true; +} + #ifdef __cplusplus extern "C" { #endif @@ -293,65 +363,72 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec } NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; - if (!phdata) { + if (!phdata || !phdata->bitmap) { return false; } SDL_FColor *c = &texture->color; - int w = phdata->surface->w; - int h = phdata->surface->h; - int pitch = phdata->surface->pitch; - void *source = phdata->surface->pixels; + + // Get render scale. + float sx; + float sy; + SDL_GetRenderScale(renderer, &sx, &sy); + + // Fast path: No transformations needed; direct BitBlt. + if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f && + sx == 1.f && sy == 1.f) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } + + // Slow path: Transformations needed. + int w = phdata->cachedWidth; + int h = phdata->cachedHeight; + int pitch = phdata->cachedPitch; + void *source = phdata->cachedDataAddress; void *dest; if (!source) { return false; } - void *pixel_buffer_a = SDL_calloc(1, pitch * h); - if (!pixel_buffer_a) { + // Ensure work buffers have sufficient capacity. + TInt bufferSize = pitch * h; + if (!EnsureWorkBufferCapacity(bufferSize)) { return false; } - dest = pixel_buffer_a; - void *pixel_buffer_b = SDL_calloc(1, pitch * h); - if (!pixel_buffer_b) { - SDL_free(pixel_buffer_a); - return false; - } + dest = iWorkBuffer1; + bool useBuffer1 = true; if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { ApplyColorMod(dest, source, pitch, w, h, texture->color); - source = dest; + useBuffer1 = !useBuffer1; } - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); - if (sx != 1.f || sy != 1.f) { TFixed scale_x = Real2Fix(sx); TFixed scale_y = Real2Fix(sy); TFixed center_x = Int2Fix(w / 2); TFixed center_y = Int2Fix(h / 2); - dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a; - + dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y); - source = dest; + useBuffer1 = !useBuffer1; } - Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); - SDL_free(pixel_buffer_a); - SDL_free(pixel_buffer_b); + // Render directly from work buffer without copying back to bitmap. + // Note: We need a temporary bitmap for rendering the transformed data. + // For now, copy to original bitmap (this could be further optimized with a render target). + Mem::Copy(phdata->cachedDataAddress, source, pitch * h); - if (phdata->bitmap) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - } + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); return true; } @@ -359,65 +436,78 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE_CopyExData *copydata) { NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; - if (!phdata) { + if (!phdata || !phdata->bitmap) { return false; } SDL_FColor *c = &texture->color; - int w = phdata->surface->w; - int h = phdata->surface->h; - int pitch = phdata->surface->pitch; - void *source = phdata->surface->pixels; + + // Fast path: No transformations needed; direct BitBlt. + if (!copydata->flip && + copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1) && + copydata->angle == 0 && + c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } + + // Slow path: Transformations needed. + int w = phdata->cachedWidth; + int h = phdata->cachedHeight; + int pitch = phdata->cachedPitch; + void *source = phdata->cachedDataAddress; void *dest; if (!source) { return false; } - void *pixel_buffer_a = SDL_calloc(1, pitch * h); - if (!pixel_buffer_a) { + // Ensure work buffers have sufficient capacity. + TInt bufferSize = pitch * h; + if (!EnsureWorkBufferCapacity(bufferSize)) { return false; } - dest = pixel_buffer_a; - void *pixel_buffer_b = SDL_calloc(1, pitch * h); - if (!pixel_buffer_a) { - SDL_free(pixel_buffer_a); - return false; - } + dest = iWorkBuffer1; + bool useBuffer1 = true; if (copydata->flip) { ApplyFlip(dest, source, pitch, w, h, copydata->flip); source = dest; + useBuffer1 = !useBuffer1; } - if (copydata->scale_x != 1.f || copydata->scale_y != 1.f) { - dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a; + if (copydata->scale_x != Int2Fix(1) || copydata->scale_y != Int2Fix(1)) { + dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); source = dest; + useBuffer1 = !useBuffer1; } if (copydata->angle) { - dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a; + dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle); source = dest; + useBuffer1 = !useBuffer1; } if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { - dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a; + dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyColorMod(dest, source, pitch, w, h, texture->color); source = dest; + useBuffer1 = !useBuffer1; } - Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); - SDL_free(pixel_buffer_a); - SDL_free(pixel_buffer_b); + // Render directly from work buffer without copying back to bitmap. + // Note: We need a temporary bitmap for rendering the transformed data. + // For now, copy to original bitmap (this could be further optimized with a render target). + Mem::Copy(phdata->cachedDataAddress, source, pitch * h); - if (phdata->bitmap) { - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); - TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - } + TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); return true; } @@ -440,6 +530,13 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW return false; } + // Cache texture properties to avoid repeated API calls. + TSize bitmapSize = aTextureData->bitmap->SizeInPixels(); + aTextureData->cachedWidth = bitmapSize.iWidth; + aTextureData->cachedHeight = bitmapSize.iHeight; + aTextureData->cachedPitch = aTextureData->bitmap->ScanLineLength(aWidth, aTextureData->bitmap->DisplayMode()); + aTextureData->cachedDataAddress = aTextureData->bitmap->DataAddress(); + return true; } diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index 32ce861525..4d56e472ca 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -58,7 +58,12 @@ typedef struct CFbsBitmap CFbsBitmap; typedef struct NGAGE_TextureData { CFbsBitmap *bitmap; - SDL_Surface *surface; + + // Cached properties to avoid repeated API calls. + int cachedWidth; + int cachedHeight; + int cachedPitch; + void *cachedDataAddress; } NGAGE_TextureData; @@ -89,6 +94,10 @@ bool NGAGE_Copy(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Rect *srcrect, bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData *copydata); bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height); void NGAGE_DestroyTextureData(NGAGE_TextureData *data); +void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); +int NGAGE_GetBitmapPitch(NGAGE_TextureData *data); +int NGAGE_GetBitmapWidth(NGAGE_TextureData *data); +int NGAGE_GetBitmapHeight(NGAGE_TextureData *data); void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count); void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count); void NGAGE_FillRects(NGAGE_Vertex *verts, const int count); diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 63aef670d3..007b7145a7 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -86,6 +86,14 @@ class CRenderer : public MDirectScreenAccess // Screen saver. TBool iSuspendScreenSaver; + + // Work buffers for texture transformations (reusable to avoid per-frame allocations). + void *iWorkBuffer1; + void *iWorkBuffer2; + TInt iWorkBufferSize; + + // Helper method to ensure work buffers have sufficient capacity. + bool EnsureWorkBufferCapacity(TInt aRequiredSize); }; #endif // ngage_video_render_ngage_c_hpp diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 3874700bd2..8a2244436b 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -20,8 +20,8 @@ */ #include "SDL_internal.h" -#include <3dtypes.h> #include "SDL_render_ops.hpp" +#include <3dtypes.h> void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color) { @@ -32,18 +32,22 @@ void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, S TFixed gf = Real2Fix(color.g); TFixed bf = Real2Fix(color.b); - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { - TUint16 pixel = src_pixels[y * pitch / 2 + x]; + // Pre-calculate pitch in pixels to avoid repeated division. + const TInt pitchPixels = pitch >> 1; + + for (int y = 0; y < height; ++y) { + // Calculate row offset once per row. + TInt rowOffset = y * pitchPixels; + + for (int x = 0; x < width; ++x) { + TUint16 pixel = src_pixels[rowOffset + x]; TUint8 r = (pixel & 0xF800) >> 8; TUint8 g = (pixel & 0x07E0) >> 3; TUint8 b = (pixel & 0x001F) << 3; r = FixMul(r, rf); g = FixMul(g, gf); b = FixMul(b, bf); - dst_pixels[y * pitch / 2 + x] = (r << 8) | (g << 3) | (b >> 3); + dst_pixels[rowOffset + x] = (r << 8) | (g << 3) | (b >> 3); } } } @@ -53,20 +57,16 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { int src_x = x; int src_y = y; - if (flip & SDL_FLIP_HORIZONTAL) - { + if (flip & SDL_FLIP_HORIZONTAL) { src_x = width - 1 - x; } - if (flip & SDL_FLIP_VERTICAL) - { + if (flip & SDL_FLIP_VERTICAL) { src_y = height - 1 - y; } @@ -83,15 +83,12 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T TFixed cos_angle = 0; TFixed sin_angle = 0; - if (angle != 0) - { + if (angle != 0) { FixSinCos(angle, sin_angle, cos_angle); } - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { // Translate point to origin. TFixed translated_x = Int2Fix(x) - center_x; TFixed translated_y = Int2Fix(y) - center_y; @@ -105,12 +102,9 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T int final_y = Fix2Int(rotated_y + center_y); // Check bounds. - if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) - { + if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x]; - } - else - { + } else { dst_pixels[y * pitch / 2 + x] = 0; } } @@ -122,10 +116,8 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { // Translate point to origin. TFixed translated_x = Int2Fix(x) - center_x; TFixed translated_y = Int2Fix(y) - center_y; @@ -139,12 +131,9 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix int final_y = Fix2Int(scaled_y + center_y); // Check bounds. - if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) - { + if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x]; - } - else - { + } else { dst_pixels[y * pitch / 2 + x] = 0; } } From e5c8523b36fae58983d020414f8dec22359e6e04 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 15 Apr 2026 20:05:26 +0200 Subject: [PATCH 114/407] [N-Gage] Preserve source textures and optimize rotation with DDA - Add temporary render bitmap to avoid destroying source texture data - Implement incremental DDA algorithm for rotation - Replaces per-pixel FixMul operations with simple additions and preserves textures for reuse. --- src/render/ngage/SDL_render_ngage.cpp | 70 +++++++++++++++++++++---- src/render/ngage/SDL_render_ngage_c.hpp | 8 ++- src/render/ngage/SDL_render_ops.cpp | 42 ++++++++++----- 3 files changed, 95 insertions(+), 25 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 18f5084139..47ba9fbf9a 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -160,7 +160,7 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0) {} CRenderer::~CRenderer() { @@ -173,6 +173,12 @@ CRenderer::~CRenderer() iWorkBuffer1 = 0; iWorkBuffer2 = 0; iWorkBufferSize = 0; + + // Free temp render bitmap. + delete iTempRenderBitmap; + iTempRenderBitmap = 0; + iTempRenderBitmapWidth = 0; + iTempRenderBitmapHeight = 0; } void CRenderer::ConstructL() @@ -321,6 +327,40 @@ bool CRenderer::EnsureWorkBufferCapacity(TInt aRequiredSize) return true; } +bool CRenderer::EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight) +{ + if (iTempRenderBitmap && + iTempRenderBitmapWidth >= aWidth && + iTempRenderBitmapHeight >= aHeight) { + return true; + } + + // Delete old bitmap. + delete iTempRenderBitmap; + iTempRenderBitmap = 0; + + // Create new bitmap. + iTempRenderBitmap = new CFbsBitmap(); + if (!iTempRenderBitmap) { + iTempRenderBitmapWidth = 0; + iTempRenderBitmapHeight = 0; + return false; + } + + TInt error = iTempRenderBitmap->Create(TSize(aWidth, aHeight), EColor4K); + if (error != KErrNone) { + delete iTempRenderBitmap; + iTempRenderBitmap = 0; + iTempRenderBitmapWidth = 0; + iTempRenderBitmapHeight = 0; + return false; + } + + iTempRenderBitmapWidth = aWidth; + iTempRenderBitmapHeight = aHeight; + return true; +} + #ifdef __cplusplus extern "C" { #endif @@ -421,14 +461,18 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec useBuffer1 = !useBuffer1; } - // Render directly from work buffer without copying back to bitmap. - // Note: We need a temporary bitmap for rendering the transformed data. - // For now, copy to original bitmap (this could be further optimized with a render target). - Mem::Copy(phdata->cachedDataAddress, source, pitch * h); + // Use temp bitmap to avoid destroying source texture. + if (!EnsureTempBitmapCapacity(w, h)) { + return false; + } + // Copy transformed data to temp bitmap. + Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h); + + // Render from temp bitmap, preserving original texture. TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + iRenderer->Gc()->BitBlt(aDest, iTempRenderBitmap, aSource); return true; } @@ -500,14 +544,18 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE useBuffer1 = !useBuffer1; } - // Render directly from work buffer without copying back to bitmap. - // Note: We need a temporary bitmap for rendering the transformed data. - // For now, copy to original bitmap (this could be further optimized with a render target). - Mem::Copy(phdata->cachedDataAddress, source, pitch * h); + // Use temp bitmap to avoid destroying source texture. + if (!EnsureTempBitmapCapacity(w, h)) { + return false; + } + // Copy transformed data to temp bitmap. + Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h); + + // Render from temp bitmap, preserving original texture. TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + iRenderer->Gc()->BitBlt(aDest, iTempRenderBitmap, aSource); return true; } diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 007b7145a7..600d4d0622 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -92,8 +92,14 @@ class CRenderer : public MDirectScreenAccess void *iWorkBuffer2; TInt iWorkBufferSize; - // Helper method to ensure work buffers have sufficient capacity. + // Temporary render bitmap to avoid destroying source textures. + CFbsBitmap *iTempRenderBitmap; + TInt iTempRenderBitmapWidth; + TInt iTempRenderBitmapHeight; + + // Helper methods. bool EnsureWorkBufferCapacity(TInt aRequiredSize); + bool EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight); }; #endif // ngage_video_render_ngage_c_hpp diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 8a2244436b..89006e662c 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -87,26 +87,42 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T FixSinCos(angle, sin_angle, cos_angle); } + // Pre-calculate pitch in pixels to avoid repeated division. + const TInt pitchPixels = pitch >> 1; + + // Incremental DDA: Calculate per-pixel increments. + // As we move right (x+1), the rotated position changes by (cos, -sin). + TFixed dx_cos = cos_angle; + TFixed dx_sin = -sin_angle; + for (int y = 0; y < height; ++y) { + // Calculate destination row offset once per row. + TInt dstRowOffset = y * pitchPixels; + + // Calculate starting position for this row. + TFixed translated_y = Int2Fix(y) - center_y; + TFixed row_start_x = FixMul(translated_y, sin_angle) + center_x; + TFixed row_start_y = FixMul(translated_y, cos_angle) + center_y; + + // For first pixel in row, account for x=0 translation. + TFixed src_x = row_start_x - FixMul(center_x, cos_angle); + TFixed src_y = row_start_y + FixMul(center_x, sin_angle); + for (int x = 0; x < width; ++x) { - // Translate point to origin. - TFixed translated_x = Int2Fix(x) - center_x; - TFixed translated_y = Int2Fix(y) - center_y; - - // Rotate point (clockwise). - TFixed rotated_x = FixMul(translated_x, cos_angle) + FixMul(translated_y, sin_angle); - TFixed rotated_y = FixMul(translated_y, cos_angle) - FixMul(translated_x, sin_angle); - - // Translate point back. - int final_x = Fix2Int(rotated_x + center_x); - int final_y = Fix2Int(rotated_y + center_y); + // Convert to integer coordinates. + int final_x = Fix2Int(src_x); + int final_y = Fix2Int(src_y); // Check bounds. if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { - dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x]; + dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; } else { - dst_pixels[y * pitch / 2 + x] = 0; + dst_pixels[dstRowOffset + x] = 0; } + + // Incremental step: move to next pixel (just additions, no multiplications!). + src_x += dx_cos; + src_y += dx_sin; } } } From 5bd1a65e6f830bff5fba97f2abd5dd22948c8a52 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 15 Apr 2026 20:34:23 +0200 Subject: [PATCH 115/407] [N-Gage] Add LUT color mod, cardinal rotation cache and loop unrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implement lookup tables for faster color modulation - Cache 0°/90°/180°/270° rotations for speedup on common angles - Add dirty rectangle tracking infrastructure - Process 4 pixels at a time in all transform operations --- src/render/ngage/SDL_render_ngage.c | 14 ++ src/render/ngage/SDL_render_ngage.cpp | 165 +++++++++++++++++++++++- src/render/ngage/SDL_render_ngage_c.h | 7 + src/render/ngage/SDL_render_ngage_c.hpp | 9 ++ src/render/ngage/SDL_render_ops.cpp | 162 +++++++++++++++++------ src/render/ngage/SDL_render_ops.hpp | 2 +- 6 files changed, 319 insertions(+), 40 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.c b/src/render/ngage/SDL_render_ngage.c index 74a4ce5771..b960a84d87 100644 --- a/src/render/ngage/SDL_render_ngage.c +++ b/src/render/ngage/SDL_render_ngage.c @@ -461,6 +461,10 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co dst += bitmapPitch; } + // Mark texture as dirty. + phdata->isDirty = true; + phdata->dirtyRect = *rect; + return true; } @@ -481,11 +485,21 @@ static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons *pixels = (void *)((Uint8 *)bitmapData + rect->y * bitmapPitch + rect->x * 2); // 2 bytes per pixel for EColor4K *pitch = bitmapPitch; + + // Store the lock rectangle for dirty tracking. + phdata->dirtyRect = *rect; + return true; } static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { + NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; + + if (phdata) { + // Mark texture as dirty after unlock (assume it was modified). + phdata->isDirty = true; + } } static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 47ba9fbf9a..d80f9929e1 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -69,6 +69,14 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data) if (data) { delete data->bitmap; data->bitmap = NULL; + + // Free cardinal rotation cache. + for (int i = 0; i < 4; i++) { + if (data->cardinalRotations[i]) { + delete data->cardinalRotations[i]; + data->cardinalRotations[i] = NULL; + } + } } } @@ -160,7 +168,7 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1) {} CRenderer::~CRenderer() { @@ -361,6 +369,94 @@ bool CRenderer::EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight) return true; } +void CRenderer::BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf) +{ + // Build lookup tables for R, G, B channels. + for (int i = 0; i < 256; i++) { + TFixed val = i << 16; // Convert to fixed-point + iColorModLUT[i] = (TUint8)SDL_min(Fix2Int(FixMul(val, rf)), 255); // R + iColorModLUT[i + 256] = (TUint8)SDL_min(Fix2Int(FixMul(val, gf)), 255); // G + iColorModLUT[i + 512] = (TUint8)SDL_min(Fix2Int(FixMul(val, bf)), 255); // B + } + + // Remember the last color to avoid rebuilding unnecessarily. + iLastColorR = rf; + iLastColorG = gf; + iLastColorB = bf; +} + +CFbsBitmap* CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex) +{ + // Check if already cached. + if (aTextureData->cardinalRotations[aAngleIndex]) { + return aTextureData->cardinalRotations[aAngleIndex]; + } + + // Create rotated bitmap. + CFbsBitmap *rotated = new CFbsBitmap(); + if (!rotated) { + return NULL; + } + + TInt w = aTextureData->cachedWidth; + TInt h = aTextureData->cachedHeight; + TSize size(w, h); + + // For 90 and 270 degree rotations, swap width/height. + if (aAngleIndex == 1 || aAngleIndex == 3) { + size = TSize(h, w); + } + + TInt error = rotated->Create(size, EColor4K); + if (error != KErrNone) { + delete rotated; + return NULL; + } + + // Rotate the bitmap data. + TUint16 *src = (TUint16 *)aTextureData->cachedDataAddress; + TUint16 *dst = (TUint16 *)rotated->DataAddress(); + TInt srcPitch = aTextureData->cachedPitch >> 1; + TInt dstPitch = rotated->ScanLineLength(size.iWidth, rotated->DisplayMode()) >> 1; + + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + TUint16 pixel = src[y * srcPitch + x]; + int dstX = 0; + int dstY = 0; + + switch (aAngleIndex) { + case 0: // 0 degrees + dstX = x; + dstY = y; + break; + case 1: // 90 degrees + dstX = h - 1 - y; + dstY = x; + break; + case 2: // 180 degrees + dstX = w - 1 - x; + dstY = h - 1 - y; + break; + case 3: // 270 degrees + dstX = y; + dstY = w - 1 - x; + break; + default: + // Should never happen, but initialize to avoid warnings + dstX = x; + dstY = y; + break; + } + + dst[dstY * dstPitch + dstX] = pixel; + } + } + + aTextureData->cardinalRotations[aAngleIndex] = rotated; + return rotated; +} + #ifdef __cplusplus extern "C" { #endif @@ -444,7 +540,16 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec bool useBuffer1 = true; if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { - ApplyColorMod(dest, source, pitch, w, h, texture->color); + TFixed rf = Real2Fix(c->r); + TFixed gf = Real2Fix(c->g); + TFixed bf = Real2Fix(c->b); + + // Build LUT if color changed. + if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) { + BuildColorModLUT(rf, gf, bf); + } + + ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); source = dest; useBuffer1 = !useBuffer1; } @@ -486,6 +591,39 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE SDL_FColor *c = &texture->color; + // Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). + TInt angleIndex = -1; + TFixed angle = copydata->angle; + + if (!copydata->flip && + copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1) && + c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + + // Convert angle to degrees and check if it's a cardinal angle. + // Angle is in fixed-point radians: 0, Ï€/2, Ï€, 3Ï€/2 + TFixed zero = 0; + TFixed pi_2 = Real2Fix(M_PI / 2.0); + TFixed pi = Real2Fix(M_PI); + TFixed pi3_2 = Real2Fix(3.0 * M_PI / 2.0); + TFixed pi2 = Real2Fix(2.0 * M_PI); + + if (angle == zero) angleIndex = 0; + else if (SDL_abs(angle - pi_2) < 100) angleIndex = 1; // 90° + else if (SDL_abs(angle - pi) < 100) angleIndex = 2; // 180° + else if (SDL_abs(angle - pi3_2) < 100) angleIndex = 3; // 270° + else if (SDL_abs(angle - pi2) < 100) angleIndex = 0; // 360° = 0° + + if (angleIndex >= 0) { + CFbsBitmap *cached = GetCardinalRotation(phdata, angleIndex); + if (cached) { + TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); + iRenderer->Gc()->BitBlt(aDest, cached, aSource); + return true; + } + } + } + // Fast path: No transformations needed; direct BitBlt. if (!copydata->flip && copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1) && @@ -538,8 +676,17 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { + TFixed rf = Real2Fix(c->r); + TFixed gf = Real2Fix(c->g); + TFixed bf = Real2Fix(c->b); + + // Build LUT if color changed. + if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) { + BuildColorModLUT(rf, gf, bf); + } + dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; - ApplyColorMod(dest, source, pitch, w, h, texture->color); + ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); source = dest; useBuffer1 = !useBuffer1; } @@ -585,6 +732,18 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW aTextureData->cachedPitch = aTextureData->bitmap->ScanLineLength(aWidth, aTextureData->bitmap->DisplayMode()); aTextureData->cachedDataAddress = aTextureData->bitmap->DataAddress(); + // Initialize cardinal rotation cache to NULL. + for (int i = 0; i < 4; i++) { + aTextureData->cardinalRotations[i] = NULL; + } + + // Initialize dirty tracking. + aTextureData->isDirty = true; // New textures start dirty + aTextureData->dirtyRect.x = 0; + aTextureData->dirtyRect.y = 0; + aTextureData->dirtyRect.w = aWidth; + aTextureData->dirtyRect.h = aHeight; + return true; } diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index 4d56e472ca..fa87a34f30 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -65,6 +65,13 @@ typedef struct NGAGE_TextureData int cachedPitch; void *cachedDataAddress; + // Cardinal rotation cache (0°, 90°, 180°, 270°) - created on demand. + CFbsBitmap *cardinalRotations[4]; + + // Dirty tracking to avoid redundant rendering. + bool isDirty; + SDL_Rect dirtyRect; + } NGAGE_TextureData; typedef struct NGAGE_CopyExData diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 600d4d0622..ae27edbaf9 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -23,6 +23,7 @@ #define ngage_video_render_ngage_c_hpp #include "SDL_render_ngage_c.h" +#include <3dtypes.h> #include #include #include @@ -97,9 +98,17 @@ class CRenderer : public MDirectScreenAccess TInt iTempRenderBitmapWidth; TInt iTempRenderBitmapHeight; + // Color modulation lookup tables (pre-calculated to avoid per-pixel FixMul). + TUint8 iColorModLUT[768]; // 256 entries each for R, G, B + TFixed iLastColorR; + TFixed iLastColorG; + TFixed iLastColorB; + // Helper methods. bool EnsureWorkBufferCapacity(TInt aRequiredSize); bool EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight); + void BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf); + CFbsBitmap *GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex); }; #endif // ngage_video_render_ngage_c_hpp diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 89006e662c..fda9ecfb96 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -23,30 +23,58 @@ #include "SDL_render_ops.hpp" #include <3dtypes.h> -void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color) +void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color, const TUint8 *colorLUT) { TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - TFixed rf = Real2Fix(color.r); - TFixed gf = Real2Fix(color.g); - TFixed bf = Real2Fix(color.b); - // Pre-calculate pitch in pixels to avoid repeated division. const TInt pitchPixels = pitch >> 1; + const int totalPixels = width * height; + // Process 4 pixels at a time (loop unrolling). + int pixelIndex = 0; for (int y = 0; y < height; ++y) { - // Calculate row offset once per row. TInt rowOffset = y * pitchPixels; + int x = 0; - for (int x = 0; x < width; ++x) { + // Unrolled loop: process 4 pixels at once. + for (; x < width - 3; x += 4) { + // Pixel 0 + TUint16 p0 = src_pixels[rowOffset + x]; + TUint8 r0 = colorLUT[(p0 & 0xF800) >> 8]; + TUint8 g0 = colorLUT[256 + ((p0 & 0x07E0) >> 3)]; + TUint8 b0 = colorLUT[512 + ((p0 & 0x001F) << 3)]; + dst_pixels[rowOffset + x] = (r0 << 8) | (g0 << 3) | (b0 >> 3); + + // Pixel 1 + TUint16 p1 = src_pixels[rowOffset + x + 1]; + TUint8 r1 = colorLUT[(p1 & 0xF800) >> 8]; + TUint8 g1 = colorLUT[256 + ((p1 & 0x07E0) >> 3)]; + TUint8 b1 = colorLUT[512 + ((p1 & 0x001F) << 3)]; + dst_pixels[rowOffset + x + 1] = (r1 << 8) | (g1 << 3) | (b1 >> 3); + + // Pixel 2 + TUint16 p2 = src_pixels[rowOffset + x + 2]; + TUint8 r2 = colorLUT[(p2 & 0xF800) >> 8]; + TUint8 g2 = colorLUT[256 + ((p2 & 0x07E0) >> 3)]; + TUint8 b2 = colorLUT[512 + ((p2 & 0x001F) << 3)]; + dst_pixels[rowOffset + x + 2] = (r2 << 8) | (g2 << 3) | (b2 >> 3); + + // Pixel 3 + TUint16 p3 = src_pixels[rowOffset + x + 3]; + TUint8 r3 = colorLUT[(p3 & 0xF800) >> 8]; + TUint8 g3 = colorLUT[256 + ((p3 & 0x07E0) >> 3)]; + TUint8 b3 = colorLUT[512 + ((p3 & 0x001F) << 3)]; + dst_pixels[rowOffset + x + 3] = (r3 << 8) | (g3 << 3) | (b3 >> 3); + } + + // Handle remaining pixels. + for (; x < width; ++x) { TUint16 pixel = src_pixels[rowOffset + x]; - TUint8 r = (pixel & 0xF800) >> 8; - TUint8 g = (pixel & 0x07E0) >> 3; - TUint8 b = (pixel & 0x001F) << 3; - r = FixMul(r, rf); - g = FixMul(g, gf); - b = FixMul(b, bf); + TUint8 r = colorLUT[(pixel & 0xF800) >> 8]; + TUint8 g = colorLUT[256 + ((pixel & 0x07E0) >> 3)]; + TUint8 b = colorLUT[512 + ((pixel & 0x001F) << 3)]; dst_pixels[rowOffset + x] = (r << 8) | (g << 3) | (b >> 3); } } @@ -57,20 +85,40 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); + // Pre-calculate pitch in pixels to avoid repeated division. + const TInt pitchPixels = pitch >> 1; + + // Pre-calculate flip flags to avoid repeated bitwise operations. + const bool flipHorizontal = (flip & SDL_FLIP_HORIZONTAL) != 0; + const bool flipVertical = (flip & SDL_FLIP_VERTICAL) != 0; + for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - int src_x = x; - int src_y = y; + // Calculate destination row offset once per row. + TInt dstRowOffset = y * pitchPixels; - if (flip & SDL_FLIP_HORIZONTAL) { - src_x = width - 1 - x; - } + // Calculate source Y coordinate once per row. + int src_y = flipVertical ? (height - 1 - y) : y; + TInt srcRowOffset = src_y * pitchPixels; - if (flip & SDL_FLIP_VERTICAL) { - src_y = height - 1 - y; - } + int x = 0; - dst_pixels[y * pitch / 2 + x] = src_pixels[src_y * pitch / 2 + src_x]; + // Unrolled loop: process 4 pixels at once. + for (; x < width - 3; x += 4) { + int src_x0 = flipHorizontal ? (width - 1 - x) : x; + int src_x1 = flipHorizontal ? (width - 2 - x) : (x + 1); + int src_x2 = flipHorizontal ? (width - 3 - x) : (x + 2); + int src_x3 = flipHorizontal ? (width - 4 - x) : (x + 3); + + dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + src_x0]; + dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + src_x1]; + dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + src_x2]; + dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + src_x3]; + } + + // Handle remaining pixels. + for (; x < width; ++x) { + int src_x = flipHorizontal ? (width - 1 - x) : x; + dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + src_x]; } } } @@ -132,25 +180,67 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); + // Pre-calculate pitch in pixels to avoid repeated division. + const TInt pitchPixels = pitch >> 1; + for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - // Translate point to origin. + // Calculate destination row offset once per row. + TInt dstRowOffset = y * pitchPixels; + + // Pre-calculate translated_y for the entire row. + TFixed translated_y = Int2Fix(y) - center_y; + TFixed scaled_y = FixDiv(translated_y, scale_y); + int final_y = Fix2Int(scaled_y + center_y); + + // Check if this row is within bounds. + bool rowInBounds = (final_y >= 0 && final_y < height); + TInt srcRowOffset = final_y * pitchPixels; + + int x = 0; + + // Unrolled loop: process 4 pixels at once. + for (; x < width - 3; x += 4) { + // Pixel 0 + TFixed translated_x0 = Int2Fix(x) - center_x; + TFixed scaled_x0 = FixDiv(translated_x0, scale_x); + int final_x0 = Fix2Int(scaled_x0 + center_x); + + // Pixel 1 + TFixed translated_x1 = Int2Fix(x + 1) - center_x; + TFixed scaled_x1 = FixDiv(translated_x1, scale_x); + int final_x1 = Fix2Int(scaled_x1 + center_x); + + // Pixel 2 + TFixed translated_x2 = Int2Fix(x + 2) - center_x; + TFixed scaled_x2 = FixDiv(translated_x2, scale_x); + int final_x2 = Fix2Int(scaled_x2 + center_x); + + // Pixel 3 + TFixed translated_x3 = Int2Fix(x + 3) - center_x; + TFixed scaled_x3 = FixDiv(translated_x3, scale_x); + int final_x3 = Fix2Int(scaled_x3 + center_x); + + // Write all 4 pixels + dst_pixels[dstRowOffset + x] = (rowInBounds && final_x0 >= 0 && final_x0 < width) ? + src_pixels[srcRowOffset + final_x0] : 0; + dst_pixels[dstRowOffset + x + 1] = (rowInBounds && final_x1 >= 0 && final_x1 < width) ? + src_pixels[srcRowOffset + final_x1] : 0; + dst_pixels[dstRowOffset + x + 2] = (rowInBounds && final_x2 >= 0 && final_x2 < width) ? + src_pixels[srcRowOffset + final_x2] : 0; + dst_pixels[dstRowOffset + x + 3] = (rowInBounds && final_x3 >= 0 && final_x3 < width) ? + src_pixels[srcRowOffset + final_x3] : 0; + } + + // Handle remaining pixels. + for (; x < width; ++x) { TFixed translated_x = Int2Fix(x) - center_x; - TFixed translated_y = Int2Fix(y) - center_y; - - // Scale point. TFixed scaled_x = FixDiv(translated_x, scale_x); - TFixed scaled_y = FixDiv(translated_y, scale_y); - - // Translate point back. int final_x = Fix2Int(scaled_x + center_x); - int final_y = Fix2Int(scaled_y + center_y); - // Check bounds. - if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { - dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x]; + if (rowInBounds && final_x >= 0 && final_x < width) { + dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + final_x]; } else { - dst_pixels[y * pitch / 2 + x] = 0; + dst_pixels[dstRowOffset + x] = 0; } } } diff --git a/src/render/ngage/SDL_render_ops.hpp b/src/render/ngage/SDL_render_ops.hpp index 65e92e5bca..ae580f65e7 100644 --- a/src/render/ngage/SDL_render_ops.hpp +++ b/src/render/ngage/SDL_render_ops.hpp @@ -24,7 +24,7 @@ #include <3dtypes.h> -void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color); +void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color, const TUint8 *colorLUT); void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_FlipMode flip); void ApplyRotation(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle); void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y); From 08285d828efcb03c2c373289810ab62d4487a7a2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 10 Apr 2026 01:00:02 +0100 Subject: [PATCH 116/407] policy: Added to the PR template, and an AGENTS.md, refusing AI contributions. Fixes #15350. --- .github/PULL_REQUEST_TEMPLATE.md | 9 +++++++++ AGENTS.md | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 AGENTS.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 533be8573d..f66bf697d1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,12 @@ + + + ## Description diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..58ac294068 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,11 @@ +The SDL project does not accept contributions that are in any part created by +AI agents. + +We reject any pull requests that have any amount of code generated by an LLM, +generative AI, or anything other than a human being. + +Any code that was produced this way must be disclosed when submitting it to +the project. + +Thank you! + From 4711119605651549950c244137eedfba6d66b91c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Apr 2026 10:11:19 +0100 Subject: [PATCH 117/407] policy: Updated AI-related text based on excellent feedback. --- .github/PULL_REQUEST_TEMPLATE.md | 9 +-------- AGENTS.md | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f66bf697d1..b210acaa95 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,4 @@ - - +- [ ] I confirm that I am the author of this code and release it to the SDL project under the Zlib license. This contribution does not contain code from other sources, including AI generated code. diff --git a/AGENTS.md b/AGENTS.md index 58ac294068..93842ddbb5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,11 +1,17 @@ -The SDL project does not accept contributions that are in any part created by -AI agents. +AI may not be used to generate code for contributions to this project. -We reject any pull requests that have any amount of code generated by an LLM, -generative AI, or anything other than a human being. +AI-generated code is based upon sources of unknown origins and may not be +compatible with the Zlib license, or may introduce conflicting license terms +if they include code from other projects. -Any code that was produced this way must be disclosed when submitting it to -the project. +AI can be used to identify issues with contributions to this project, but the +solutions to those issues should be authored by humans. -Thank you! +We have found that AI will frequently hallucinate issues that are not actually +problems in practice, report incorrect information, and describe problems that +are actually not issues at all. If AI identifies a problem with this codebase, +please make sure you understand what it is saying and have independently +confirmed that the issue exists before submitting a bug report or pull request. +Any pull request to this project will ask you to confirm that you are the +author and that you are contributing your changes under the Zlib license. From 954e2f33541afbb55f02450ed6cf6c1f418a3ab6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 12 Apr 2026 15:34:30 +0200 Subject: [PATCH 118/407] policy: Clarify that "AI" means specific things. --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- AGENTS.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b210acaa95..5fd28bcd23 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,4 @@ -- [ ] I confirm that I am the author of this code and release it to the SDL project under the Zlib license. This contribution does not contain code from other sources, including AI generated code. +- [ ] I confirm that I am the author of this code and release it to the SDL project under the Zlib license. This contribution does not contain code from other sources, including code generated by a Large Language Model ("AI"). diff --git a/AGENTS.md b/AGENTS.md index 93842ddbb5..cc5ac33845 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,8 @@ AI may not be used to generate code for contributions to this project. +"AI" in this case means a Large Language Model ("LLM"), such as ChatGPT, +Claude, Copilot, Grok, etc. + AI-generated code is based upon sources of unknown origins and may not be compatible with the Zlib license, or may introduce conflicting license terms if they include code from other projects. From 30522e859885e1ef1c9f1ff5c74135e81b5a6997 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 15 Apr 2026 21:34:59 +0200 Subject: [PATCH 119/407] [N-Gage] Optimize renderer even further - Replace FixDiv with inverse scale factors in ApplyScale - Improve incremental DDA in ApplyRotation - Optimize ApplyColorMod bit manipulation and LUT addressing - Batch color changes in DrawPoints and FillRects to reduce API overhead - Add early-exit optimizations to Copy/CopyEx for common cases - Streamline Flip function by removing unnecessary API calls - Fix vertex indexing bug in FillRects --- src/render/ngage/SDL_render_ngage.cpp | 120 +++++++++------ src/render/ngage/SDL_render_ops.cpp | 212 ++++++++++++++++---------- 2 files changed, 205 insertions(+), 127 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index d80f9929e1..95eae3f1c7 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -505,20 +505,26 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec SDL_FColor *c = &texture->color; - // Get render scale. + // Fast path 1: No transformations needed; direct BitBlt. + if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + // Get render scale. + float sx; + float sy; + SDL_GetRenderScale(renderer, &sx, &sy); + + if (sx == 1.f && sy == 1.f) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } + } + + // Get render scale (moved here to avoid redundant call in fast path). float sx; float sy; SDL_GetRenderScale(renderer, &sx, &sy); - // Fast path: No transformations needed; direct BitBlt. - if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f && - sx == 1.f && sy == 1.f) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; - } - // Slow path: Transformations needed. int w = phdata->cachedWidth; int h = phdata->cachedHeight; @@ -591,16 +597,18 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE SDL_FColor *c = &texture->color; - // Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). - TInt angleIndex = -1; - TFixed angle = copydata->angle; + // Pre-calculate common checks. + const bool isIdentityScale = (copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1)); + const bool isNoRotation = (copydata->angle == 0); + const bool isNoFlip = (!copydata->flip); + const bool isNoColorMod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f); - if (!copydata->flip && - copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1) && - c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + // Fast path 1: Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). + if (isNoFlip && isIdentityScale && isNoColorMod && !isNoRotation) { + TInt angleIndex = -1; + TFixed angle = copydata->angle; // Convert angle to degrees and check if it's a cardinal angle. - // Angle is in fixed-point radians: 0, Ï€/2, Ï€, 3Ï€/2 TFixed zero = 0; TFixed pi_2 = Real2Fix(M_PI / 2.0); TFixed pi = Real2Fix(M_PI); @@ -624,11 +632,8 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } } - // Fast path: No transformations needed; direct BitBlt. - if (!copydata->flip && - copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1) && - copydata->angle == 0 && - c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + // Fast path 2: No transformations needed; direct BitBlt. + if (isNoFlip && isIdentityScale && isNoRotation && isNoColorMod) { TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); @@ -661,7 +666,7 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE useBuffer1 = !useBuffer1; } - if (copydata->scale_x != Int2Fix(1) || copydata->scale_y != Int2Fix(1)) { + if (!isIdentityScale) { dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); source = dest; @@ -675,7 +680,7 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE useBuffer1 = !useBuffer1; } - if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { + if (!isNoColorMod) { TFixed rf = Real2Fix(c->r); TFixed gf = Real2Fix(c->g); TFixed bf = Real2Fix(c->b); @@ -771,13 +776,23 @@ void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount) void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { + // Batch points by color to minimize SetPenColor calls. + TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + bool colorSet = false; + for (TInt i = 0; i < aCount; i++, aVerts++) { TUint32 aColor = (((TUint8)aVerts->color.a << 24) | ((TUint8)aVerts->color.b << 16) | ((TUint8)aVerts->color.g << 8) | (TUint8)aVerts->color.r); - iRenderer->Gc()->SetPenColor(aColor); + // Only set pen color when it changes. + if (!colorSet || aColor != currentColor) { + iRenderer->Gc()->SetPenColor(aColor); + currentColor = aColor; + colorSet = true; + } + iRenderer->Gc()->Plot(TPoint(aVerts->x, aVerts->y)); } } @@ -786,20 +801,29 @@ void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { - for (TInt i = 0; i < aCount; i++, aVerts++) { + // Batch rectangles by color to minimize SetPenColor/SetBrushColor calls. + TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + bool colorSet = false; + + // Process rectangles (each rect uses 2 vertices: position and size). + for (TInt i = 0; i < aCount; i += 2) { TPoint pos(aVerts[i].x, aVerts[i].y); - TSize size( - aVerts[i + 1].x, - aVerts[i + 1].y); + TSize size(aVerts[i + 1].x, aVerts[i + 1].y); TRect rect(pos, size); - TUint32 aColor = (((TUint8)aVerts->color.a << 24) | - ((TUint8)aVerts->color.b << 16) | - ((TUint8)aVerts->color.g << 8) | - (TUint8)aVerts->color.r); + TUint32 aColor = (((TUint8)aVerts[i].color.a << 24) | + ((TUint8)aVerts[i].color.b << 16) | + ((TUint8)aVerts[i].color.g << 8) | + (TUint8)aVerts[i].color.r); + + // Only set colors when they change. + if (!colorSet || aColor != currentColor) { + iRenderer->Gc()->SetPenColor(aColor); + iRenderer->Gc()->SetBrushColor(aColor); + currentColor = aColor; + colorSet = true; + } - iRenderer->Gc()->SetPenColor(aColor); - iRenderer->Gc()->SetBrushColor(aColor); iRenderer->Gc()->DrawRect(rect); } } @@ -816,38 +840,36 @@ void CRenderer::Flip() return; } - iRenderer->Gc()->UseFont(iFont); - if (iShowFPS && iRenderer->Gc()) { UpdateFPS(); + iRenderer->Gc()->UseFont(iFont); + TBuf<64> info; iRenderer->Gc()->SetPenStyle(CGraphicsContext::ESolidPen); - iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ENullBrush); - iRenderer->Gc()->SetPenColor(KRgbCyan); - - TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2)); iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush); iRenderer->Gc()->SetBrushColor(KRgbBlack); + iRenderer->Gc()->SetPenColor(KRgbCyan); + + // Draw FPS background and text. + TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2)); iRenderer->Gc()->DrawRect(aTextRect); - // Draw messages. info.Format(_L("FPS: %d"), iFPS); iRenderer->Gc()->DrawText(info, TPoint(5, 203)); - } else { - // This is a workaround that helps regulating the FPS. - iRenderer->Gc()->DrawText(_L(""), TPoint(0, 0)); + + iRenderer->Gc()->DiscardFont(); } - iRenderer->Gc()->DiscardFont(); + iRenderer->Flip(iDirectScreen); - // Keep the backlight on. + // Keep the backlight on when screen saver is suspended. if (iSuspendScreenSaver) { User::ResetInactivityTime(); } - // Suspend the current thread for a short while. - // Give some time to other threads and active objects. + + // Yield to other threads and active objects briefly. User::After(0); } diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index fda9ecfb96..92f28cd2a1 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -30,52 +30,58 @@ void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, S // Pre-calculate pitch in pixels to avoid repeated division. const TInt pitchPixels = pitch >> 1; - const int totalPixels = width * height; + + // Pre-calculate LUT offsets to reduce addressing calculations. + const TUint8 *lut_r = colorLUT; + const TUint8 *lut_g = colorLUT + 256; + const TUint8 *lut_b = colorLUT + 512; // Process 4 pixels at a time (loop unrolling). - int pixelIndex = 0; for (int y = 0; y < height; ++y) { - TInt rowOffset = y * pitchPixels; + const TInt rowOffset = y * pitchPixels; int x = 0; - // Unrolled loop: process 4 pixels at once. + // Unrolled loop: process 4 pixels at once with optimized bit manipulation. for (; x < width - 3; x += 4) { - // Pixel 0 + // Load 4 pixels at once. TUint16 p0 = src_pixels[rowOffset + x]; - TUint8 r0 = colorLUT[(p0 & 0xF800) >> 8]; - TUint8 g0 = colorLUT[256 + ((p0 & 0x07E0) >> 3)]; - TUint8 b0 = colorLUT[512 + ((p0 & 0x001F) << 3)]; - dst_pixels[rowOffset + x] = (r0 << 8) | (g0 << 3) | (b0 >> 3); + TUint16 p1 = src_pixels[rowOffset + x + 1]; + TUint16 p2 = src_pixels[rowOffset + x + 2]; + TUint16 p3 = src_pixels[rowOffset + x + 3]; + + // Pixel 0: Extract and modulate RGB4444 components. + // RGB4444 format: RRRR GGGG BBBB xxxx + TUint8 r0 = lut_r[(p0 >> 8) & 0xF0]; // Extract R (bits 12-15), shift to byte position + TUint8 g0 = lut_g[(p0 >> 3) & 0xF8]; // Extract G (bits 6-9), scale to 8-bit + TUint8 b0 = lut_b[(p0 << 3) & 0xF8]; // Extract B (bits 0-3), scale to 8-bit + dst_pixels[rowOffset + x] = ((r0 & 0xF0) << 8) | ((g0 & 0xF0) << 3) | ((b0 & 0xF0) >> 1); // Pixel 1 - TUint16 p1 = src_pixels[rowOffset + x + 1]; - TUint8 r1 = colorLUT[(p1 & 0xF800) >> 8]; - TUint8 g1 = colorLUT[256 + ((p1 & 0x07E0) >> 3)]; - TUint8 b1 = colorLUT[512 + ((p1 & 0x001F) << 3)]; - dst_pixels[rowOffset + x + 1] = (r1 << 8) | (g1 << 3) | (b1 >> 3); + TUint8 r1 = lut_r[(p1 >> 8) & 0xF0]; + TUint8 g1 = lut_g[(p1 >> 3) & 0xF8]; + TUint8 b1 = lut_b[(p1 << 3) & 0xF8]; + dst_pixels[rowOffset + x + 1] = ((r1 & 0xF0) << 8) | ((g1 & 0xF0) << 3) | ((b1 & 0xF0) >> 1); // Pixel 2 - TUint16 p2 = src_pixels[rowOffset + x + 2]; - TUint8 r2 = colorLUT[(p2 & 0xF800) >> 8]; - TUint8 g2 = colorLUT[256 + ((p2 & 0x07E0) >> 3)]; - TUint8 b2 = colorLUT[512 + ((p2 & 0x001F) << 3)]; - dst_pixels[rowOffset + x + 2] = (r2 << 8) | (g2 << 3) | (b2 >> 3); + TUint8 r2 = lut_r[(p2 >> 8) & 0xF0]; + TUint8 g2 = lut_g[(p2 >> 3) & 0xF8]; + TUint8 b2 = lut_b[(p2 << 3) & 0xF8]; + dst_pixels[rowOffset + x + 2] = ((r2 & 0xF0) << 8) | ((g2 & 0xF0) << 3) | ((b2 & 0xF0) >> 1); // Pixel 3 - TUint16 p3 = src_pixels[rowOffset + x + 3]; - TUint8 r3 = colorLUT[(p3 & 0xF800) >> 8]; - TUint8 g3 = colorLUT[256 + ((p3 & 0x07E0) >> 3)]; - TUint8 b3 = colorLUT[512 + ((p3 & 0x001F) << 3)]; - dst_pixels[rowOffset + x + 3] = (r3 << 8) | (g3 << 3) | (b3 >> 3); + TUint8 r3 = lut_r[(p3 >> 8) & 0xF0]; + TUint8 g3 = lut_g[(p3 >> 3) & 0xF8]; + TUint8 b3 = lut_b[(p3 << 3) & 0xF8]; + dst_pixels[rowOffset + x + 3] = ((r3 & 0xF0) << 8) | ((g3 & 0xF0) << 3) | ((b3 & 0xF0) >> 1); } // Handle remaining pixels. for (; x < width; ++x) { TUint16 pixel = src_pixels[rowOffset + x]; - TUint8 r = colorLUT[(pixel & 0xF800) >> 8]; - TUint8 g = colorLUT[256 + ((pixel & 0x07E0) >> 3)]; - TUint8 b = colorLUT[512 + ((pixel & 0x001F) << 3)]; - dst_pixels[rowOffset + x] = (r << 8) | (g << 3) | (b >> 3); + TUint8 r = lut_r[(pixel >> 8) & 0xF0]; + TUint8 g = lut_g[(pixel >> 3) & 0xF8]; + TUint8 b = lut_b[(pixel << 3) & 0xF8]; + dst_pixels[rowOffset + x] = ((r & 0xF0) << 8) | ((g & 0xF0) << 3) | ((b & 0xF0) >> 1); } } } @@ -92,32 +98,38 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F const bool flipHorizontal = (flip & SDL_FLIP_HORIZONTAL) != 0; const bool flipVertical = (flip & SDL_FLIP_VERTICAL) != 0; + // Pre-calculate width/height bounds for horizontal/vertical flipping. + const int width_m1 = width - 1; + const int height_m1 = height - 1; + for (int y = 0; y < height; ++y) { // Calculate destination row offset once per row. - TInt dstRowOffset = y * pitchPixels; + const TInt dstRowOffset = y * pitchPixels; // Calculate source Y coordinate once per row. - int src_y = flipVertical ? (height - 1 - y) : y; - TInt srcRowOffset = src_y * pitchPixels; + const int src_y = flipVertical ? (height_m1 - y) : y; + const TInt srcRowOffset = src_y * pitchPixels; int x = 0; // Unrolled loop: process 4 pixels at once. for (; x < width - 3; x += 4) { - int src_x0 = flipHorizontal ? (width - 1 - x) : x; - int src_x1 = flipHorizontal ? (width - 2 - x) : (x + 1); - int src_x2 = flipHorizontal ? (width - 3 - x) : (x + 2); - int src_x3 = flipHorizontal ? (width - 4 - x) : (x + 3); - - dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + src_x0]; - dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + src_x1]; - dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + src_x2]; - dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + src_x3]; + if (flipHorizontal) { + dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + (width_m1 - x)]; + dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + (width_m1 - x - 1)]; + dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + (width_m1 - x - 2)]; + dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + (width_m1 - x - 3)]; + } else { + dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + x]; + dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + x + 1]; + dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + x + 2]; + dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + x + 3]; + } } // Handle remaining pixels. for (; x < width; ++x) { - int src_x = flipHorizontal ? (width - 1 - x) : x; + const int src_x = flipHorizontal ? (width_m1 - x) : x; dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + src_x]; } } @@ -140,23 +152,65 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T // Incremental DDA: Calculate per-pixel increments. // As we move right (x+1), the rotated position changes by (cos, -sin). - TFixed dx_cos = cos_angle; - TFixed dx_sin = -sin_angle; + const TFixed dx_cos = cos_angle; + const TFixed dx_sin = -sin_angle; for (int y = 0; y < height; ++y) { // Calculate destination row offset once per row. - TInt dstRowOffset = y * pitchPixels; + const TInt dstRowOffset = y * pitchPixels; // Calculate starting position for this row. - TFixed translated_y = Int2Fix(y) - center_y; - TFixed row_start_x = FixMul(translated_y, sin_angle) + center_x; - TFixed row_start_y = FixMul(translated_y, cos_angle) + center_y; + // For y, rotation transforms: x' = x*cos - y*sin, y' = x*sin + y*cos + // At x=0: x' = -y*sin, y' = y*cos (relative to center) + const TFixed translated_y = Int2Fix(y) - center_y; + const TFixed row_start_x = center_x - FixMul(translated_y, sin_angle); + const TFixed row_start_y = center_y + FixMul(translated_y, cos_angle); - // For first pixel in row, account for x=0 translation. - TFixed src_x = row_start_x - FixMul(center_x, cos_angle); - TFixed src_y = row_start_y + FixMul(center_x, sin_angle); + // Start at x=0 position. + TFixed src_x = row_start_x; + TFixed src_y = row_start_y; - for (int x = 0; x < width; ++x) { + int x = 0; + + // Unrolled loop: process 4 pixels at once. + for (; x < width - 3; x += 4) { + // Pixel 0 + int final_x0 = Fix2Int(src_x); + int final_y0 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 1 + int final_x1 = Fix2Int(src_x); + int final_y1 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 2 + int final_x2 = Fix2Int(src_x); + int final_y2 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 3 + int final_x3 = Fix2Int(src_x); + int final_y3 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Write all 4 pixels with bounds checking. + dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? + src_pixels[final_y0 * pitchPixels + final_x0] : 0; + dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? + src_pixels[final_y1 * pitchPixels + final_x1] : 0; + dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? + src_pixels[final_y2 * pitchPixels + final_x2] : 0; + dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? + src_pixels[final_y3 * pitchPixels + final_x3] : 0; + } + + // Handle remaining pixels. + for (; x < width; ++x) { // Convert to integer coordinates. int final_x = Fix2Int(src_x); int final_y = Fix2Int(src_y); @@ -183,44 +237,47 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix // Pre-calculate pitch in pixels to avoid repeated division. const TInt pitchPixels = pitch >> 1; + // Pre-calculate inverse scale factors to use FixMul instead of FixDiv. + // This is MUCH faster on N-Gage hardware (no division per pixel!). + TFixed inv_scale_x = FixDiv(Int2Fix(1), scale_x); + TFixed inv_scale_y = FixDiv(Int2Fix(1), scale_y); + + // Pre-calculate center offset to reduce operations per pixel. + TFixed center_x_fixed = center_x; + TFixed center_y_fixed = center_y; + for (int y = 0; y < height; ++y) { // Calculate destination row offset once per row. TInt dstRowOffset = y * pitchPixels; - // Pre-calculate translated_y for the entire row. - TFixed translated_y = Int2Fix(y) - center_y; - TFixed scaled_y = FixDiv(translated_y, scale_y); - int final_y = Fix2Int(scaled_y + center_y); + // Use inverse scale factor (multiply instead of divide). + TFixed translated_y = Int2Fix(y) - center_y_fixed; + TFixed scaled_y = FixMul(translated_y, inv_scale_y); + int final_y = Fix2Int(scaled_y + center_y_fixed); // Check if this row is within bounds. bool rowInBounds = (final_y >= 0 && final_y < height); TInt srcRowOffset = final_y * pitchPixels; + // Incremental DDA for X: pre-calculate starting position and increment. + TFixed src_x_start = FixMul(-center_x_fixed, inv_scale_x) + center_x_fixed; + TFixed src_x = src_x_start; + int x = 0; // Unrolled loop: process 4 pixels at once. for (; x < width - 3; x += 4) { - // Pixel 0 - TFixed translated_x0 = Int2Fix(x) - center_x; - TFixed scaled_x0 = FixDiv(translated_x0, scale_x); - int final_x0 = Fix2Int(scaled_x0 + center_x); + // Process 4 pixels using incremental approach. + int final_x0 = Fix2Int(src_x); + src_x += inv_scale_x; + int final_x1 = Fix2Int(src_x); + src_x += inv_scale_x; + int final_x2 = Fix2Int(src_x); + src_x += inv_scale_x; + int final_x3 = Fix2Int(src_x); + src_x += inv_scale_x; - // Pixel 1 - TFixed translated_x1 = Int2Fix(x + 1) - center_x; - TFixed scaled_x1 = FixDiv(translated_x1, scale_x); - int final_x1 = Fix2Int(scaled_x1 + center_x); - - // Pixel 2 - TFixed translated_x2 = Int2Fix(x + 2) - center_x; - TFixed scaled_x2 = FixDiv(translated_x2, scale_x); - int final_x2 = Fix2Int(scaled_x2 + center_x); - - // Pixel 3 - TFixed translated_x3 = Int2Fix(x + 3) - center_x; - TFixed scaled_x3 = FixDiv(translated_x3, scale_x); - int final_x3 = Fix2Int(scaled_x3 + center_x); - - // Write all 4 pixels + // Write all 4 pixels with bounds checking. dst_pixels[dstRowOffset + x] = (rowInBounds && final_x0 >= 0 && final_x0 < width) ? src_pixels[srcRowOffset + final_x0] : 0; dst_pixels[dstRowOffset + x + 1] = (rowInBounds && final_x1 >= 0 && final_x1 < width) ? @@ -233,9 +290,8 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix // Handle remaining pixels. for (; x < width; ++x) { - TFixed translated_x = Int2Fix(x) - center_x; - TFixed scaled_x = FixDiv(translated_x, scale_x); - int final_x = Fix2Int(scaled_x + center_x); + int final_x = Fix2Int(src_x); + src_x += inv_scale_x; if (rowInBounds && final_x >= 0 && final_x < width) { dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + final_x]; From 5bda0ccfb06ea56c1f15a304927f2438c1300f95 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 15 Apr 2026 17:26:54 -0400 Subject: [PATCH 120/407] AGENTS.md: Change "may not" to "must not". (Hat tip to Sean Barrett on the stronger wording here.) --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index cc5ac33845..7709baa11a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,4 @@ -AI may not be used to generate code for contributions to this project. +AI must not be used to generate code for contributions to this project. "AI" in this case means a Large Language Model ("LLM"), such as ChatGPT, Claude, Copilot, Grok, etc. From c1bf0e9de9fe4a14bb834a368b624f281614e69b Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Thu, 16 Apr 2026 10:14:46 -0400 Subject: [PATCH 121/407] wayland: Fix some comments Fix grammar, and remove a TODO that is no longer relevant with an event thread. --- src/video/wayland/SDL_waylandevents.c | 4 +--- src/video/wayland/SDL_waylandkeyboard.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 05298cfa57..0f95d6d6a8 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -499,9 +499,7 @@ void Wayland_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window) { SDL_VideoData *d = _this->internal; - /* Queue a sync event to unblock the event queue fd if it's empty and being waited on. - * TODO: Maybe use a pipe to avoid the compositor roundtrip? - */ + // Queue a sync event to unblock the main event queue if it's being waited on. struct wl_callback *cb = wl_display_sync(d->display); wl_callback_add_listener(cb, &sync_listener, NULL); WAYLAND_wl_display_flush(d->display); diff --git a/src/video/wayland/SDL_waylandkeyboard.c b/src/video/wayland/SDL_waylandkeyboard.c index f604a7e3df..ac0558877d 100644 --- a/src/video/wayland/SDL_waylandkeyboard.c +++ b/src/video/wayland/SDL_waylandkeyboard.c @@ -186,7 +186,7 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop } /* Always return true, even if the text input protocol isn't supported, as basic - * text can still be obtained from individual keys and composition system. + * text can still be obtained from keysyms and the composition system. */ return true; } From 1124e44e4c66668a719147a2032c5e77015583c8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 16 Apr 2026 12:20:00 -0400 Subject: [PATCH 122/407] CLAUDE.md: added. Apparently Claude Code won't read AGENTS.md by default at this moment, but since that's the direction we're moving, let's just add the file Claude currently looks for and tell it that the actual instructions are in AGENTS.md. I thought these things were supposed to be less complicated that interacting with humans, lol. --- CLAUDE.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..cff53b6ab9 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,2 @@ +Hi, Claude! Please read our actual instructions in the AGENTS.md file. Thanks! + From 847fc72b1b4726255144e1c419090a0a38687632 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 16 Apr 2026 13:51:49 -0400 Subject: [PATCH 123/407] CLAUDE.md: Just copy the text from AGENTS.md in here for now. Someone mentioned that Claude sees this file's previous text and adds "look at AGENTS.md" to it's TODO list instead of treating it as the thing it should do first. If everything decides to prefer AGENTS.md at some point, we'll delete this file. A symlink would apparently also work, but it would be the only symlink in the SDL git repo, so it seemed less disruptive to just copy the file over for now. --- CLAUDE.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index cff53b6ab9..c8408cf2c1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,2 +1,22 @@ -Hi, Claude! Please read our actual instructions in the AGENTS.md file. Thanks! +AI must not be used to generate code for contributions to this project. + +"AI" in this case means a Large Language Model ("LLM"), such as ChatGPT, +Claude, Copilot, Grok, etc. + +AI-generated code is based upon sources of unknown origins and may not be +compatible with the Zlib license, or may introduce conflicting license terms +if they include code from other projects. + +AI can be used to identify issues with contributions to this project, but the +solutions to those issues should be authored by humans. + +We have found that AI will frequently hallucinate issues that are not actually +problems in practice, report incorrect information, and describe problems that +are actually not issues at all. If AI identifies a problem with this codebase, +please make sure you understand what it is saying and have independently +confirmed that the issue exists before submitting a bug report or pull request. + +Any pull request to this project will ask you to confirm that you are the +author and that you are contributing your changes under the Zlib license. + From b53b31b74a14cf7d36e2b1ce6fddcfed07f90621 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Thu, 16 Apr 2026 20:50:34 +0200 Subject: [PATCH 124/407] [N-Gage] Add various micro-optimizations to rendering back-end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add reusable line points buffer to eliminate per-call heap allocations in DrawLines. - Cache last draw color to skip redundant SetPenColor/SetBrushColor calls. - Pre-compute cardinal angle constants (0°, 90°, 180°, 270°) for CopyEx fast-path. - Cache color modulation state to avoid redundant LUT rebuilds. - Add missing break statement in HandleEvent. - Initialize previously uninitialized lastTime variable in UpdateFPS. --- src/render/ngage/SDL_render_ngage.cpp | 151 ++++++++++++++++-------- src/render/ngage/SDL_render_ngage_c.hpp | 8 ++ src/render/ngage/SDL_render_ops.cpp | 40 +++---- 3 files changed, 125 insertions(+), 74 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 95eae3f1c7..bf1d9b96ba 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -159,6 +159,15 @@ void NGAGE_SuspendScreenSaverInternal(bool suspend) } #endif +// Pre-calculated fixed-point angle constants for cardinal rotation checks. +// These avoid repeated Real2Fix conversions in CopyEx hot path. +static const TFixed kAngleZero = 0; +static const TFixed kAnglePi_2 = Real2Fix(M_PI / 2.0); // 90 degrees +static const TFixed kAnglePi = Real2Fix(M_PI); // 180 degrees +static const TFixed kAnglePi3_2 = Real2Fix(3.0 * M_PI / 2.0); // 270 degrees +static const TFixed kAnglePi2 = Real2Fix(2.0 * M_PI); // 360 degrees +static const TFixed kAngleTolerance = 100; // Tolerance for angle comparison + CRenderer *CRenderer::NewL() { CRenderer *self = new (ELeave) CRenderer(); @@ -168,7 +177,7 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0xFFFFFFFF) {} CRenderer::~CRenderer() { @@ -187,6 +196,11 @@ CRenderer::~CRenderer() iTempRenderBitmap = 0; iTempRenderBitmapWidth = 0; iTempRenderBitmapHeight = 0; + + // Free line points buffer. + delete[] iLinePointsBuffer; + iLinePointsBuffer = 0; + iLinePointsBufferCapacity = 0; } void CRenderer::ConstructL() @@ -335,10 +349,30 @@ bool CRenderer::EnsureWorkBufferCapacity(TInt aRequiredSize) return true; } +bool CRenderer::EnsureLinePointsCapacity(TInt aRequiredCount) +{ + if (aRequiredCount <= iLinePointsBufferCapacity) { + return true; + } + + // Free old buffer. + delete[] iLinePointsBuffer; + + // Allocate new buffer. + iLinePointsBuffer = new TPoint[aRequiredCount]; + if (!iLinePointsBuffer) { + iLinePointsBufferCapacity = 0; + return false; + } + + iLinePointsBufferCapacity = aRequiredCount; + return true; +} + bool CRenderer::EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight) { - if (iTempRenderBitmap && - iTempRenderBitmapWidth >= aWidth && + if (iTempRenderBitmap && + iTempRenderBitmapWidth >= aWidth && iTempRenderBitmapHeight >= aHeight) { return true; } @@ -373,10 +407,10 @@ void CRenderer::BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf) { // Build lookup tables for R, G, B channels. for (int i = 0; i < 256; i++) { - TFixed val = i << 16; // Convert to fixed-point - iColorModLUT[i] = (TUint8)SDL_min(Fix2Int(FixMul(val, rf)), 255); // R - iColorModLUT[i + 256] = (TUint8)SDL_min(Fix2Int(FixMul(val, gf)), 255); // G - iColorModLUT[i + 512] = (TUint8)SDL_min(Fix2Int(FixMul(val, bf)), 255); // B + TFixed val = i << 16; // Convert to fixed-point + iColorModLUT[i] = (TUint8)SDL_min(Fix2Int(FixMul(val, rf)), 255); // R + iColorModLUT[i + 256] = (TUint8)SDL_min(Fix2Int(FixMul(val, gf)), 255); // G + iColorModLUT[i + 512] = (TUint8)SDL_min(Fix2Int(FixMul(val, bf)), 255); // B } // Remember the last color to avoid rebuilding unnecessarily. @@ -385,7 +419,7 @@ void CRenderer::BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf) iLastColorB = bf; } -CFbsBitmap* CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex) +CFbsBitmap *CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex) { // Check if already cached. if (aTextureData->cardinalRotations[aAngleIndex]) { @@ -426,27 +460,27 @@ CFbsBitmap* CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt int dstY = 0; switch (aAngleIndex) { - case 0: // 0 degrees - dstX = x; - dstY = y; - break; - case 1: // 90 degrees - dstX = h - 1 - y; - dstY = x; - break; - case 2: // 180 degrees - dstX = w - 1 - x; - dstY = h - 1 - y; - break; - case 3: // 270 degrees - dstX = y; - dstY = w - 1 - x; - break; - default: - // Should never happen, but initialize to avoid warnings - dstX = x; - dstY = y; - break; + case 0: // 0 degrees + dstX = x; + dstY = y; + break; + case 1: // 90 degrees + dstX = h - 1 - y; + dstY = x; + break; + case 2: // 180 degrees + dstX = w - 1 - x; + dstY = h - 1 - y; + break; + case 3: // 270 degrees + dstX = y; + dstY = w - 1 - x; + break; + default: + // Should never happen, but initialize to avoid warnings + dstX = x; + dstY = y; + break; } dst[dstY * dstPitch + dstX] = pixel; @@ -608,18 +642,18 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE TInt angleIndex = -1; TFixed angle = copydata->angle; - // Convert angle to degrees and check if it's a cardinal angle. - TFixed zero = 0; - TFixed pi_2 = Real2Fix(M_PI / 2.0); - TFixed pi = Real2Fix(M_PI); - TFixed pi3_2 = Real2Fix(3.0 * M_PI / 2.0); - TFixed pi2 = Real2Fix(2.0 * M_PI); - - if (angle == zero) angleIndex = 0; - else if (SDL_abs(angle - pi_2) < 100) angleIndex = 1; // 90° - else if (SDL_abs(angle - pi) < 100) angleIndex = 2; // 180° - else if (SDL_abs(angle - pi3_2) < 100) angleIndex = 3; // 270° - else if (SDL_abs(angle - pi2) < 100) angleIndex = 0; // 360° = 0° + // Use pre-calculated angle constants for comparison. + if (angle == kAngleZero) { + angleIndex = 0; + } else if (SDL_abs(angle - kAnglePi_2) < kAngleTolerance) { + angleIndex = 1; // 90° + } else if (SDL_abs(angle - kAnglePi) < kAngleTolerance) { + angleIndex = 2; // 180° + } else if (SDL_abs(angle - kAnglePi3_2) < kAngleTolerance) { + angleIndex = 3; // 270° + } else if (SDL_abs(angle - kAnglePi2) < kAngleTolerance) { + angleIndex = 0; // 360° = 0° + } if (angleIndex >= 0) { CFbsBitmap *cached = GetCardinalRotation(phdata, angleIndex); @@ -743,7 +777,7 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW } // Initialize dirty tracking. - aTextureData->isDirty = true; // New textures start dirty + aTextureData->isDirty = true; // New textures start dirty. aTextureData->dirtyRect.x = 0; aTextureData->dirtyRect.y = 0; aTextureData->dirtyRect.w = aWidth; @@ -755,10 +789,14 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { - TPoint *aPoints = new TPoint[aCount]; + // Ensure reusable buffer has sufficient capacity. + if (!EnsureLinePointsCapacity(aCount)) { + return; + } + // Fill points from vertex data. for (TInt i = 0; i < aCount; i++) { - aPoints[i] = TPoint(aVerts[i].x, aVerts[i].y); + iLinePointsBuffer[i] = TPoint(aVerts[i].x, aVerts[i].y); } TUint32 aColor = (((TUint8)aVerts->color.a << 24) | @@ -767,9 +805,7 @@ void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount) (TUint8)aVerts->color.r); iRenderer->Gc()->SetPenColor(aColor); - iRenderer->Gc()->DrawPolyLineNoEndPoint(aPoints, aCount); - - delete[] aPoints; + iRenderer->Gc()->DrawPolyLineNoEndPoint(iLinePointsBuffer, aCount); } } @@ -777,7 +813,7 @@ void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { // Batch points by color to minimize SetPenColor calls. - TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color bool colorSet = false; for (TInt i = 0; i < aCount; i++, aVerts++) { @@ -802,7 +838,7 @@ void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { // Batch rectangles by color to minimize SetPenColor/SetBrushColor calls. - TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color bool colorSet = false; // Process rectangles (each rect uses 2 vertices: position and size). @@ -876,6 +912,11 @@ void CRenderer::Flip() void CRenderer::SetDrawColor(TUint32 iColor) { if (iRenderer && iRenderer->Gc()) { + // Skip redundant calls if color hasn't changed. + if (iColor == iLastDrawColor) { + return; + } + iRenderer->Gc()->SetPenColor(iColor); iRenderer->Gc()->SetBrushColor(iColor); iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush); @@ -884,6 +925,8 @@ void CRenderer::SetDrawColor(TUint32 iColor) if (err != KErrNone) { return; } + + iLastDrawColor = iColor; } } @@ -899,10 +942,17 @@ void CRenderer::UpdateFPS() { static TTime lastTime; static TInt frameCount = 0; + static TBool initialized = EFalse; TTime currentTime; - const TUint KOneSecond = 1000000; // 1s in ms. + const TUint KOneSecond = 1000000; // 1s in microseconds. currentTime.HomeTime(); + + if (!initialized) { + lastTime = currentTime; + initialized = ETrue; + } + ++frameCount; TTimeIntervalMicroSeconds timeDiff = currentTime.MicroSecondsFrom(lastTime); @@ -1022,6 +1072,7 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent) case EEventKeyUp: /* Key events */ timestamp = SDL_GetPerformanceCounter(); SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), false); + break; case EEventFocusGained: DisableKeyBlocking(); diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index ae27edbaf9..4b1d38ddcf 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -104,9 +104,17 @@ class CRenderer : public MDirectScreenAccess TFixed iLastColorG; TFixed iLastColorB; + // Reusable line points buffer to avoid per-frame allocations in DrawLines. + TPoint *iLinePointsBuffer; + TInt iLinePointsBufferCapacity; + + // Cached draw color to avoid redundant SetPenColor/SetBrushColor calls. + TUint32 iLastDrawColor; + // Helper methods. bool EnsureWorkBufferCapacity(TInt aRequiredSize); bool EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight); + bool EnsureLinePointsCapacity(TInt aRequiredCount); void BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf); CFbsBitmap *GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex); }; diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 92f28cd2a1..54fbddb900 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -36,12 +36,12 @@ void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, S const TUint8 *lut_g = colorLUT + 256; const TUint8 *lut_b = colorLUT + 512; - // Process 4 pixels at a time (loop unrolling). + // Process 4 pixels at a time. for (int y = 0; y < height; ++y) { const TInt rowOffset = y * pitchPixels; int x = 0; - // Unrolled loop: process 4 pixels at once with optimized bit manipulation. + // Process 4 pixels at once with optimized bit manipulation. for (; x < width - 3; x += 4) { // Load 4 pixels at once. TUint16 p0 = src_pixels[rowOffset + x]; @@ -51,9 +51,9 @@ void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, S // Pixel 0: Extract and modulate RGB4444 components. // RGB4444 format: RRRR GGGG BBBB xxxx - TUint8 r0 = lut_r[(p0 >> 8) & 0xF0]; // Extract R (bits 12-15), shift to byte position - TUint8 g0 = lut_g[(p0 >> 3) & 0xF8]; // Extract G (bits 6-9), scale to 8-bit - TUint8 b0 = lut_b[(p0 << 3) & 0xF8]; // Extract B (bits 0-3), scale to 8-bit + TUint8 r0 = lut_r[(p0 >> 8) & 0xF0]; // Extract R (bits 12-15), shift to byte position + TUint8 g0 = lut_g[(p0 >> 3) & 0xF8]; // Extract G (bits 6-9), scale to 8-bit + TUint8 b0 = lut_b[(p0 << 3) & 0xF8]; // Extract B (bits 0-3), scale to 8-bit dst_pixels[rowOffset + x] = ((r0 & 0xF0) << 8) | ((g0 & 0xF0) << 3) | ((b0 & 0xF0) >> 1); // Pixel 1 @@ -112,7 +112,7 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F int x = 0; - // Unrolled loop: process 4 pixels at once. + // Process 4 pixels at once. for (; x < width - 3; x += 4) { if (flipHorizontal) { dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + (width_m1 - x)]; @@ -172,7 +172,7 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T int x = 0; - // Unrolled loop: process 4 pixels at once. + // Process 4 pixels at once. for (; x < width - 3; x += 4) { // Pixel 0 int final_x0 = Fix2Int(src_x); @@ -199,14 +199,10 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T src_y += dx_sin; // Write all 4 pixels with bounds checking. - dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? - src_pixels[final_y0 * pitchPixels + final_x0] : 0; - dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? - src_pixels[final_y1 * pitchPixels + final_x1] : 0; - dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? - src_pixels[final_y2 * pitchPixels + final_x2] : 0; - dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? - src_pixels[final_y3 * pitchPixels + final_x3] : 0; + dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? src_pixels[final_y0 * pitchPixels + final_x0] : 0; + dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? src_pixels[final_y1 * pitchPixels + final_x1] : 0; + dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? src_pixels[final_y2 * pitchPixels + final_x2] : 0; + dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? src_pixels[final_y3 * pitchPixels + final_x3] : 0; } // Handle remaining pixels. @@ -265,7 +261,7 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix int x = 0; - // Unrolled loop: process 4 pixels at once. + // Process 4 pixels at once. for (; x < width - 3; x += 4) { // Process 4 pixels using incremental approach. int final_x0 = Fix2Int(src_x); @@ -278,14 +274,10 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix src_x += inv_scale_x; // Write all 4 pixels with bounds checking. - dst_pixels[dstRowOffset + x] = (rowInBounds && final_x0 >= 0 && final_x0 < width) ? - src_pixels[srcRowOffset + final_x0] : 0; - dst_pixels[dstRowOffset + x + 1] = (rowInBounds && final_x1 >= 0 && final_x1 < width) ? - src_pixels[srcRowOffset + final_x1] : 0; - dst_pixels[dstRowOffset + x + 2] = (rowInBounds && final_x2 >= 0 && final_x2 < width) ? - src_pixels[srcRowOffset + final_x2] : 0; - dst_pixels[dstRowOffset + x + 3] = (rowInBounds && final_x3 >= 0 && final_x3 < width) ? - src_pixels[srcRowOffset + final_x3] : 0; + dst_pixels[dstRowOffset + x] = (rowInBounds && final_x0 >= 0 && final_x0 < width) ? src_pixels[srcRowOffset + final_x0] : 0; + dst_pixels[dstRowOffset + x + 1] = (rowInBounds && final_x1 >= 0 && final_x1 < width) ? src_pixels[srcRowOffset + final_x1] : 0; + dst_pixels[dstRowOffset + x + 2] = (rowInBounds && final_x2 >= 0 && final_x2 < width) ? src_pixels[srcRowOffset + final_x2] : 0; + dst_pixels[dstRowOffset + x + 3] = (rowInBounds && final_x3 >= 0 && final_x3 < width) ? src_pixels[srcRowOffset + final_x3] : 0; } // Handle remaining pixels. From 87e356f102f0b85f87dbe265b2b57e2f0e1512a9 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Thu, 16 Apr 2026 21:09:58 +0200 Subject: [PATCH 125/407] [N-Gage] Simplify rendering back-end; more micro-optimization - Remove redundant null checks - Use cached texture properties instead of API calls (GetBitmapWidth/Height/Pitch) - Eliminate duplicate SDL_GetRenderScale() call in Copy() - Reorder CopyEx() fast paths to check no-transform case first - Combine operations in NGAGE_ConvertColor() to reduce intermediate steps --- src/render/ngage/SDL_render_ngage.cpp | 136 ++++++++++++-------------- 1 file changed, 60 insertions(+), 76 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index bf1d9b96ba..e9dcd547ab 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -82,7 +82,7 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data) void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data) { - if (data && data->bitmap) { + if (data) { return data->bitmap->DataAddress(); } return NULL; @@ -90,25 +90,24 @@ void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data) int NGAGE_GetBitmapPitch(NGAGE_TextureData *data) { - if (data && data->bitmap) { - TSize size = data->bitmap->SizeInPixels(); - return data->bitmap->ScanLineLength(size.iWidth, data->bitmap->DisplayMode()); + if (data) { + return data->cachedPitch; } return 0; } int NGAGE_GetBitmapWidth(NGAGE_TextureData *data) { - if (data && data->bitmap) { - return data->bitmap->SizeInPixels().iWidth; + if (data) { + return data->cachedWidth; } return 0; } int NGAGE_GetBitmapHeight(NGAGE_TextureData *data) { - if (data && data->bitmap) { - return data->bitmap->SizeInPixels().iHeight; + if (data) { + return data->cachedHeight; } return 0; } @@ -140,9 +139,7 @@ void NGAGE_SetClipRect(const SDL_Rect *rect) void NGAGE_SetDrawColor(const Uint32 color) { - if (gRenderer) { - gRenderer->SetDrawColor(color); - } + gRenderer->SetDrawColor(color); } void NGAGE_PumpEventsInternal() @@ -177,7 +174,9 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0xFFFFFFFF) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0) +{ +} CRenderer::~CRenderer() { @@ -505,13 +504,9 @@ Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale) TFixed bf = Real2Fix(b); TFixed af = Real2Fix(a); - rf = FixMul(rf, scalef); - gf = FixMul(gf, scalef); - bf = FixMul(bf, scalef); - - rf = SDL_clamp(rf, 0, ff); - gf = SDL_clamp(gf, 0, ff); - bf = SDL_clamp(bf, 0, ff); + rf = SDL_clamp(FixMul(rf, scalef), 0, ff); + gf = SDL_clamp(FixMul(gf, scalef), 0, ff); + bf = SDL_clamp(FixMul(bf, scalef), 0, ff); af = SDL_clamp(af, 0, ff); rf = FixMul(rf, ff) >> 16; @@ -539,26 +534,19 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec SDL_FColor *c = &texture->color; - // Fast path 1: No transformations needed; direct BitBlt. - if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { - // Get render scale. - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); - - if (sx == 1.f && sy == 1.f) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; - } - } - - // Get render scale (moved here to avoid redundant call in fast path). + // Get render scale once. float sx; float sy; SDL_GetRenderScale(renderer, &sx, &sy); + // Fast path 1: No transformations needed; direct BitBlt. + if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f && sx == 1.f && sy == 1.f) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } + // Slow path: Transformations needed. int w = phdata->cachedWidth; int h = phdata->cachedHeight; @@ -577,7 +565,6 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec } dest = iWorkBuffer1; - bool useBuffer1 = true; if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { TFixed rf = Real2Fix(c->r); @@ -591,7 +578,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); source = dest; - useBuffer1 = !useBuffer1; + dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } if (sx != 1.f || sy != 1.f) { @@ -600,10 +587,8 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec TFixed center_x = Int2Fix(w / 2); TFixed center_y = Int2Fix(h / 2); - dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y); source = dest; - useBuffer1 = !useBuffer1; } // Use temp bitmap to avoid destroying source texture. @@ -637,14 +622,22 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE const bool isNoFlip = (!copydata->flip); const bool isNoColorMod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f); - // Fast path 1: Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). - if (isNoFlip && isIdentityScale && isNoColorMod && !isNoRotation) { - TInt angleIndex = -1; - TFixed angle = copydata->angle; + // Fast path 1: No transformations needed; direct BitBlt. + if (isNoFlip && isIdentityScale && isNoRotation && isNoColorMod) { + TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } - // Use pre-calculated angle constants for comparison. - if (angle == kAngleZero) { - angleIndex = 0; + // Fast path 2: Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). + if (isNoFlip && isIdentityScale && isNoColorMod && !isNoRotation) { + TFixed angle = copydata->angle; + TInt angleIndex = -1; + + // Check cardinal angles with tolerance - optimized for early exit. + if (SDL_abs(angle - kAngleZero) < kAngleTolerance) { + angleIndex = 0; // 0° } else if (SDL_abs(angle - kAnglePi_2) < kAngleTolerance) { angleIndex = 1; // 90° } else if (SDL_abs(angle - kAnglePi) < kAngleTolerance) { @@ -666,14 +659,6 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } } - // Fast path 2: No transformations needed; direct BitBlt. - if (isNoFlip && isIdentityScale && isNoRotation && isNoColorMod) { - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); - TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; - } - // Slow path: Transformations needed. int w = phdata->cachedWidth; int h = phdata->cachedHeight; @@ -692,26 +677,23 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } dest = iWorkBuffer1; - bool useBuffer1 = true; if (copydata->flip) { ApplyFlip(dest, source, pitch, w, h, copydata->flip); source = dest; - useBuffer1 = !useBuffer1; + dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } if (!isIdentityScale) { - dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); source = dest; - useBuffer1 = !useBuffer1; + dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } if (copydata->angle) { - dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle); source = dest; - useBuffer1 = !useBuffer1; + dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } if (!isNoColorMod) { @@ -724,10 +706,8 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE BuildColorModLUT(rf, gf, bf); } - dest = useBuffer1 ? iWorkBuffer1 : iWorkBuffer2; ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); source = dest; - useBuffer1 = !useBuffer1; } // Use temp bitmap to avoid destroying source texture. @@ -799,10 +779,12 @@ void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount) iLinePointsBuffer[i] = TPoint(aVerts[i].x, aVerts[i].y); } - TUint32 aColor = (((TUint8)aVerts->color.a << 24) | - ((TUint8)aVerts->color.b << 16) | - ((TUint8)aVerts->color.g << 8) | - (TUint8)aVerts->color.r); + // Pack color once - all vertices use the same color in polyline. + Uint8 ca = aVerts->color.a; + Uint8 cr = aVerts->color.r; + Uint8 cg = aVerts->color.g; + Uint8 cb = aVerts->color.b; + TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; iRenderer->Gc()->SetPenColor(aColor); iRenderer->Gc()->DrawPolyLineNoEndPoint(iLinePointsBuffer, aCount); @@ -813,14 +795,15 @@ void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { // Batch points by color to minimize SetPenColor calls. - TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + TUint32 currentColor = 0; bool colorSet = false; for (TInt i = 0; i < aCount; i++, aVerts++) { - TUint32 aColor = (((TUint8)aVerts->color.a << 24) | - ((TUint8)aVerts->color.b << 16) | - ((TUint8)aVerts->color.g << 8) | - (TUint8)aVerts->color.r); + Uint8 ca = aVerts->color.a; + Uint8 cr = aVerts->color.r; + Uint8 cg = aVerts->color.g; + Uint8 cb = aVerts->color.b; + TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; // Only set pen color when it changes. if (!colorSet || aColor != currentColor) { @@ -838,7 +821,7 @@ void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) { if (iRenderer && iRenderer->Gc()) { // Batch rectangles by color to minimize SetPenColor/SetBrushColor calls. - TUint32 currentColor = 0xFFFFFFFF; // Invalid initial color + TUint32 currentColor = 0; bool colorSet = false; // Process rectangles (each rect uses 2 vertices: position and size). @@ -847,10 +830,11 @@ void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) TSize size(aVerts[i + 1].x, aVerts[i + 1].y); TRect rect(pos, size); - TUint32 aColor = (((TUint8)aVerts[i].color.a << 24) | - ((TUint8)aVerts[i].color.b << 16) | - ((TUint8)aVerts[i].color.g << 8) | - (TUint8)aVerts[i].color.r); + Uint8 ca = aVerts[i].color.a; + Uint8 cr = aVerts[i].color.r; + Uint8 cg = aVerts[i].color.g; + Uint8 cb = aVerts[i].color.b; + TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; // Only set colors when they change. if (!colorSet || aColor != currentColor) { From badc3b82c51ef55c06ef1e1fffe4cd14617d964c Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Thu, 16 Apr 2026 21:27:14 +0200 Subject: [PATCH 126/407] [N-Gage] Micro-optimize rendering back-end - Skip SDL_GetRenderScale call in Copy() fast path - Cache last clear color to avoid redundant SetBrushColor calls - Add whole-image bounds pre-check to skip per-pixel checks in rotation - Simplify color packing in DrawPoints/FillRects to reduce overhead --- src/render/ngage/SDL_render_ngage.cpp | 52 +++---- src/render/ngage/SDL_render_ngage_c.hpp | 3 + src/render/ngage/SDL_render_ops.cpp | 174 ++++++++++++++++++------ 3 files changed, 161 insertions(+), 68 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index e9dcd547ab..88fe359275 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -174,7 +174,7 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0) +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0), iLastClearColor(0xFFFFFFFF) { } @@ -313,7 +313,11 @@ void CRenderer::AbortNow(RDirectScreenAccess::TTerminationReasons aReason) void CRenderer::Clear(TUint32 iColor) { if (iRenderer && iRenderer->Gc()) { - iRenderer->Gc()->SetBrushColor(iColor); + // Skip redundant SetBrushColor if color hasn't changed. + if (iColor != iLastClearColor) { + iRenderer->Gc()->SetBrushColor(iColor); + iLastClearColor = iColor; + } iRenderer->Gc()->Clear(); } } @@ -534,20 +538,24 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec SDL_FColor *c = &texture->color; - // Get render scale once. - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); - // Fast path 1: No transformations needed; direct BitBlt. - if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f && sx == 1.f && sy == 1.f) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; + if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { + // Only check render scale if color mod passes. + float sx; + float sy; + SDL_GetRenderScale(renderer, &sx, &sy); + if (sx == 1.f && sy == 1.f) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); + return true; + } } // Slow path: Transformations needed. + float sx; + float sy; + SDL_GetRenderScale(renderer, &sx, &sy); int w = phdata->cachedWidth; int h = phdata->cachedHeight; int pitch = phdata->cachedPitch; @@ -617,13 +625,13 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE SDL_FColor *c = &texture->color; // Pre-calculate common checks. - const bool isIdentityScale = (copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1)); - const bool isNoRotation = (copydata->angle == 0); const bool isNoFlip = (!copydata->flip); + const bool isNoRotation = (copydata->angle == 0); const bool isNoColorMod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f); + const bool isIdentityScale = (copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1)); // Fast path 1: No transformations needed; direct BitBlt. - if (isNoFlip && isIdentityScale && isNoRotation && isNoColorMod) { + if (isNoFlip && isNoRotation && isNoColorMod && isIdentityScale) { TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); @@ -799,11 +807,8 @@ void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) bool colorSet = false; for (TInt i = 0; i < aCount; i++, aVerts++) { - Uint8 ca = aVerts->color.a; - Uint8 cr = aVerts->color.r; - Uint8 cg = aVerts->color.g; - Uint8 cb = aVerts->color.b; - TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; + TUint32 aColor = (TUint32(aVerts->color.a) << 24) | (TUint32(aVerts->color.b) << 16) | + (TUint32(aVerts->color.g) << 8) | TUint32(aVerts->color.r); // Only set pen color when it changes. if (!colorSet || aColor != currentColor) { @@ -830,11 +835,8 @@ void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) TSize size(aVerts[i + 1].x, aVerts[i + 1].y); TRect rect(pos, size); - Uint8 ca = aVerts[i].color.a; - Uint8 cr = aVerts[i].color.r; - Uint8 cg = aVerts[i].color.g; - Uint8 cb = aVerts[i].color.b; - TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; + TUint32 aColor = (TUint32(aVerts[i].color.a) << 24) | (TUint32(aVerts[i].color.b) << 16) | + (TUint32(aVerts[i].color.g) << 8) | TUint32(aVerts[i].color.r); // Only set colors when they change. if (!colorSet || aColor != currentColor) { diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 4b1d38ddcf..7fbfc88799 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -111,6 +111,9 @@ class CRenderer : public MDirectScreenAccess // Cached draw color to avoid redundant SetPenColor/SetBrushColor calls. TUint32 iLastDrawColor; + // Cached clear color to avoid redundant SetBrushColor calls. + TUint32 iLastClearColor; + // Helper methods. bool EnsureWorkBufferCapacity(TInt aRequiredSize); bool EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight); diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 54fbddb900..6bb925749c 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -98,6 +98,22 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F const bool flipHorizontal = (flip & SDL_FLIP_HORIZONTAL) != 0; const bool flipVertical = (flip & SDL_FLIP_VERTICAL) != 0; + // Fast path: No flip; just copy entire buffer. + if (!flipHorizontal && !flipVertical) { + Mem::Copy(dest, source, pitch * height); + return; + } + + // Fast path: Vertical-only flip; copy rows in reverse order. + if (flipVertical && !flipHorizontal) { + for (int y = 0; y < height; ++y) { + const int src_y = height - 1 - y; + Mem::Copy(&dst_pixels[y * pitchPixels], &src_pixels[src_y * pitchPixels], pitch); + } + return; + } + + // Slow path: Horizontal or both flips; need pixel-level operations. // Pre-calculate width/height bounds for horizontal/vertical flipping. const int width_m1 = width - 1; const int height_m1 = height - 1; @@ -150,6 +166,27 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T // Pre-calculate pitch in pixels to avoid repeated division. const TInt pitchPixels = pitch >> 1; + // Pre-check if rotation keeps all pixels within bounds to skip per-pixel checks. + // Calculate the four corners of the image after rotation around center. + bool allInBounds = true; + if (angle != 0) { + // Check corners: (0,0), (width-1,0), (0,height-1), (width-1,height-1) + TFixed corners_x[4] = { -center_x, Int2Fix(width - 1) - center_x, -center_x, Int2Fix(width - 1) - center_x }; + TFixed corners_y[4] = { -center_y, -center_y, Int2Fix(height - 1) - center_y, Int2Fix(height - 1) - center_y }; + + for (int i = 0; i < 4; ++i) { + TFixed rot_x = FixMul(corners_x[i], cos_angle) - FixMul(corners_y[i], sin_angle) + center_x; + TFixed rot_y = FixMul(corners_x[i], sin_angle) + FixMul(corners_y[i], cos_angle) + center_y; + int final_x = Fix2Int(rot_x); + int final_y = Fix2Int(rot_y); + + if (final_x < 0 || final_x >= width || final_y < 0 || final_y >= height) { + allInBounds = false; + break; + } + } + } + // Incremental DDA: Calculate per-pixel increments. // As we move right (x+1), the rotated position changes by (cos, -sin). const TFixed dx_cos = cos_angle; @@ -172,55 +209,99 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T int x = 0; - // Process 4 pixels at once. - for (; x < width - 3; x += 4) { - // Pixel 0 - int final_x0 = Fix2Int(src_x); - int final_y0 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; + if (allInBounds) { + // Fast path: No bounds checking needed. + for (; x < width - 3; x += 4) { + // Pixel 0 + int final_x0 = Fix2Int(src_x); + int final_y0 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; - // Pixel 1 - int final_x1 = Fix2Int(src_x); - int final_y1 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; + // Pixel 1 + int final_x1 = Fix2Int(src_x); + int final_y1 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; - // Pixel 2 - int final_x2 = Fix2Int(src_x); - int final_y2 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; + // Pixel 2 + int final_x2 = Fix2Int(src_x); + int final_y2 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; - // Pixel 3 - int final_x3 = Fix2Int(src_x); - int final_y3 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; + // Pixel 3 + int final_x3 = Fix2Int(src_x); + int final_y3 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; - // Write all 4 pixels with bounds checking. - dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? src_pixels[final_y0 * pitchPixels + final_x0] : 0; - dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? src_pixels[final_y1 * pitchPixels + final_x1] : 0; - dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? src_pixels[final_y2 * pitchPixels + final_x2] : 0; - dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? src_pixels[final_y3 * pitchPixels + final_x3] : 0; - } - - // Handle remaining pixels. - for (; x < width; ++x) { - // Convert to integer coordinates. - int final_x = Fix2Int(src_x); - int final_y = Fix2Int(src_y); - - // Check bounds. - if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { - dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; - } else { - dst_pixels[dstRowOffset + x] = 0; + // Write all 4 pixels without bounds checking. + dst_pixels[dstRowOffset + x] = src_pixels[final_y0 * pitchPixels + final_x0]; + dst_pixels[dstRowOffset + x + 1] = src_pixels[final_y1 * pitchPixels + final_x1]; + dst_pixels[dstRowOffset + x + 2] = src_pixels[final_y2 * pitchPixels + final_x2]; + dst_pixels[dstRowOffset + x + 3] = src_pixels[final_y3 * pitchPixels + final_x3]; } - // Incremental step: move to next pixel (just additions, no multiplications!). - src_x += dx_cos; - src_y += dx_sin; + // Handle remaining pixels. + for (; x < width; ++x) { + int final_x = Fix2Int(src_x); + int final_y = Fix2Int(src_y); + dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; + src_x += dx_cos; + src_y += dx_sin; + } + } else { + // Slow path: Bounds checking required. + for (; x < width - 3; x += 4) { + // Pixel 0 + int final_x0 = Fix2Int(src_x); + int final_y0 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 1 + int final_x1 = Fix2Int(src_x); + int final_y1 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 2 + int final_x2 = Fix2Int(src_x); + int final_y2 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Pixel 3 + int final_x3 = Fix2Int(src_x); + int final_y3 = Fix2Int(src_y); + src_x += dx_cos; + src_y += dx_sin; + + // Write all 4 pixels with bounds checking. + dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? src_pixels[final_y0 * pitchPixels + final_x0] : 0; + dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? src_pixels[final_y1 * pitchPixels + final_x1] : 0; + dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? src_pixels[final_y2 * pitchPixels + final_x2] : 0; + dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? src_pixels[final_y3 * pitchPixels + final_x3] : 0; + } + + // Handle remaining pixels. + for (; x < width; ++x) { + // Convert to integer coordinates. + int final_x = Fix2Int(src_x); + int final_y = Fix2Int(src_y); + + // Check bounds. + if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { + dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; + } else { + dst_pixels[dstRowOffset + x] = 0; + } + + // Incremental step: move to next pixel (just additions, no multiplications!). + src_x += dx_cos; + src_y += dx_sin; + } } } } @@ -230,6 +311,13 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); + // Fast path: Identity scale; just copy entire buffer. + const TFixed identity = Int2Fix(1); + if (scale_x == identity && scale_y == identity) { + Mem::Copy(dest, source, pitch * height); + return; + } + // Pre-calculate pitch in pixels to avoid repeated division. const TInt pitchPixels = pitch >> 1; From 63901401cab9051012d85c4bf245bea23687dce0 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Thu, 16 Apr 2026 21:35:10 +0200 Subject: [PATCH 127/407] [N-Gage] Micro-optimize main loop handler to improve performance and input latency - Change active object priority from EPriorityLow to EPriorityStandard - Process all events in batch before SDL_AppIterate() to reduce input lag - Remove redundant SDL_PumpEvents() call (already done by SDL_PollEvent) - Move clean-up logic into ShutdownApp() helper function --- src/main/ngage/SDL_sysmain_main.cpp | 136 +++++++++++++--------------- 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/src/main/ngage/SDL_sysmain_main.cpp b/src/main/ngage/SDL_sysmain_main.cpp index fc3ce05827..7fe7a9bf31 100644 --- a/src/main/ngage/SDL_sysmain_main.cpp +++ b/src/main/ngage/SDL_sysmain_main.cpp @@ -35,12 +35,12 @@ extern void SDL_AppQuit(void *appstate, SDL_AppResult result); #include #include -#include #include +#include -#include "SDL_sysmain_main.hpp" #include "../../audio/ngage/SDL_ngageaudio.hpp" #include "../../render/ngage/SDL_render_ngage_c.hpp" +#include "SDL_sysmain_main.hpp" CRenderer *gRenderer = 0; @@ -56,69 +56,64 @@ GLDEF_C TInt E32Main() char **envp_lvalue = envp; CTrapCleanup *cleanup = CTrapCleanup::New(); - if (!cleanup) - { + if (!cleanup) { return KErrNoMemory; } TRAPD(err, - { - CActiveScheduler *scheduler = new (ELeave) CActiveScheduler(); - CleanupStack::PushL(scheduler); - CActiveScheduler::Install(scheduler); + { + CActiveScheduler *scheduler = new (ELeave) CActiveScheduler(); + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); - TInt posixErr = SpawnPosixServerThread(); - if (posixErr != KErrNone) - { - SDL_Log("Error: Failed to spawn POSIX server thread: %d", posixErr); - User::Leave(posixErr); - } + TInt posixErr = SpawnPosixServerThread(); + if (posixErr != KErrNone) { + SDL_Log("Error: Failed to spawn POSIX server thread: %d", posixErr); + User::Leave(posixErr); + } - __crt0(argc, argv_lvalue, envp_lvalue); + __crt0(argc, argv_lvalue, envp_lvalue); - // Increase heap size. - RHeap *newHeap = User::ChunkHeap(NULL, 7500000, 7500000, KMinHeapGrowBy); - if (!newHeap) - { - SDL_Log("Error: Failed to create new heap"); - User::Leave(KErrNoMemory); - } - CleanupStack::PushL(newHeap); + // Increase heap size. + RHeap *newHeap = User::ChunkHeap(NULL, 7500000, 7500000, KMinHeapGrowBy); + if (!newHeap) { + SDL_Log("Error: Failed to create new heap"); + User::Leave(KErrNoMemory); + } + CleanupStack::PushL(newHeap); - RHeap *oldHeap = User::SwitchHeap(newHeap); + RHeap *oldHeap = User::SwitchHeap(newHeap); - TInt targetLatency = 225; - InitAudio(&targetLatency); + TInt targetLatency = 225; + InitAudio(&targetLatency); - // Wait until audio is ready. - while (!AudioIsReady()) - { - User::After(100000); // 100ms. - } + // Wait until audio is ready. + while (!AudioIsReady()) { + User::After(100000); // 100ms. + } - // Create and start the rendering backend. - gRenderer = CRenderer::NewL(); - CleanupStack::PushL(gRenderer); + // Create and start the rendering backend. + gRenderer = CRenderer::NewL(); + CleanupStack::PushL(gRenderer); - // Create and start the SDL main runner. - CSDLmain *mainApp = CSDLmain::NewL(); - CleanupStack::PushL(mainApp); - mainApp->Start(); + // Create and start the SDL main runner. + CSDLmain *mainApp = CSDLmain::NewL(); + CleanupStack::PushL(mainApp); + mainApp->Start(); - // Start the active scheduler to handle events. - CActiveScheduler::Start(); + // Start the active scheduler to handle events. + CActiveScheduler::Start(); - CleanupStack::PopAndDestroy(gRenderer); - CleanupStack::PopAndDestroy(mainApp); + CleanupStack::PopAndDestroy(gRenderer); + CleanupStack::PopAndDestroy(mainApp); - User::SwitchHeap(oldHeap); + User::SwitchHeap(oldHeap); - CleanupStack::PopAndDestroy(newHeap); - CleanupStack::PopAndDestroy(scheduler); - }); + CleanupStack::PopAndDestroy(newHeap); + CleanupStack::PopAndDestroy(scheduler); + }); - if (err != KErrNone) - { + if (err != KErrNone) { SDL_Log("Error: %d", err); } @@ -134,7 +129,7 @@ CSDLmain *CSDLmain::NewL() return self; } -CSDLmain::CSDLmain() : CActive(EPriorityLow) {} +CSDLmain::CSDLmain() : CActive(EPriorityStandard) {} void CSDLmain::ConstructL() { @@ -157,40 +152,35 @@ void CSDLmain::DoCancel() {} static bool callbacks_initialized = false; +static void ShutdownApp(SDL_AppResult result) +{ + DeinitAudio(); + SDL_AppQuit(NULL, result); + SDL_Quit(); + CActiveScheduler::Stop(); +} + void CSDLmain::RunL() { - if (callbacks_initialized) - { + if (callbacks_initialized) { SDL_Event event; - iResult = SDL_AppIterate(NULL); - if (iResult != SDL_APP_CONTINUE) - { - DeinitAudio(); - SDL_AppQuit(NULL, iResult); - SDL_Quit(); - CActiveScheduler::Stop(); - return; - } - - SDL_PumpEvents(); - if (SDL_PollEvent(&event)) - { + while (SDL_PollEvent(&event)) { iResult = SDL_AppEvent(NULL, &event); - if (iResult != SDL_APP_CONTINUE) - { - DeinitAudio(); - SDL_AppQuit(NULL, iResult); - SDL_Quit(); - CActiveScheduler::Stop(); + if (iResult != SDL_APP_CONTINUE) { + ShutdownApp(iResult); return; } } + iResult = SDL_AppIterate(NULL); + if (iResult != SDL_APP_CONTINUE) { + ShutdownApp(iResult); + return; + } + Start(); - } - else - { + } else { SDL_SetMainReady(); SDL_AppInit(NULL, 0, NULL); callbacks_initialized = true; From 75a65e05e1a5d6b2199eefc3edc1f9ed9bd684fa Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 15 Apr 2026 11:24:20 -0400 Subject: [PATCH 128/407] x11: Use XInput2 events to pass through the keyboard ID to core key events XInput2 keyboard handling has limitations: system keys that shouldn't be passed through when the keyboard isn't grabbed can be seen, and the text input system needs key events to flow through the X server to function properly (passing synthesized events through the filter function is not sufficient and doesn't work with non-Latin character sets). The primary bit of information missing from the core X key events that XInput2 provides is the source device, so use the XInput2 slave keyboard device events to store that value, and apply it to core X key events with the same serial. XInput2 events always arrive before core events so this works universally. --- src/video/x11/SDL_x11events.c | 8 ++++++-- src/video/x11/SDL_x11video.h | 2 ++ src/video/x11/SDL_x11xinput2.c | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 15af66124f..961c8b08e2 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1834,12 +1834,16 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case KeyPress: case KeyRelease: { + SDL_KeyboardID keyboardID = SDL_GLOBAL_KEYBOARD_ID; if (data->xinput2_keyboard_enabled) { - // This input is being handled by XInput2 + // This input is being handled by XInput2. break; + } else if (xevent->xkey.serial == videodata->xinput_last_key_serial) { + // Use the device ID from the XInput2 event if the serials match. + keyboardID = videodata->xinput_last_keyboard_device; } - X11_HandleKeyEvent(_this, data, SDL_GLOBAL_KEYBOARD_ID, xevent); + X11_HandleKeyEvent(_this, data, keyboardID, xevent); } break; case MotionNotify: diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 01c2e5b9fb..7bc858d98b 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -140,6 +140,8 @@ struct SDL_VideoData SDL_XInput2DeviceInfo *mouse_device_info; unsigned long xinput_last_button_serial; + unsigned long xinput_last_key_serial; + int xinput_last_keyboard_device; int xinput_master_pointer_device; bool xinput_hierarchy_changed; diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index d6c704e3f6..3a94c6a1f0 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -303,6 +303,12 @@ bool X11_InitXinput2(SDL_VideoDevice *_this) eventmask.mask_len = sizeof(mask); eventmask.mask = mask; +#ifndef USE_XINPUT2_KEYBOARD + // If not using the full keyboard handling, register for keypresses to get the event source devices. + XISetMask(mask, XI_KeyPress); + XISetMask(mask, XI_KeyRelease); +#endif + XISetMask(mask, XI_HierarchyChanged); X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1); @@ -535,6 +541,8 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) case XI_KeyRelease: { const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + +#ifdef XINPUT2_USE_KEYBOARD SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); XEvent xevent; @@ -564,6 +572,13 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) xevent.xkey.same_screen = 1; X11_HandleKeyEvent(_this, windowdata, (SDL_KeyboardID)xev->sourceid, &xevent); +#else + /* Keys are handled through core X events, however, note the device ID and + * associated serial, so that the source device ID can be passed through. + */ + videodata->xinput_last_key_serial = xev->serial; + videodata->xinput_last_keyboard_device = xev->sourceid; +#endif } break; case XI_RawButtonPress: From b181eb4ed0e117083e86b66e538492c815c8f899 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 17 Apr 2026 10:28:50 -0400 Subject: [PATCH 129/407] x11: Fix #define name --- src/video/x11/SDL_x11xinput2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 3a94c6a1f0..c099589591 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -542,7 +542,7 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) { const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; -#ifdef XINPUT2_USE_KEYBOARD +#ifdef USE_XINPUT2_KEYBOARD SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); XEvent xevent; From 6e65c3fac4d3f0c9eb017c7d11b2ef49a960e422 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Sat, 18 Apr 2026 12:52:22 +0200 Subject: [PATCH 130/407] [N-Gage] Remove optimisations except for native texture handling prior to some rework of the rendering back-end [N-Gage] Set proper brush style to draw filled rects properly. [N-Gage] Add persistent buffers to avoid per-frame memory allocations (which are expensive) [N-Gage] Add support for SDL_TEXTURE_ACCESS_TARGET, fixes #13165 [N-Gage] Update README, add hint that the compiler does not support aggregate initializations for structs (knowing this, avoids a lot of headache during debugging) [N-Gage] Add basic fast-path optimisations for render operations. [N-Gage] Fix line drawing. --- docs/README-ngage.md | 11 +- src/render/ngage/SDL_render_ngage.c | 66 +-- src/render/ngage/SDL_render_ngage.cpp | 688 +++++++----------------- src/render/ngage/SDL_render_ngage_c.h | 26 +- src/render/ngage/SDL_render_ngage_c.hpp | 46 +- src/render/ngage/SDL_render_ops.cpp | 537 +++++++++--------- src/render/ngage/SDL_render_ops.hpp | 2 +- 7 files changed, 509 insertions(+), 867 deletions(-) diff --git a/docs/README-ngage.md b/docs/README-ngage.md index beed7af0af..eebbcabd81 100644 --- a/docs/README-ngage.md +++ b/docs/README-ngage.md @@ -33,14 +33,6 @@ software renderer has been removed. The outcome is a significantly leaner and more efficient SDL port, which we hope will breathe new life into this beloved yet obscure platform. -## To the Stubborn Legends of the DC Scene - -This port is lovingly dedicated to the ever-nostalgic Dreamcast homebrew scene -- -because if we managed to pull this off for the N-Gage (yes, the N-Gage), surely -you guys can stop clinging to SDL2 like it's a rare Shenmue prototype and finally -make the leap to SDL3. It's 2025, not 1999 -- and let's be honest, you're rocking -a state-of-the-art C23 compiler. The irony writes itself. - ## Existing Issues and Limitations - For now, the new @@ -62,3 +54,6 @@ a state-of-the-art C23 compiler. The irony writes itself. expected to be resolved in a future update. - Dependency tracking is currently non-functional. + +- The compiler doesn't support aggregate initialization for structs, so + each field must be assigned explicitly. diff --git a/src/render/ngage/SDL_render_ngage.c b/src/render/ngage/SDL_render_ngage.c index b960a84d87..b3710c39dc 100644 --- a/src/render/ngage/SDL_render_ngage.c +++ b/src/render/ngage/SDL_render_ngage.c @@ -155,7 +155,7 @@ static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD return false; } - if (!NGAGE_CreateTextureData(data, texture->w, texture->h)) { + if (!NGAGE_CreateTextureData(data, texture->w, texture->h, texture->access)) { SDL_free(data); return false; } @@ -283,8 +283,12 @@ static bool NGAGE_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SD verts->dstrect.h = (int)dstrect->h; verts->angle = Real2Fix(angle); - verts->center.x = Real2Fix(center->x); - verts->center.y = Real2Fix(center->y); + // Convert center from destination-space to source-space. + // Center is relative to dstrect, but rotation is applied in source texture space. + float center_x_src = (center->x / dstrect->w) * srcquad->w; + float center_y_src = (center->y / dstrect->h) * srcquad->h; + verts->center.x = Real2Fix(center_x_src); + verts->center.y = Real2Fix(center_y_src); verts->scale_x = Real2Fix(scale_x); verts->scale_y = Real2Fix(scale_y); @@ -444,27 +448,24 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co return false; } - void *bitmapData = NGAGE_GetBitmapDataAddress(phdata); - int bitmapPitch = NGAGE_GetBitmapPitch(phdata); - - if (!bitmapData || bitmapPitch == 0) { + Uint8 *dst = (Uint8 *)NGAGE_GetBitmapDataAddress(phdata); + if (!dst) { return false; } - Uint8 *src = (Uint8 *)pixels; - Uint8 *dst = (Uint8 *)bitmapData + rect->y * bitmapPitch + rect->x * 2; // 2 bytes per pixel for EColor4K + const int bytes_per_pixel = 2; + const int bitmap_pitch = texture->w * bytes_per_pixel; - size_t length = (size_t)rect->w * 2; // 2 bytes per pixel for EColor4K + const Uint8 *src = (const Uint8 *)pixels; + dst += rect->y * bitmap_pitch + rect->x * bytes_per_pixel; + + const size_t length = (size_t)rect->w * bytes_per_pixel; for (int row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; - dst += bitmapPitch; + dst += bitmap_pitch; } - // Mark texture as dirty. - phdata->isDirty = true; - phdata->dirtyRect = *rect; - return true; } @@ -476,34 +477,39 @@ static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons return false; } - void *bitmapData = NGAGE_GetBitmapDataAddress(phdata); - int bitmapPitch = NGAGE_GetBitmapPitch(phdata); - - if (!bitmapData || bitmapPitch == 0) { + Uint8 *data = (Uint8 *)NGAGE_GetBitmapDataAddress(phdata); + if (!data) { return false; } - *pixels = (void *)((Uint8 *)bitmapData + rect->y * bitmapPitch + rect->x * 2); // 2 bytes per pixel for EColor4K - *pitch = bitmapPitch; - - // Store the lock rectangle for dirty tracking. - phdata->dirtyRect = *rect; + const int bytes_per_pixel = 2; + const int bitmap_pitch = texture->w * bytes_per_pixel; + *pixels = (void *)(data + rect->y * bitmap_pitch + rect->x * bytes_per_pixel); + *pitch = bitmap_pitch; return true; } static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; - - if (phdata) { - // Mark texture as dirty after unlock (assume it was modified). - phdata->isDirty = true; - } } static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { + NGAGE_RendererData *data = (NGAGE_RendererData *)renderer->internal; + + if (texture) { + NGAGE_TextureData *texturedata = (NGAGE_TextureData *)texture->internal; + if (!texturedata || !texturedata->gc) { + return SDL_SetError("Texture is not a render target"); + } + data->current_target = texture; + NGAGE_SetRenderTargetInternal(texturedata); + } else { + data->current_target = NULL; + NGAGE_SetRenderTargetInternal(NULL); + } + return true; } diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 88fe359275..a4b9a6d0a1 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -59,57 +59,33 @@ bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData return gRenderer->CopyEx(renderer, texture, copydata); } -bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height) +bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height, const int access) { - return gRenderer->CreateTextureData(data, width, height); + return gRenderer->CreateTextureData(data, width, height, access); } void NGAGE_DestroyTextureData(NGAGE_TextureData *data) { if (data) { + if (data->gc) { + delete data->gc; + data->gc = NULL; + } + if (data->device) { + delete data->device; + data->device = NULL; + } delete data->bitmap; data->bitmap = NULL; - - // Free cardinal rotation cache. - for (int i = 0; i < 4; i++) { - if (data->cardinalRotations[i]) { - delete data->cardinalRotations[i]; - data->cardinalRotations[i] = NULL; - } - } } } void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data) { - if (data) { - return data->bitmap->DataAddress(); + if (!data || !data->bitmap) { + return NULL; } - return NULL; -} - -int NGAGE_GetBitmapPitch(NGAGE_TextureData *data) -{ - if (data) { - return data->cachedPitch; - } - return 0; -} - -int NGAGE_GetBitmapWidth(NGAGE_TextureData *data) -{ - if (data) { - return data->cachedWidth; - } - return 0; -} - -int NGAGE_GetBitmapHeight(NGAGE_TextureData *data) -{ - if (data) { - return data->cachedHeight; - } - return 0; + return data->bitmap->DataAddress(); } void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count) @@ -139,7 +115,9 @@ void NGAGE_SetClipRect(const SDL_Rect *rect) void NGAGE_SetDrawColor(const Uint32 color) { - gRenderer->SetDrawColor(color); + if (gRenderer) { + gRenderer->SetDrawColor(color); + } } void NGAGE_PumpEventsInternal() @@ -152,19 +130,17 @@ void NGAGE_SuspendScreenSaverInternal(bool suspend) gRenderer->SuspendScreenSaver(suspend); } +void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target) +{ + if (gRenderer) { + gRenderer->SetRenderTarget(target); + } +} + #ifdef __cplusplus } #endif -// Pre-calculated fixed-point angle constants for cardinal rotation checks. -// These avoid repeated Real2Fix conversions in CopyEx hot path. -static const TFixed kAngleZero = 0; -static const TFixed kAnglePi_2 = Real2Fix(M_PI / 2.0); // 90 degrees -static const TFixed kAnglePi = Real2Fix(M_PI); // 180 degrees -static const TFixed kAnglePi3_2 = Real2Fix(3.0 * M_PI / 2.0); // 270 degrees -static const TFixed kAnglePi2 = Real2Fix(2.0 * M_PI); // 360 degrees -static const TFixed kAngleTolerance = 100; // Tolerance for angle comparison - CRenderer *CRenderer::NewL() { CRenderer *self = new (ELeave) CRenderer(); @@ -174,32 +150,16 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iWorkBuffer1(0), iWorkBuffer2(0), iWorkBufferSize(0), iTempRenderBitmap(0), iTempRenderBitmapWidth(0), iTempRenderBitmapHeight(0), iLastColorR(-1), iLastColorG(-1), iLastColorB(-1), iLinePointsBuffer(0), iLinePointsBufferCapacity(0), iLastDrawColor(0), iLastClearColor(0xFFFFFFFF) -{ -} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iCurrentRenderTarget(0), iPixelBufferA(0), iPixelBufferB(0), iPixelBufferSize(0), iPointsBuffer(0), iPointsBufferSize(0) {} CRenderer::~CRenderer() { delete iRenderer; iRenderer = 0; - // Free work buffers. - SDL_free(iWorkBuffer1); - SDL_free(iWorkBuffer2); - iWorkBuffer1 = 0; - iWorkBuffer2 = 0; - iWorkBufferSize = 0; - - // Free temp render bitmap. - delete iTempRenderBitmap; - iTempRenderBitmap = 0; - iTempRenderBitmapWidth = 0; - iTempRenderBitmapHeight = 0; - - // Free line points buffer. - delete[] iLinePointsBuffer; - iLinePointsBuffer = 0; - iLinePointsBufferCapacity = 0; + SDL_free(iPixelBufferA); + SDL_free(iPixelBufferB); + delete[] iPointsBuffer; } void CRenderer::ConstructL() @@ -312,188 +272,13 @@ void CRenderer::AbortNow(RDirectScreenAccess::TTerminationReasons aReason) void CRenderer::Clear(TUint32 iColor) { - if (iRenderer && iRenderer->Gc()) { - // Skip redundant SetBrushColor if color hasn't changed. - if (iColor != iLastClearColor) { - iRenderer->Gc()->SetBrushColor(iColor); - iLastClearColor = iColor; - } - iRenderer->Gc()->Clear(); + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + gc->SetBrushColor(iColor); + gc->Clear(); } } -bool CRenderer::EnsureWorkBufferCapacity(TInt aRequiredSize) -{ - if (aRequiredSize <= iWorkBufferSize) { - return true; - } - - // Free old buffers. - SDL_free(iWorkBuffer1); - SDL_free(iWorkBuffer2); - - // Allocate new buffers. - iWorkBuffer1 = SDL_calloc(1, aRequiredSize); - if (!iWorkBuffer1) { - iWorkBuffer2 = 0; - iWorkBufferSize = 0; - return false; - } - - iWorkBuffer2 = SDL_calloc(1, aRequiredSize); - if (!iWorkBuffer2) { - SDL_free(iWorkBuffer1); - iWorkBuffer1 = 0; - iWorkBufferSize = 0; - return false; - } - - iWorkBufferSize = aRequiredSize; - return true; -} - -bool CRenderer::EnsureLinePointsCapacity(TInt aRequiredCount) -{ - if (aRequiredCount <= iLinePointsBufferCapacity) { - return true; - } - - // Free old buffer. - delete[] iLinePointsBuffer; - - // Allocate new buffer. - iLinePointsBuffer = new TPoint[aRequiredCount]; - if (!iLinePointsBuffer) { - iLinePointsBufferCapacity = 0; - return false; - } - - iLinePointsBufferCapacity = aRequiredCount; - return true; -} - -bool CRenderer::EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight) -{ - if (iTempRenderBitmap && - iTempRenderBitmapWidth >= aWidth && - iTempRenderBitmapHeight >= aHeight) { - return true; - } - - // Delete old bitmap. - delete iTempRenderBitmap; - iTempRenderBitmap = 0; - - // Create new bitmap. - iTempRenderBitmap = new CFbsBitmap(); - if (!iTempRenderBitmap) { - iTempRenderBitmapWidth = 0; - iTempRenderBitmapHeight = 0; - return false; - } - - TInt error = iTempRenderBitmap->Create(TSize(aWidth, aHeight), EColor4K); - if (error != KErrNone) { - delete iTempRenderBitmap; - iTempRenderBitmap = 0; - iTempRenderBitmapWidth = 0; - iTempRenderBitmapHeight = 0; - return false; - } - - iTempRenderBitmapWidth = aWidth; - iTempRenderBitmapHeight = aHeight; - return true; -} - -void CRenderer::BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf) -{ - // Build lookup tables for R, G, B channels. - for (int i = 0; i < 256; i++) { - TFixed val = i << 16; // Convert to fixed-point - iColorModLUT[i] = (TUint8)SDL_min(Fix2Int(FixMul(val, rf)), 255); // R - iColorModLUT[i + 256] = (TUint8)SDL_min(Fix2Int(FixMul(val, gf)), 255); // G - iColorModLUT[i + 512] = (TUint8)SDL_min(Fix2Int(FixMul(val, bf)), 255); // B - } - - // Remember the last color to avoid rebuilding unnecessarily. - iLastColorR = rf; - iLastColorG = gf; - iLastColorB = bf; -} - -CFbsBitmap *CRenderer::GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex) -{ - // Check if already cached. - if (aTextureData->cardinalRotations[aAngleIndex]) { - return aTextureData->cardinalRotations[aAngleIndex]; - } - - // Create rotated bitmap. - CFbsBitmap *rotated = new CFbsBitmap(); - if (!rotated) { - return NULL; - } - - TInt w = aTextureData->cachedWidth; - TInt h = aTextureData->cachedHeight; - TSize size(w, h); - - // For 90 and 270 degree rotations, swap width/height. - if (aAngleIndex == 1 || aAngleIndex == 3) { - size = TSize(h, w); - } - - TInt error = rotated->Create(size, EColor4K); - if (error != KErrNone) { - delete rotated; - return NULL; - } - - // Rotate the bitmap data. - TUint16 *src = (TUint16 *)aTextureData->cachedDataAddress; - TUint16 *dst = (TUint16 *)rotated->DataAddress(); - TInt srcPitch = aTextureData->cachedPitch >> 1; - TInt dstPitch = rotated->ScanLineLength(size.iWidth, rotated->DisplayMode()) >> 1; - - for (int y = 0; y < h; ++y) { - for (int x = 0; x < w; ++x) { - TUint16 pixel = src[y * srcPitch + x]; - int dstX = 0; - int dstY = 0; - - switch (aAngleIndex) { - case 0: // 0 degrees - dstX = x; - dstY = y; - break; - case 1: // 90 degrees - dstX = h - 1 - y; - dstY = x; - break; - case 2: // 180 degrees - dstX = w - 1 - x; - dstY = h - 1 - y; - break; - case 3: // 270 degrees - dstX = y; - dstY = w - 1 - x; - break; - default: - // Should never happen, but initialize to avoid warnings - dstX = x; - dstY = y; - break; - } - - dst[dstY * dstPitch + dstX] = pixel; - } - } - - aTextureData->cardinalRotations[aAngleIndex] = rotated; - return rotated; -} - #ifdef __cplusplus extern "C" { #endif @@ -508,9 +293,13 @@ Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale) TFixed bf = Real2Fix(b); TFixed af = Real2Fix(a); - rf = SDL_clamp(FixMul(rf, scalef), 0, ff); - gf = SDL_clamp(FixMul(gf, scalef), 0, ff); - bf = SDL_clamp(FixMul(bf, scalef), 0, ff); + rf = FixMul(rf, scalef); + gf = FixMul(gf, scalef); + bf = FixMul(bf, scalef); + + rf = SDL_clamp(rf, 0, ff); + gf = SDL_clamp(gf, 0, ff); + bf = SDL_clamp(bf, 0, ff); af = SDL_clamp(af, 0, ff); rf = FixMul(rf, ff) >> 16; @@ -537,81 +326,70 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec } SDL_FColor *c = &texture->color; - - // Fast path 1: No transformations needed; direct BitBlt. - if (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f) { - // Only check render scale if color mod passes. - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); - if (sx == 1.f && sy == 1.f) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; - } - } - - // Slow path: Transformations needed. - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); - int w = phdata->cachedWidth; - int h = phdata->cachedHeight; - int pitch = phdata->cachedPitch; - void *source = phdata->cachedDataAddress; + int w = texture->w; + int h = texture->h; + const int bytes_per_pixel = 2; + int pitch = w * bytes_per_pixel; + void *source = phdata->bitmap->DataAddress(); void *dest; if (!source) { return false; } - // Ensure work buffers have sufficient capacity. - TInt bufferSize = pitch * h; - if (!EnsureWorkBufferCapacity(bufferSize)) { - return false; + TInt required_size = pitch * h; + if (required_size > iPixelBufferSize) { + void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size); + if (!new_buffer_a) { + return false; + } + iPixelBufferA = new_buffer_a; + + void *new_buffer_b = SDL_realloc(iPixelBufferB, required_size); + if (!new_buffer_b) { + return false; + } + iPixelBufferB = new_buffer_b; + + iPixelBufferSize = required_size; } - dest = iWorkBuffer1; + dest = iPixelBufferA; if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { - TFixed rf = Real2Fix(c->r); - TFixed gf = Real2Fix(c->g); - TFixed bf = Real2Fix(c->b); + ApplyColorMod(dest, source, pitch, w, h, texture->color); - // Build LUT if color changed. - if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) { - BuildColorModLUT(rf, gf, bf); - } - - ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); source = dest; - dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } + float sx; + float sy; + SDL_GetRenderScale(renderer, &sx, &sy); + if (sx != 1.f || sy != 1.f) { TFixed scale_x = Real2Fix(sx); TFixed scale_y = Real2Fix(sy); TFixed center_x = Int2Fix(w / 2); TFixed center_y = Int2Fix(h / 2); + dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; + ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y); + source = dest; } - // Use temp bitmap to avoid destroying source texture. - if (!EnsureTempBitmapCapacity(w, h)) { - return false; + Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); + + if (phdata->bitmap) { + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TPoint aDest(dstrect->x, dstrect->y); + gc->BitBlt(aDest, phdata->bitmap, aSource); + } } - // Copy transformed data to temp bitmap. - Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h); - - // Render from temp bitmap, preserving original texture. - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); - TPoint aDest(dstrect->x, dstrect->y); - iRenderer->Gc()->BitBlt(aDest, iTempRenderBitmap, aSource); - return true; } @@ -623,118 +401,74 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } SDL_FColor *c = &texture->color; - - // Pre-calculate common checks. - const bool isNoFlip = (!copydata->flip); - const bool isNoRotation = (copydata->angle == 0); - const bool isNoColorMod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f); - const bool isIdentityScale = (copydata->scale_x == Int2Fix(1) && copydata->scale_y == Int2Fix(1)); - - // Fast path 1: No transformations needed; direct BitBlt. - if (isNoFlip && isNoRotation && isNoColorMod && isIdentityScale) { - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); - TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource); - return true; - } - - // Fast path 2: Check for cardinal rotation cache opportunity (0°, 90°, 180°, 270°). - if (isNoFlip && isIdentityScale && isNoColorMod && !isNoRotation) { - TFixed angle = copydata->angle; - TInt angleIndex = -1; - - // Check cardinal angles with tolerance - optimized for early exit. - if (SDL_abs(angle - kAngleZero) < kAngleTolerance) { - angleIndex = 0; // 0° - } else if (SDL_abs(angle - kAnglePi_2) < kAngleTolerance) { - angleIndex = 1; // 90° - } else if (SDL_abs(angle - kAnglePi) < kAngleTolerance) { - angleIndex = 2; // 180° - } else if (SDL_abs(angle - kAnglePi3_2) < kAngleTolerance) { - angleIndex = 3; // 270° - } else if (SDL_abs(angle - kAnglePi2) < kAngleTolerance) { - angleIndex = 0; // 360° = 0° - } - - if (angleIndex >= 0) { - CFbsBitmap *cached = GetCardinalRotation(phdata, angleIndex); - if (cached) { - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); - TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, cached, aSource); - return true; - } - } - } - - // Slow path: Transformations needed. - int w = phdata->cachedWidth; - int h = phdata->cachedHeight; - int pitch = phdata->cachedPitch; - void *source = phdata->cachedDataAddress; + int w = texture->w; + int h = texture->h; + const int bytes_per_pixel = 2; + int pitch = w * bytes_per_pixel; + void *source = phdata->bitmap->DataAddress(); void *dest; if (!source) { return false; } - // Ensure work buffers have sufficient capacity. - TInt bufferSize = pitch * h; - if (!EnsureWorkBufferCapacity(bufferSize)) { - return false; + TInt required_size = pitch * h; + if (required_size > iPixelBufferSize) { + void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size); + if (!new_buffer_a) { + return false; + } + iPixelBufferA = new_buffer_a; + + void *new_buffer_b = SDL_realloc(iPixelBufferB, required_size); + if (!new_buffer_b) { + return false; + } + iPixelBufferB = new_buffer_b; + + iPixelBufferSize = required_size; } - dest = iWorkBuffer1; + dest = iPixelBufferA; if (copydata->flip) { ApplyFlip(dest, source, pitch, w, h, copydata->flip); source = dest; - dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } - if (!isIdentityScale) { + if (copydata->scale_x != 1.f || copydata->scale_y != 1.f) { + dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); source = dest; - dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } if (copydata->angle) { + dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle); source = dest; - dest = (dest == iWorkBuffer1) ? iWorkBuffer2 : iWorkBuffer1; } - if (!isNoColorMod) { - TFixed rf = Real2Fix(c->r); - TFixed gf = Real2Fix(c->g); - TFixed bf = Real2Fix(c->b); - - // Build LUT if color changed. - if (rf != iLastColorR || gf != iLastColorG || bf != iLastColorB) { - BuildColorModLUT(rf, gf, bf); - } - - ApplyColorMod(dest, source, pitch, w, h, texture->color, iColorModLUT); + if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { + dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; + ApplyColorMod(dest, source, pitch, w, h, texture->color); source = dest; } - // Use temp bitmap to avoid destroying source texture. - if (!EnsureTempBitmapCapacity(w, h)) { - return false; + Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); + + if (phdata->bitmap) { + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); + gc->BitBlt(aDest, phdata->bitmap, aSource); + } } - // Copy transformed data to temp bitmap. - Mem::Copy(iTempRenderBitmap->DataAddress(), source, pitch * h); - - // Render from temp bitmap, preserving original texture. - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); - TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - iRenderer->Gc()->BitBlt(aDest, iTempRenderBitmap, aSource); - return true; } -bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight) +bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight, const TInt aAccess) { if (!aTextureData) { return false; @@ -752,101 +486,88 @@ bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aW return false; } - // Cache texture properties to avoid repeated API calls. - TSize bitmapSize = aTextureData->bitmap->SizeInPixels(); - aTextureData->cachedWidth = bitmapSize.iWidth; - aTextureData->cachedHeight = bitmapSize.iHeight; - aTextureData->cachedPitch = aTextureData->bitmap->ScanLineLength(aWidth, aTextureData->bitmap->DisplayMode()); - aTextureData->cachedDataAddress = aTextureData->bitmap->DataAddress(); + if (aAccess == SDL_TEXTUREACCESS_TARGET) { + TRAPD(err1, aTextureData->device = CFbsBitmapDevice::NewL(aTextureData->bitmap)); + if (err1 != KErrNone || !aTextureData->device) { + delete aTextureData->bitmap; + aTextureData->bitmap = NULL; + return false; + } - // Initialize cardinal rotation cache to NULL. - for (int i = 0; i < 4; i++) { - aTextureData->cardinalRotations[i] = NULL; + TRAPD(err2, aTextureData->gc = CFbsBitGc::NewL()); + if (err2 != KErrNone || !aTextureData->gc) { + delete aTextureData->device; + aTextureData->device = NULL; + delete aTextureData->bitmap; + aTextureData->bitmap = NULL; + return false; + } + + aTextureData->gc->Activate(aTextureData->device); + } else { + aTextureData->gc = NULL; + aTextureData->device = NULL; } - // Initialize dirty tracking. - aTextureData->isDirty = true; // New textures start dirty. - aTextureData->dirtyRect.x = 0; - aTextureData->dirtyRect.y = 0; - aTextureData->dirtyRect.w = aWidth; - aTextureData->dirtyRect.h = aHeight; - return true; } void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount) { - if (iRenderer && iRenderer->Gc()) { - // Ensure reusable buffer has sufficient capacity. - if (!EnsureLinePointsCapacity(aCount)) { - return; + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + gc->SetPenStyle(CGraphicsContext::ESolidPen); + + // Draw lines as pairs of points (start, end) + for (TInt i = 0; i < aCount - 1; i += 2) { + TPoint start(aVerts[i].x, aVerts[i].y); + TPoint end(aVerts[i + 1].x, aVerts[i + 1].y); + + TRgb color = TRgb(aVerts[i].color.r, aVerts[i].color.g, aVerts[i].color.b); + + gc->SetPenColor(color); + gc->DrawLine(start, end); } - - // Fill points from vertex data. - for (TInt i = 0; i < aCount; i++) { - iLinePointsBuffer[i] = TPoint(aVerts[i].x, aVerts[i].y); - } - - // Pack color once - all vertices use the same color in polyline. - Uint8 ca = aVerts->color.a; - Uint8 cr = aVerts->color.r; - Uint8 cg = aVerts->color.g; - Uint8 cb = aVerts->color.b; - TUint32 aColor = (ca << 24) | (cb << 16) | (cg << 8) | cr; - - iRenderer->Gc()->SetPenColor(aColor); - iRenderer->Gc()->DrawPolyLineNoEndPoint(iLinePointsBuffer, aCount); } } void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) { - if (iRenderer && iRenderer->Gc()) { - // Batch points by color to minimize SetPenColor calls. - TUint32 currentColor = 0; - bool colorSet = false; - + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { for (TInt i = 0; i < aCount; i++, aVerts++) { - TUint32 aColor = (TUint32(aVerts->color.a) << 24) | (TUint32(aVerts->color.b) << 16) | - (TUint32(aVerts->color.g) << 8) | TUint32(aVerts->color.r); + TUint32 aColor = (((TUint8)aVerts->color.a << 24) | + ((TUint8)aVerts->color.b << 16) | + ((TUint8)aVerts->color.g << 8) | + (TUint8)aVerts->color.r); - // Only set pen color when it changes. - if (!colorSet || aColor != currentColor) { - iRenderer->Gc()->SetPenColor(aColor); - currentColor = aColor; - colorSet = true; - } - - iRenderer->Gc()->Plot(TPoint(aVerts->x, aVerts->y)); + gc->SetPenColor(aColor); + gc->Plot(TPoint(aVerts->x, aVerts->y)); } } } void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) { - if (iRenderer && iRenderer->Gc()) { - // Batch rectangles by color to minimize SetPenColor/SetBrushColor calls. - TUint32 currentColor = 0; - bool colorSet = false; - - // Process rectangles (each rect uses 2 vertices: position and size). - for (TInt i = 0; i < aCount; i += 2) { + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + for (TInt i = 0; i < aCount; i++, aVerts++) { TPoint pos(aVerts[i].x, aVerts[i].y); - TSize size(aVerts[i + 1].x, aVerts[i + 1].y); + TSize size( + aVerts[i + 1].x, + aVerts[i + 1].y); TRect rect(pos, size); - TUint32 aColor = (TUint32(aVerts[i].color.a) << 24) | (TUint32(aVerts[i].color.b) << 16) | - (TUint32(aVerts[i].color.g) << 8) | TUint32(aVerts[i].color.r); + TUint32 aColor = (((TUint8)aVerts->color.a << 24) | + ((TUint8)aVerts->color.b << 16) | + ((TUint8)aVerts->color.g << 8) | + (TUint8)aVerts->color.r); - // Only set colors when they change. - if (!colorSet || aColor != currentColor) { - iRenderer->Gc()->SetPenColor(aColor); - iRenderer->Gc()->SetBrushColor(aColor); - currentColor = aColor; - colorSet = true; - } - - iRenderer->Gc()->DrawRect(rect); + gc->SetPenColor(aColor); + gc->SetBrushColor(aColor); + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetPenStyle(CGraphicsContext::ENullPen); + gc->DrawRect(rect); } } } @@ -862,65 +583,64 @@ void CRenderer::Flip() return; } + iRenderer->Gc()->UseFont(iFont); + if (iShowFPS && iRenderer->Gc()) { UpdateFPS(); - iRenderer->Gc()->UseFont(iFont); - TBuf<64> info; iRenderer->Gc()->SetPenStyle(CGraphicsContext::ESolidPen); - iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush); - iRenderer->Gc()->SetBrushColor(KRgbBlack); + iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ENullBrush); iRenderer->Gc()->SetPenColor(KRgbCyan); - // Draw FPS background and text. TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2)); + iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush); + iRenderer->Gc()->SetBrushColor(KRgbBlack); iRenderer->Gc()->DrawRect(aTextRect); + // Draw messages. info.Format(_L("FPS: %d"), iFPS); iRenderer->Gc()->DrawText(info, TPoint(5, 203)); - - iRenderer->Gc()->DiscardFont(); + } else { + // This is a workaround that helps regulating the FPS. + iRenderer->Gc()->DrawText(_L(""), TPoint(0, 0)); } - + iRenderer->Gc()->DiscardFont(); iRenderer->Flip(iDirectScreen); - // Keep the backlight on when screen saver is suspended. + // Keep the backlight on. if (iSuspendScreenSaver) { User::ResetInactivityTime(); } - - // Yield to other threads and active objects briefly. + // Suspend the current thread for a short while. + // Give some time to other threads and active objects. User::After(0); } void CRenderer::SetDrawColor(TUint32 iColor) { - if (iRenderer && iRenderer->Gc()) { - // Skip redundant calls if color hasn't changed. - if (iColor == iLastDrawColor) { - return; - } - - iRenderer->Gc()->SetPenColor(iColor); - iRenderer->Gc()->SetBrushColor(iColor); - iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush); + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + gc->SetPenColor(iColor); + gc->SetBrushColor(iColor); + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + } + if (iRenderer) { TRAPD(err, iRenderer->SetCurrentColor(iColor)); if (err != KErrNone) { return; } - - iLastDrawColor = iColor; } } void CRenderer::SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight) { - if (iRenderer && iRenderer->Gc()) { + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { TRect viewportRect(aX, aY, aX + aWidth, aY + aHeight); - iRenderer->Gc()->SetClippingRect(viewportRect); + gc->SetClippingRect(viewportRect); } } @@ -928,17 +648,10 @@ void CRenderer::UpdateFPS() { static TTime lastTime; static TInt frameCount = 0; - static TBool initialized = EFalse; TTime currentTime; - const TUint KOneSecond = 1000000; // 1s in microseconds. + const TUint KOneSecond = 1000000; // 1s in ms. currentTime.HomeTime(); - - if (!initialized) { - lastTime = currentTime; - initialized = ETrue; - } - ++frameCount; TTimeIntervalMicroSeconds timeDiff = currentTime.MicroSecondsFrom(lastTime); @@ -958,6 +671,19 @@ void CRenderer::SuspendScreenSaver(TBool aSuspend) iSuspendScreenSaver = aSuspend; } +void CRenderer::SetRenderTarget(NGAGE_TextureData *aTarget) +{ + iCurrentRenderTarget = aTarget; +} + +CFbsBitGc *CRenderer::GetCurrentGc() +{ + if (iCurrentRenderTarget && iCurrentRenderTarget->gc) { + return iCurrentRenderTarget->gc; + } + return iRenderer ? iRenderer->Gc() : NULL; +} + static SDL_Scancode ConvertScancode(int key) { SDL_Keycode keycode; @@ -1058,8 +784,8 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent) case EEventKeyUp: /* Key events */ timestamp = SDL_GetPerformanceCounter(); SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), false); - break; + break; case EEventFocusGained: DisableKeyBlocking(); if (!iDirectScreen->IsActive()) { diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index fa87a34f30..20f1af17cf 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -34,6 +34,7 @@ extern "C" { typedef struct NGAGE_RendererData { SDL_Rect *viewport; + SDL_Texture *current_target; } NGAGE_RendererData; @@ -54,23 +55,14 @@ typedef struct NGAGE_Vertex } NGAGE_Vertex; typedef struct CFbsBitmap CFbsBitmap; +typedef struct CFbsBitGc CFbsBitGc; +typedef struct CFbsDevice CFbsDevice; typedef struct NGAGE_TextureData { CFbsBitmap *bitmap; - - // Cached properties to avoid repeated API calls. - int cachedWidth; - int cachedHeight; - int cachedPitch; - void *cachedDataAddress; - - // Cardinal rotation cache (0°, 90°, 180°, 270°) - created on demand. - CFbsBitmap *cardinalRotations[4]; - - // Dirty tracking to avoid redundant rendering. - bool isDirty; - SDL_Rect dirtyRect; + CFbsBitGc *gc; + CFbsDevice *device; } NGAGE_TextureData; @@ -99,12 +91,9 @@ void NGAGE_Clear(const Uint32 color); Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale); bool NGAGE_Copy(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Rect *srcrect, SDL_Rect *dstrect); bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData *copydata); -bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height); +bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height, const int access); void NGAGE_DestroyTextureData(NGAGE_TextureData *data); -void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); -int NGAGE_GetBitmapPitch(NGAGE_TextureData *data); -int NGAGE_GetBitmapWidth(NGAGE_TextureData *data); -int NGAGE_GetBitmapHeight(NGAGE_TextureData *data); +void* NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count); void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count); void NGAGE_FillRects(NGAGE_Vertex *verts, const int count); @@ -113,6 +102,7 @@ void NGAGE_SetClipRect(const SDL_Rect *rect); void NGAGE_SetDrawColor(const Uint32 color); void NGAGE_PumpEventsInternal(void); void NGAGE_SuspendScreenSaverInternal(bool suspend); +void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target); #ifdef __cplusplus } diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 7fbfc88799..b7776ec589 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -23,7 +23,6 @@ #define ngage_video_render_ngage_c_hpp #include "SDL_render_ngage_c.h" -#include <3dtypes.h> #include #include #include @@ -38,7 +37,7 @@ class CRenderer : public MDirectScreenAccess void Clear(TUint32 iColor); bool Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect); bool CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE_CopyExData *copydata); - bool CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight); + bool CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight, const TInt aAccess); void DrawLines(NGAGE_Vertex *aVerts, const TInt aCount); void DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount); void FillRects(NGAGE_Vertex *aVerts, const TInt aCount); @@ -48,6 +47,10 @@ class CRenderer : public MDirectScreenAccess void UpdateFPS(); void SuspendScreenSaver(TBool aSuspend); + // Render target management. + void SetRenderTarget(NGAGE_TextureData *aTarget); + CFbsBitGc* GetCurrentGc(); + // Event handling. void DisableKeyBlocking(); void HandleEvent(const TWsEvent &aWsEvent); @@ -88,38 +91,15 @@ class CRenderer : public MDirectScreenAccess // Screen saver. TBool iSuspendScreenSaver; - // Work buffers for texture transformations (reusable to avoid per-frame allocations). - void *iWorkBuffer1; - void *iWorkBuffer2; - TInt iWorkBufferSize; + // Render target. + NGAGE_TextureData *iCurrentRenderTarget; - // Temporary render bitmap to avoid destroying source textures. - CFbsBitmap *iTempRenderBitmap; - TInt iTempRenderBitmapWidth; - TInt iTempRenderBitmapHeight; - - // Color modulation lookup tables (pre-calculated to avoid per-pixel FixMul). - TUint8 iColorModLUT[768]; // 256 entries each for R, G, B - TFixed iLastColorR; - TFixed iLastColorG; - TFixed iLastColorB; - - // Reusable line points buffer to avoid per-frame allocations in DrawLines. - TPoint *iLinePointsBuffer; - TInt iLinePointsBufferCapacity; - - // Cached draw color to avoid redundant SetPenColor/SetBrushColor calls. - TUint32 iLastDrawColor; - - // Cached clear color to avoid redundant SetBrushColor calls. - TUint32 iLastClearColor; - - // Helper methods. - bool EnsureWorkBufferCapacity(TInt aRequiredSize); - bool EnsureTempBitmapCapacity(TInt aWidth, TInt aHeight); - bool EnsureLinePointsCapacity(TInt aRequiredCount); - void BuildColorModLUT(TFixed rf, TFixed gf, TFixed bf); - CFbsBitmap *GetCardinalRotation(NGAGE_TextureData *aTextureData, TInt aAngleIndex); + // Persistent buffers to avoid per-frame allocations. + void *iPixelBufferA; + void *iPixelBufferB; + TInt iPixelBufferSize; + TPoint *iPointsBuffer; + TInt iPointsBufferSize; }; #endif // ngage_video_render_ngage_c_hpp diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 6bb925749c..3b998d8132 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -23,65 +23,43 @@ #include "SDL_render_ops.hpp" #include <3dtypes.h> -void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color, const TUint8 *colorLUT) +void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color) { TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - // Pre-calculate pitch in pixels to avoid repeated division. - const TInt pitchPixels = pitch >> 1; - - // Pre-calculate LUT offsets to reduce addressing calculations. - const TUint8 *lut_r = colorLUT; - const TUint8 *lut_g = colorLUT + 256; - const TUint8 *lut_b = colorLUT + 512; - - // Process 4 pixels at a time. - for (int y = 0; y < height; ++y) { - const TInt rowOffset = y * pitchPixels; - int x = 0; - - // Process 4 pixels at once with optimized bit manipulation. - for (; x < width - 3; x += 4) { - // Load 4 pixels at once. - TUint16 p0 = src_pixels[rowOffset + x]; - TUint16 p1 = src_pixels[rowOffset + x + 1]; - TUint16 p2 = src_pixels[rowOffset + x + 2]; - TUint16 p3 = src_pixels[rowOffset + x + 3]; - - // Pixel 0: Extract and modulate RGB4444 components. - // RGB4444 format: RRRR GGGG BBBB xxxx - TUint8 r0 = lut_r[(p0 >> 8) & 0xF0]; // Extract R (bits 12-15), shift to byte position - TUint8 g0 = lut_g[(p0 >> 3) & 0xF8]; // Extract G (bits 6-9), scale to 8-bit - TUint8 b0 = lut_b[(p0 << 3) & 0xF8]; // Extract B (bits 0-3), scale to 8-bit - dst_pixels[rowOffset + x] = ((r0 & 0xF0) << 8) | ((g0 & 0xF0) << 3) | ((b0 & 0xF0) >> 1); - - // Pixel 1 - TUint8 r1 = lut_r[(p1 >> 8) & 0xF0]; - TUint8 g1 = lut_g[(p1 >> 3) & 0xF8]; - TUint8 b1 = lut_b[(p1 << 3) & 0xF8]; - dst_pixels[rowOffset + x + 1] = ((r1 & 0xF0) << 8) | ((g1 & 0xF0) << 3) | ((b1 & 0xF0) >> 1); - - // Pixel 2 - TUint8 r2 = lut_r[(p2 >> 8) & 0xF0]; - TUint8 g2 = lut_g[(p2 >> 3) & 0xF8]; - TUint8 b2 = lut_b[(p2 << 3) & 0xF8]; - dst_pixels[rowOffset + x + 2] = ((r2 & 0xF0) << 8) | ((g2 & 0xF0) << 3) | ((b2 & 0xF0) >> 1); - - // Pixel 3 - TUint8 r3 = lut_r[(p3 >> 8) & 0xF0]; - TUint8 g3 = lut_g[(p3 >> 3) & 0xF8]; - TUint8 b3 = lut_b[(p3 << 3) & 0xF8]; - dst_pixels[rowOffset + x + 3] = ((r3 & 0xF0) << 8) | ((g3 & 0xF0) << 3) | ((b3 & 0xF0) >> 1); + // Fast path: no color modulation (white color). + if (color.r == 1.0f && color.g == 1.0f && color.b == 1.0f) { + if (dest != source) { + for (int y = 0; y < height; ++y) { + TUint16 *src_row = src_pixels + (y * pitch / 2); + TUint16 *dst_row = dst_pixels + (y * pitch / 2); + for (int x = 0; x < width; ++x) { + dst_row[x] = src_row[x]; + } + } } + return; + } - // Handle remaining pixels. - for (; x < width; ++x) { - TUint16 pixel = src_pixels[rowOffset + x]; - TUint8 r = lut_r[(pixel >> 8) & 0xF0]; - TUint8 g = lut_g[(pixel >> 3) & 0xF8]; - TUint8 b = lut_b[(pixel << 3) & 0xF8]; - dst_pixels[rowOffset + x] = ((r & 0xF0) << 8) | ((g & 0xF0) << 3) | ((b & 0xF0) >> 1); + TFixed rf = Real2Fix(color.r); + TFixed gf = Real2Fix(color.g); + TFixed bf = Real2Fix(color.b); + + int pitch_offset = pitch / 2; + + for (int y = 0; y < height; ++y) { + int row_offset = y * pitch_offset; + for (int x = 0; x < width; ++x) { + int idx = row_offset + x; + TUint16 pixel = src_pixels[idx]; + TUint8 r = (pixel & 0xF800) >> 8; + TUint8 g = (pixel & 0x07E0) >> 3; + TUint8 b = (pixel & 0x001F) << 3; + r = FixMul(r, rf); + g = FixMul(g, gf); + b = FixMul(b, bf); + dst_pixels[idx] = (r << 8) | (g << 3) | (b >> 3); } } } @@ -91,62 +69,56 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - // Pre-calculate pitch in pixels to avoid repeated division. - const TInt pitchPixels = pitch >> 1; - - // Pre-calculate flip flags to avoid repeated bitwise operations. - const bool flipHorizontal = (flip & SDL_FLIP_HORIZONTAL) != 0; - const bool flipVertical = (flip & SDL_FLIP_VERTICAL) != 0; - - // Fast path: No flip; just copy entire buffer. - if (!flipHorizontal && !flipVertical) { - Mem::Copy(dest, source, pitch * height); - return; - } - - // Fast path: Vertical-only flip; copy rows in reverse order. - if (flipVertical && !flipHorizontal) { - for (int y = 0; y < height; ++y) { - const int src_y = height - 1 - y; - Mem::Copy(&dst_pixels[y * pitchPixels], &src_pixels[src_y * pitchPixels], pitch); - } - return; - } - - // Slow path: Horizontal or both flips; need pixel-level operations. - // Pre-calculate width/height bounds for horizontal/vertical flipping. - const int width_m1 = width - 1; - const int height_m1 = height - 1; - - for (int y = 0; y < height; ++y) { - // Calculate destination row offset once per row. - const TInt dstRowOffset = y * pitchPixels; - - // Calculate source Y coordinate once per row. - const int src_y = flipVertical ? (height_m1 - y) : y; - const TInt srcRowOffset = src_y * pitchPixels; - - int x = 0; - - // Process 4 pixels at once. - for (; x < width - 3; x += 4) { - if (flipHorizontal) { - dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + (width_m1 - x)]; - dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + (width_m1 - x - 1)]; - dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + (width_m1 - x - 2)]; - dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + (width_m1 - x - 3)]; - } else { - dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + x]; - dst_pixels[dstRowOffset + x + 1] = src_pixels[srcRowOffset + x + 1]; - dst_pixels[dstRowOffset + x + 2] = src_pixels[srcRowOffset + x + 2]; - dst_pixels[dstRowOffset + x + 3] = src_pixels[srcRowOffset + x + 3]; + // Fast path: no flip. + if (flip == SDL_FLIP_NONE) { + if (dest != source) { + for (int y = 0; y < height; ++y) { + TUint16 *src_row = src_pixels + (y * pitch / 2); + TUint16 *dst_row = dst_pixels + (y * pitch / 2); + for (int x = 0; x < width; ++x) { + dst_row[x] = src_row[x]; + } } } + return; + } - // Handle remaining pixels. - for (; x < width; ++x) { - const int src_x = flipHorizontal ? (width_m1 - x) : x; - dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + src_x]; + int pitch_offset = pitch / 2; + + // Fast path: horizontal flip only. + if (flip == SDL_FLIP_HORIZONTAL) { + for (int y = 0; y < height; ++y) { + int dst_row_offset = y * pitch_offset; + int src_row_offset = y * pitch_offset; + int width_minus_1 = width - 1; + for (int x = 0; x < width; ++x) { + dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; + } + } + return; + } + + // Fast path: vertical flip only. + if (flip == SDL_FLIP_VERTICAL) { + int height_minus_1 = height - 1; + for (int y = 0; y < height; ++y) { + int dst_row_offset = y * pitch_offset; + int src_row_offset = (height_minus_1 - y) * pitch_offset; + for (int x = 0; x < width; ++x) { + dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + x]; + } + } + return; + } + + // Both horizontal and vertical flip + int width_minus_1 = width - 1; + int height_minus_1 = height - 1; + for (int y = 0; y < height; ++y) { + int dst_row_offset = y * pitch_offset; + int src_row_offset = (height_minus_1 - y) * pitch_offset; + for (int x = 0; x < width; ++x) { + dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; } } } @@ -156,152 +128,151 @@ void ApplyRotation(void *dest, void *source, int pitch, int width, int height, T TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - TFixed cos_angle = 0; - TFixed sin_angle = 0; - - if (angle != 0) { - FixSinCos(angle, sin_angle, cos_angle); - } - - // Pre-calculate pitch in pixels to avoid repeated division. - const TInt pitchPixels = pitch >> 1; - - // Pre-check if rotation keeps all pixels within bounds to skip per-pixel checks. - // Calculate the four corners of the image after rotation around center. - bool allInBounds = true; - if (angle != 0) { - // Check corners: (0,0), (width-1,0), (0,height-1), (width-1,height-1) - TFixed corners_x[4] = { -center_x, Int2Fix(width - 1) - center_x, -center_x, Int2Fix(width - 1) - center_x }; - TFixed corners_y[4] = { -center_y, -center_y, Int2Fix(height - 1) - center_y, Int2Fix(height - 1) - center_y }; - - for (int i = 0; i < 4; ++i) { - TFixed rot_x = FixMul(corners_x[i], cos_angle) - FixMul(corners_y[i], sin_angle) + center_x; - TFixed rot_y = FixMul(corners_x[i], sin_angle) + FixMul(corners_y[i], cos_angle) + center_y; - int final_x = Fix2Int(rot_x); - int final_y = Fix2Int(rot_y); - - if (final_x < 0 || final_x >= width || final_y < 0 || final_y >= height) { - allInBounds = false; - break; + // Fast path: no rotation. + if (angle == 0) { + if (dest != source) { + int pitch_offset = pitch / 2; + for (int y = 0; y < height; ++y) { + TUint16 *src_row = src_pixels + (y * pitch_offset); + TUint16 *dst_row = dst_pixels + (y * pitch_offset); + for (int x = 0; x < width; ++x) { + dst_row[x] = src_row[x]; + } } } + return; } - // Incremental DDA: Calculate per-pixel increments. - // As we move right (x+1), the rotated position changes by (cos, -sin). - const TFixed dx_cos = cos_angle; - const TFixed dx_sin = -sin_angle; + // Fast paths for 90-degree rotations + TFixed angle_90 = Int2Fix(90); + TFixed angle_180 = Int2Fix(180); + TFixed angle_270 = Int2Fix(270); + TFixed angle_360 = Int2Fix(360); + + // Normalize angle to 0-360 range + TFixed normalized_angle = angle; + while (normalized_angle < 0) { + normalized_angle += angle_360; + } + while (normalized_angle >= angle_360) { + normalized_angle -= angle_360; + } + + int pitch_offset = pitch / 2; + + // Fast path: 90-degree rotation (clockwise). + if (normalized_angle == angle_90) { + TFixed center_x_int = Fix2Int(center_x); + TFixed center_y_int = Fix2Int(center_y); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + // Translate to origin. + int tx = x - center_x_int; + int ty = y - center_y_int; + // Rotate 90 degrees clockwise: (x, y) -> (y, -x). + int rx = ty; + int ry = -tx; + // Translate back. + int src_x = rx + center_x_int; + int src_y = ry + center_y_int; + if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { + dst_pixels[y * pitch_offset + x] = src_pixels[src_y * pitch_offset + src_x]; + } else { + dst_pixels[y * pitch_offset + x] = 0; + } + } + } + return; + } + + // Fast path: 180-degree rotation. + if (normalized_angle == angle_180) { + TFixed center_x_int = Fix2Int(center_x); + TFixed center_y_int = Fix2Int(center_y); + for (int y = 0; y < height; ++y) { + int dst_row_offset = y * pitch_offset; + for (int x = 0; x < width; ++x) { + // Translate to origin + int tx = x - center_x_int; + int ty = y - center_y_int; + // Rotate 180 degrees: (x, y) -> (-x, -y) + int rx = -tx; + int ry = -ty; + // Translate back + int src_x = rx + center_x_int; + int src_y = ry + center_y_int; + if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { + dst_pixels[dst_row_offset + x] = src_pixels[src_y * pitch_offset + src_x]; + } else { + dst_pixels[dst_row_offset + x] = 0; + } + } + } + return; + } + + // Fast path: 270-degree rotation (clockwise). + if (normalized_angle == angle_270) { + TFixed center_x_int = Fix2Int(center_x); + TFixed center_y_int = Fix2Int(center_y); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + // Translate to origin. + int tx = x - center_x_int; + int ty = y - center_y_int; + // Rotate 270 degrees clockwise (or 90 counter-clockwise): (x, y) -> (-y, x). + int rx = -ty; + int ry = tx; + // Translate back. + int src_x = rx + center_x_int; + int src_y = ry + center_y_int; + if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { + dst_pixels[y * pitch_offset + x] = src_pixels[src_y * pitch_offset + src_x]; + } else { + dst_pixels[y * pitch_offset + x] = 0; + } + } + } + return; + } + + TFixed cos_angle = 0; + TFixed sin_angle = 0; + FixSinCos(angle, sin_angle, cos_angle); + + // Pre-calculate the translation of center to origin. + TFixed neg_center_x = -center_x; + TFixed neg_center_y = -center_y; for (int y = 0; y < height; ++y) { - // Calculate destination row offset once per row. - const TInt dstRowOffset = y * pitchPixels; + int dst_row_offset = y * pitch_offset; + TFixed y_fixed = Int2Fix(y) + neg_center_y; - // Calculate starting position for this row. - // For y, rotation transforms: x' = x*cos - y*sin, y' = x*sin + y*cos - // At x=0: x' = -y*sin, y' = y*cos (relative to center) - const TFixed translated_y = Int2Fix(y) - center_y; - const TFixed row_start_x = center_x - FixMul(translated_y, sin_angle); - const TFixed row_start_y = center_y + FixMul(translated_y, cos_angle); + // Pre-calculate these values for the entire row. + TFixed cos_mul_ty = FixMul(y_fixed, cos_angle); + TFixed sin_mul_ty = FixMul(y_fixed, sin_angle); - // Start at x=0 position. - TFixed src_x = row_start_x; - TFixed src_y = row_start_y; + // Starting position for the row (x=0). + // rotated_x = cos(angle) * (0 - center_x) + sin(angle) * (y - center_y) + center_x + // rotated_y = cos(angle) * (y - center_y) - sin(angle) * (0 - center_x) + center_y + TFixed rotated_x = sin_mul_ty + center_x + FixMul(neg_center_x, cos_angle); + TFixed rotated_y = cos_mul_ty + center_y - FixMul(neg_center_x, sin_angle); - int x = 0; + for (int x = 0; x < width; ++x) { + // Convert to integer coordinates. + int final_x = Fix2Int(rotated_x); + int final_y = Fix2Int(rotated_y); - if (allInBounds) { - // Fast path: No bounds checking needed. - for (; x < width - 3; x += 4) { - // Pixel 0 - int final_x0 = Fix2Int(src_x); - int final_y0 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 1 - int final_x1 = Fix2Int(src_x); - int final_y1 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 2 - int final_x2 = Fix2Int(src_x); - int final_y2 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 3 - int final_x3 = Fix2Int(src_x); - int final_y3 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Write all 4 pixels without bounds checking. - dst_pixels[dstRowOffset + x] = src_pixels[final_y0 * pitchPixels + final_x0]; - dst_pixels[dstRowOffset + x + 1] = src_pixels[final_y1 * pitchPixels + final_x1]; - dst_pixels[dstRowOffset + x + 2] = src_pixels[final_y2 * pitchPixels + final_x2]; - dst_pixels[dstRowOffset + x + 3] = src_pixels[final_y3 * pitchPixels + final_x3]; + // Check bounds and copy pixel. + if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { + dst_pixels[dst_row_offset + x] = src_pixels[final_y * pitch_offset + final_x]; + } else { + dst_pixels[dst_row_offset + x] = 0; } - // Handle remaining pixels. - for (; x < width; ++x) { - int final_x = Fix2Int(src_x); - int final_y = Fix2Int(src_y); - dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; - src_x += dx_cos; - src_y += dx_sin; - } - } else { - // Slow path: Bounds checking required. - for (; x < width - 3; x += 4) { - // Pixel 0 - int final_x0 = Fix2Int(src_x); - int final_y0 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 1 - int final_x1 = Fix2Int(src_x); - int final_y1 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 2 - int final_x2 = Fix2Int(src_x); - int final_y2 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Pixel 3 - int final_x3 = Fix2Int(src_x); - int final_y3 = Fix2Int(src_y); - src_x += dx_cos; - src_y += dx_sin; - - // Write all 4 pixels with bounds checking. - dst_pixels[dstRowOffset + x] = (final_x0 >= 0 && final_x0 < width && final_y0 >= 0 && final_y0 < height) ? src_pixels[final_y0 * pitchPixels + final_x0] : 0; - dst_pixels[dstRowOffset + x + 1] = (final_x1 >= 0 && final_x1 < width && final_y1 >= 0 && final_y1 < height) ? src_pixels[final_y1 * pitchPixels + final_x1] : 0; - dst_pixels[dstRowOffset + x + 2] = (final_x2 >= 0 && final_x2 < width && final_y2 >= 0 && final_y2 < height) ? src_pixels[final_y2 * pitchPixels + final_x2] : 0; - dst_pixels[dstRowOffset + x + 3] = (final_x3 >= 0 && final_x3 < width && final_y3 >= 0 && final_y3 < height) ? src_pixels[final_y3 * pitchPixels + final_x3] : 0; - } - - // Handle remaining pixels. - for (; x < width; ++x) { - // Convert to integer coordinates. - int final_x = Fix2Int(src_x); - int final_y = Fix2Int(src_y); - - // Check bounds. - if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { - dst_pixels[dstRowOffset + x] = src_pixels[final_y * pitchPixels + final_x]; - } else { - dst_pixels[dstRowOffset + x] = 0; - } - - // Incremental step: move to next pixel (just additions, no multiplications!). - src_x += dx_cos; - src_y += dx_sin; - } + // Increment to next pixel (add rotation matrix column). + rotated_x += cos_angle; + rotated_y -= sin_angle; } } } @@ -311,72 +282,46 @@ void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFix TUint16 *src_pixels = static_cast(source); TUint16 *dst_pixels = static_cast(dest); - // Fast path: Identity scale; just copy entire buffer. - const TFixed identity = Int2Fix(1); - if (scale_x == identity && scale_y == identity) { - Mem::Copy(dest, source, pitch * height); + TFixed one_fixed = Int2Fix(1); + + // Fast path: no scaling (1.0x scale). + if (scale_x == one_fixed && scale_y == one_fixed) { + if (dest != source) { + for (int y = 0; y < height; ++y) { + TUint16 *src_row = src_pixels + (y * pitch / 2); + TUint16 *dst_row = dst_pixels + (y * pitch / 2); + for (int x = 0; x < width; ++x) { + dst_row[x] = src_row[x]; + } + } + } return; } - // Pre-calculate pitch in pixels to avoid repeated division. - const TInt pitchPixels = pitch >> 1; - - // Pre-calculate inverse scale factors to use FixMul instead of FixDiv. - // This is MUCH faster on N-Gage hardware (no division per pixel!). - TFixed inv_scale_x = FixDiv(Int2Fix(1), scale_x); - TFixed inv_scale_y = FixDiv(Int2Fix(1), scale_y); - - // Pre-calculate center offset to reduce operations per pixel. - TFixed center_x_fixed = center_x; - TFixed center_y_fixed = center_y; + int pitch_offset = pitch / 2; for (int y = 0; y < height; ++y) { - // Calculate destination row offset once per row. - TInt dstRowOffset = y * pitchPixels; + int dst_row_offset = y * pitch_offset; + TFixed y_fixed = Int2Fix(y); + TFixed translated_y = y_fixed - center_y; + TFixed scaled_y = FixDiv(translated_y, scale_y); - // Use inverse scale factor (multiply instead of divide). - TFixed translated_y = Int2Fix(y) - center_y_fixed; - TFixed scaled_y = FixMul(translated_y, inv_scale_y); - int final_y = Fix2Int(scaled_y + center_y_fixed); + for (int x = 0; x < width; ++x) { + // Translate point to origin. + TFixed translated_x = Int2Fix(x) - center_x; - // Check if this row is within bounds. - bool rowInBounds = (final_y >= 0 && final_y < height); - TInt srcRowOffset = final_y * pitchPixels; + // Scale point. + TFixed scaled_x = FixDiv(translated_x, scale_x); - // Incremental DDA for X: pre-calculate starting position and increment. - TFixed src_x_start = FixMul(-center_x_fixed, inv_scale_x) + center_x_fixed; - TFixed src_x = src_x_start; + // Translate point back. + int final_x = Fix2Int(scaled_x + center_x); + int final_y = Fix2Int(scaled_y + center_y); - int x = 0; - - // Process 4 pixels at once. - for (; x < width - 3; x += 4) { - // Process 4 pixels using incremental approach. - int final_x0 = Fix2Int(src_x); - src_x += inv_scale_x; - int final_x1 = Fix2Int(src_x); - src_x += inv_scale_x; - int final_x2 = Fix2Int(src_x); - src_x += inv_scale_x; - int final_x3 = Fix2Int(src_x); - src_x += inv_scale_x; - - // Write all 4 pixels with bounds checking. - dst_pixels[dstRowOffset + x] = (rowInBounds && final_x0 >= 0 && final_x0 < width) ? src_pixels[srcRowOffset + final_x0] : 0; - dst_pixels[dstRowOffset + x + 1] = (rowInBounds && final_x1 >= 0 && final_x1 < width) ? src_pixels[srcRowOffset + final_x1] : 0; - dst_pixels[dstRowOffset + x + 2] = (rowInBounds && final_x2 >= 0 && final_x2 < width) ? src_pixels[srcRowOffset + final_x2] : 0; - dst_pixels[dstRowOffset + x + 3] = (rowInBounds && final_x3 >= 0 && final_x3 < width) ? src_pixels[srcRowOffset + final_x3] : 0; - } - - // Handle remaining pixels. - for (; x < width; ++x) { - int final_x = Fix2Int(src_x); - src_x += inv_scale_x; - - if (rowInBounds && final_x >= 0 && final_x < width) { - dst_pixels[dstRowOffset + x] = src_pixels[srcRowOffset + final_x]; + // Check bounds. + if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { + dst_pixels[dst_row_offset + x] = src_pixels[final_y * pitch_offset + final_x]; } else { - dst_pixels[dstRowOffset + x] = 0; + dst_pixels[dst_row_offset + x] = 0; } } } diff --git a/src/render/ngage/SDL_render_ops.hpp b/src/render/ngage/SDL_render_ops.hpp index ae580f65e7..65e92e5bca 100644 --- a/src/render/ngage/SDL_render_ops.hpp +++ b/src/render/ngage/SDL_render_ops.hpp @@ -24,7 +24,7 @@ #include <3dtypes.h> -void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color, const TUint8 *colorLUT); +void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color); void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_FlipMode flip); void ApplyRotation(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle); void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y); From 509a36db1648dfb69a644a26db1cf40264c16839 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 11 Apr 2026 13:44:35 -0500 Subject: [PATCH 131/407] atomic: Fix missing full memory barrier on GCC/Clang __sync_lock_test_and_set() is designed for creating locks, not as a general atomic exchange function. As a result, it only provides an acquire memory barrier and isn't guaranteed to actually store the provided value (though it does on architectures we care about). __atomic_exchange_n() is supported on GCC/Clang for the last ~10 years, so let's use that instead if available. We will keep the __sync_lock_test_and_set() fallback around for ancient platforms, but add a full memory barrier to match the documented behavior. --- CMakeLists.txt | 1 + src/atomic/SDL_atomic.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 350d5c747e..111e0cb0b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3251,6 +3251,7 @@ elseif(PS2) gskit dmakit ps2_drivers + atomic ) elseif(N3DS) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/n3ds/*.c") diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index e8a013c0aa..ee036fee8d 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -33,12 +33,18 @@ #include #endif -// The __atomic_load_n() intrinsic showed up in different times for different compilers. -#if defined(__GNUC__) && (__GNUC__ >= 5) +// The __atomic intrinsics showed up in different times for different compilers. +#if (defined(__GNUC__) && (__GNUC__ >= 5)) || (defined(__clang__) && defined(HAVE_GCC_ATOMICS)) #define HAVE_ATOMIC_LOAD_N 1 -#elif SDL_HAS_BUILTIN(__atomic_load_n) || (defined(__clang__) && defined(HAVE_GCC_ATOMICS)) +#define HAVE_ATOMIC_EXCHANGE_N 1 +#else +#if SDL_HAS_BUILTIN(__atomic_load_n) #define HAVE_ATOMIC_LOAD_N 1 #endif +#if SDL_HAS_BUILTIN(__atomic_exchange_n) +#define HAVE_ATOMIC_EXCHANGE_N 1 +#endif +#endif /* If any of the operations are not provided then we must emulate some @@ -174,7 +180,14 @@ int SDL_SetAtomicInt(SDL_AtomicInt *a, int v) #ifdef HAVE_MSC_ATOMICS SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); return _InterlockedExchange((long *)&a->value, v); +#elif defined(HAVE_ATOMIC_EXCHANGE_N) + return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); #elif defined(HAVE_GCC_ATOMICS) + // __sync_lock_test_and_set() is designed for locking rather than a + // generic atomic exchange, so it only provides an acquire barrier + // and may not store the exact value on all architectures. We prefer + // __atomic_exchange_n() instead on all modern compilers. + __sync_synchronize(); return __sync_lock_test_and_set(&a->value, v); #elif defined(SDL_PLATFORM_SOLARIS) SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(uint_t) == sizeof(a->value)); @@ -193,7 +206,14 @@ Uint32 SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v) #ifdef HAVE_MSC_ATOMICS SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); return _InterlockedExchange((long *)&a->value, v); +#elif defined(HAVE_ATOMIC_EXCHANGE_N) + return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); #elif defined(HAVE_GCC_ATOMICS) + // __sync_lock_test_and_set() is designed for locking rather than a + // generic atomic exchange, so it only provides an acquire barrier + // and may not store the exact value on all architectures. We prefer + // __atomic_exchange_n() instead on all modern compilers. + __sync_synchronize(); return __sync_lock_test_and_set(&a->value, v); #elif defined(SDL_PLATFORM_SOLARIS) SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(uint_t) == sizeof(a->value)); @@ -211,7 +231,14 @@ void *SDL_SetAtomicPointer(void **a, void *v) { #ifdef HAVE_MSC_ATOMICS return _InterlockedExchangePointer(a, v); +#elif defined(HAVE_ATOMIC_EXCHANGE_N) + return __atomic_exchange_n(a, v, __ATOMIC_SEQ_CST); #elif defined(HAVE_GCC_ATOMICS) + // __sync_lock_test_and_set() is designed for locking rather than a + // generic atomic exchange, so it only provides an acquire barrier + // and may not store the exact value on all architectures. We prefer + // __atomic_exchange_n() instead on all modern compilers. + __sync_synchronize(); return __sync_lock_test_and_set(a, v); #elif defined(SDL_PLATFORM_SOLARIS) return atomic_swap_ptr(a, v); From 43c928ee86afa45e460adbd0e39bb72d92fc5dd6 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 18 Apr 2026 19:26:55 +0100 Subject: [PATCH 132/407] Improve constness with Clipboard APIs --- include/SDL3/SDL_clipboard.h | 2 +- src/dynapi/SDL_dynapi_procs.h | 2 +- src/video/SDL_clipboard.c | 16 ++++++++-------- src/video/SDL_clipboard_c.h | 4 ++-- src/video/SDL_sysvideo.h | 2 +- src/video/wayland/SDL_waylandclipboard.c | 6 +++--- src/video/wayland/SDL_waylandclipboard.h | 2 +- src/video/wayland/SDL_waylanddatamanager.c | 2 +- src/video/wayland/SDL_waylanddatamanager.h | 2 +- src/video/wayland/SDL_waylandevents.c | 2 +- src/video/x11/SDL_x11clipboard.c | 6 +++--- src/video/x11/SDL_x11clipboard.h | 4 ++-- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/SDL3/SDL_clipboard.h b/include/SDL3/SDL_clipboard.h index 696825376a..487f9746cb 100644 --- a/include/SDL3/SDL_clipboard.h +++ b/include/SDL3/SDL_clipboard.h @@ -252,7 +252,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata); * \sa SDL_GetClipboardData * \sa SDL_HasClipboardData */ -extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types); +extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char *const *mime_types, size_t num_mime_types); /** * Clear the clipboard data. diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 203d9726c8..0d2d4ce5c7 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -830,7 +830,7 @@ SDL_DYNAPI_PROC(bool,SDL_SetAudioStreamInputChannelMap,(SDL_AudioStream *a, cons SDL_DYNAPI_PROC(bool,SDL_SetAudioStreamOutputChannelMap,(SDL_AudioStream *a, const int *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_SetAudioStreamPutCallback,(SDL_AudioStream *a, SDL_AudioStreamCallback b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_SetBooleanProperty,(SDL_PropertiesID a, const char *b, bool c),(a,b,c),return) -SDL_DYNAPI_PROC(bool,SDL_SetClipboardData,(SDL_ClipboardDataCallback a, SDL_ClipboardCleanupCallback b, void *c, const char **d, size_t e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(bool,SDL_SetClipboardData,(SDL_ClipboardDataCallback a, SDL_ClipboardCleanupCallback b, void *c, const char *const *d, size_t e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(bool,SDL_SetClipboardText,(const char *a),(a),return) SDL_DYNAPI_PROC(bool,SDL_SetCurrentThreadPriority,(SDL_ThreadPriority a),(a),return) SDL_DYNAPI_PROC(bool,SDL_SetCursor,(SDL_Cursor *a),(a),return) diff --git a/src/video/SDL_clipboard.c b/src/video/SDL_clipboard.c index d76bbfdcfe..a9887fda15 100644 --- a/src/video/SDL_clipboard.c +++ b/src/video/SDL_clipboard.c @@ -62,7 +62,7 @@ void SDL_CancelClipboardData(Uint32 sequence) _this->clipboard_userdata = NULL; } -bool SDL_SaveClipboardMimeTypes(const char **mime_types, size_t num_mime_types) +bool SDL_SaveClipboardMimeTypes(const char *const *mime_types, size_t num_mime_types) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -93,7 +93,7 @@ bool SDL_SaveClipboardMimeTypes(const char **mime_types, size_t num_mime_types) return true; } -bool SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types) +bool SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char *const *mime_types, size_t num_mime_types) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -265,7 +265,7 @@ bool SDL_HasClipboardData(const char *mime_type) } } -char **SDL_CopyClipboardMimeTypes(const char **clipboard_mime_types, size_t num_mime_types, bool temporary) +char **SDL_CopyClipboardMimeTypes(const char *const *clipboard_mime_types, size_t num_mime_types, bool temporary) { size_t allocSize = sizeof(char *); for (size_t i = 0; i < num_mime_types; i++) { @@ -326,12 +326,12 @@ bool SDL_IsTextMimeType(const char *mime_type) return (SDL_strncmp(mime_type, "text", 4) == 0); } -static const char **SDL_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) +static const char *const *SDL_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) { if (_this->GetTextMimeTypes) { return _this->GetTextMimeTypes(_this, num_mime_types); } else { - static const char *text_mime_types[] = { + static const char *const text_mime_types[] = { "text/plain;charset=utf-8" }; @@ -355,7 +355,7 @@ bool SDL_SetClipboardText(const char *text) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); size_t num_mime_types; - const char **text_mime_types; + const char *const *text_mime_types; if (!_this) { return SDL_UninitializedVideo(); @@ -373,7 +373,7 @@ char *SDL_GetClipboardText(void) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); size_t i, num_mime_types; - const char **text_mime_types; + const char *const *text_mime_types; size_t length; char *text = NULL; @@ -401,7 +401,7 @@ bool SDL_HasClipboardText(void) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); size_t i, num_mime_types; - const char **text_mime_types; + const char *const *text_mime_types; if (!_this) { return SDL_UninitializedVideo(); diff --git a/src/video/SDL_clipboard_c.h b/src/video/SDL_clipboard_c.h index b77788d828..d0476d1ffa 100644 --- a/src/video/SDL_clipboard_c.h +++ b/src/video/SDL_clipboard_c.h @@ -39,8 +39,8 @@ extern bool SDL_HasInternalClipboardData(SDL_VideoDevice *_this, const char *mim // General purpose clipboard text callback const void * SDLCALL SDL_ClipboardTextCallback(void *userdata, const char *mime_type, size_t *size); -bool SDL_SaveClipboardMimeTypes(const char **mime_types, size_t num_mime_types); +bool SDL_SaveClipboardMimeTypes(const char *const *mime_types, size_t num_mime_types); void SDL_FreeClipboardMimeTypes(SDL_VideoDevice *_this); -char **SDL_CopyClipboardMimeTypes(const char **clipboard_mime_types, size_t num_mime_types, bool temporary); +char **SDL_CopyClipboardMimeTypes(const char *const *clipboard_mime_types, size_t num_mime_types, bool temporary); #endif // SDL_clipboard_c_h_ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index a7c30a5f37..06aba744ad 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -376,7 +376,7 @@ struct SDL_VideoDevice void (*SetTextInputProperties)(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); // Clipboard - const char **(*GetTextMimeTypes)(SDL_VideoDevice *_this, size_t *num_mime_types); + const char *const *(*GetTextMimeTypes)(SDL_VideoDevice *_this, size_t *num_mime_types); bool (*SetClipboardData)(SDL_VideoDevice *_this); void *(*GetClipboardData)(SDL_VideoDevice *_this, const char *mime_type, size_t *size); bool (*HasClipboardData)(SDL_VideoDevice *_this, const char *mime_type); diff --git a/src/video/wayland/SDL_waylandclipboard.c b/src/video/wayland/SDL_waylandclipboard.c index 9e0dc79312..2f3d42319f 100644 --- a/src/video/wayland/SDL_waylandclipboard.c +++ b/src/video/wayland/SDL_waylandclipboard.c @@ -96,7 +96,7 @@ bool Wayland_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type) return result; } -static const char *text_mime_types[] = { +static const char *const text_mime_types[] = { TEXT_MIME, "text/plain", "TEXT", @@ -104,7 +104,7 @@ static const char *text_mime_types[] = { "STRING" }; -const char **Wayland_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) +const char *const *Wayland_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) { *num_mime_types = SDL_arraysize(text_mime_types); return text_mime_types; @@ -185,7 +185,7 @@ bool Wayland_HasPrimarySelectionText(SDL_VideoDevice *_this) result = true; } else { size_t mime_count = 0; - const char **mime_types = Wayland_GetTextMimeTypes(_this, &mime_count); + const char *const *mime_types = Wayland_GetTextMimeTypes(_this, &mime_count); for (size_t i = 0; i < mime_count; i++) { if (Wayland_primary_selection_offer_has_mime(primary_selection_device->selection_offer, mime_types[i])) { result = true; diff --git a/src/video/wayland/SDL_waylandclipboard.h b/src/video/wayland/SDL_waylandclipboard.h index e850345c20..b57636461e 100644 --- a/src/video/wayland/SDL_waylandclipboard.h +++ b/src/video/wayland/SDL_waylandclipboard.h @@ -23,7 +23,7 @@ #ifndef SDL_waylandclipboard_h_ #define SDL_waylandclipboard_h_ -extern const char **Wayland_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types); +extern const char *const *Wayland_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types); extern bool Wayland_SetClipboardData(SDL_VideoDevice *_this); extern void *Wayland_GetClipboardData(SDL_VideoDevice *_this, const char *mime_type, size_t *length); extern bool Wayland_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type); diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c index e4a040a817..6b9d045caf 100644 --- a/src/video/wayland/SDL_waylanddatamanager.c +++ b/src/video/wayland/SDL_waylanddatamanager.c @@ -705,7 +705,7 @@ bool Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device, bool Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDevice *primary_selection_device, SDL_WaylandPrimarySelectionSource *source, - const char **mime_types, + const char *const *mime_types, size_t mime_count) { bool result = true; diff --git a/src/video/wayland/SDL_waylanddatamanager.h b/src/video/wayland/SDL_waylanddatamanager.h index d7a863221b..1ac0dbfc2f 100644 --- a/src/video/wayland/SDL_waylanddatamanager.h +++ b/src/video/wayland/SDL_waylanddatamanager.h @@ -167,7 +167,7 @@ extern bool Wayland_data_device_set_selection(SDL_WaylandDataDevice *device, size_t mime_count); extern bool Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDevice *device, SDL_WaylandPrimarySelectionSource *source, - const char **mime_types, + const char *const *mime_types, size_t mime_count); extern void Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, uint32_t serial); diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 0f95d6d6a8..b974b7fe44 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -2824,7 +2824,7 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_ } size_t mime_count = 0; - const char **text_mime_types = Wayland_GetTextMimeTypes(SDL_GetVideoDevice(), &mime_count); + const char *const *text_mime_types = Wayland_GetTextMimeTypes(SDL_GetVideoDevice(), &mime_count); for (size_t i = 0; i < mime_count; ++i) { if (Wayland_data_offer_has_mime(data_device->drag_offer, text_mime_types[i])) { data_device->has_mime_text = true; diff --git a/src/video/x11/SDL_x11clipboard.c b/src/video/x11/SDL_x11clipboard.c index 601c42f279..8a79d13b77 100644 --- a/src/video/x11/SDL_x11clipboard.c +++ b/src/video/x11/SDL_x11clipboard.c @@ -29,7 +29,7 @@ #include "../SDL_clipboard_c.h" #include "../../events/SDL_events_c.h" -static const char *text_mime_types[] = { +static const char *const text_mime_types[] = { "UTF8_STRING", "text/plain;charset=utf-8", "text/plain", @@ -62,7 +62,7 @@ Window GetWindow(SDL_VideoDevice *_this) } static bool SetSelectionData(SDL_VideoDevice *_this, Atom selection, SDL_ClipboardDataCallback callback, - void *userdata, const char **mime_types, size_t mime_count, Uint32 sequence) + void *userdata, const char *const *mime_types, size_t mime_count, Uint32 sequence) { SDL_VideoData *videodata = _this->internal; Display *display = videodata->display; @@ -258,7 +258,7 @@ static void *GetSelectionData(SDL_VideoDevice *_this, Atom selection_type, return data; } -const char **X11_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) +const char *const *X11_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types) { *num_mime_types = SDL_arraysize(text_mime_types); return text_mime_types; diff --git a/src/video/x11/SDL_x11clipboard.h b/src/video/x11/SDL_x11clipboard.h index 0044515d06..70dc4f6994 100644 --- a/src/video/x11/SDL_x11clipboard.h +++ b/src/video/x11/SDL_x11clipboard.h @@ -28,12 +28,12 @@ typedef struct X11_ClipboardData { SDL_ClipboardDataCallback callback; void *userdata; - const char **mime_types; + const char *const *mime_types; size_t mime_count; Uint32 sequence; } SDLX11_ClipboardData; -extern const char **X11_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types); +extern const char *const *X11_GetTextMimeTypes(SDL_VideoDevice *_this, size_t *num_mime_types); extern bool X11_SetClipboardData(SDL_VideoDevice *_this); extern void *X11_GetClipboardData(SDL_VideoDevice *_this, const char *mime_type, size_t *length); extern bool X11_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type); From 1e1d80110eeb129ece00c10689591fa50e866e2b Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 10 Apr 2026 21:16:47 +0200 Subject: [PATCH 133/407] test: cannot access tracked allocation node without lock This fixes a SIGSEGV error under mulithreading. --- src/test/SDL_test_memory.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index d099c668c3..11b762e5d3 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -95,31 +95,36 @@ static unsigned int get_allocation_bucket(void *mem) return index; } -static SDL_tracked_allocation *SDL_GetTrackedAllocation(void *mem) +static bool SDL_GetTrackedAllocation(void *mem, size_t *entry_size) { SDL_tracked_allocation *entry; LOCK_ALLOCATOR(); int index = get_allocation_bucket(mem); for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { if (mem == entry->mem) { + if (entry_size) { + *entry_size = entry->size; + } UNLOCK_ALLOCATOR(); - return entry; + return true; } } UNLOCK_ALLOCATOR(); - return NULL; + return false; } static size_t SDL_GetTrackedAllocationSize(void *mem) { - SDL_tracked_allocation *entry = SDL_GetTrackedAllocation(mem); - - return entry ? entry->size : SIZE_MAX; + size_t size = 0; + if (!SDL_GetTrackedAllocation(mem, &size)) { + size = SIZE_MAX; + } + return size; } static bool SDL_IsAllocationTracked(void *mem) { - return SDL_GetTrackedAllocation(mem) != NULL; + return SDL_GetTrackedAllocation(mem, NULL); } static void SDL_TrackAllocation(void *mem, size_t size) From 010e892752ef0c7c51b601743561aade468f8354 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 10 Apr 2026 22:02:39 +0200 Subject: [PATCH 134/407] test: simplify SDL_UntrackAllocation a bit --- src/test/SDL_test_memory.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index 11b762e5d3..0536e7dad4 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -77,12 +77,12 @@ static SDL_tracked_allocation *s_tracked_allocations[256]; static bool s_randfill_allocations = false; static SDL_AtomicInt s_lock; -#define LOCK_ALLOCATOR() \ - do { \ +#define LOCK_ALLOCATOR() \ + do { \ if (SDL_CompareAndSwapAtomicInt(&s_lock, 0, 1)) { \ - break; \ - } \ - SDL_CPUPauseInstruction(); \ + break; \ + } \ + SDL_CPUPauseInstruction(); \ } while (true) #define UNLOCK_ALLOCATOR() do { SDL_SetAtomicInt(&s_lock, 0); } while (0) @@ -199,23 +199,19 @@ static void SDL_TrackAllocation(void *mem, size_t size) static void SDL_UntrackAllocation(void *mem) { - SDL_tracked_allocation *entry, *prev; + SDL_tracked_allocation *entry, **prev_next_ptr; int index = get_allocation_bucket(mem); LOCK_ALLOCATOR(); - prev = NULL; + prev_next_ptr = &s_tracked_allocations[index]; for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { if (mem == entry->mem) { - if (prev) { - prev->next = entry->next; - } else { - s_tracked_allocations[index] = entry->next; - } + *prev_next_ptr = entry->next; SDL_free_orig(entry); UNLOCK_ALLOCATOR(); return; } - prev = entry; + prev_next_ptr = &entry->next; } s_unknown_frees += 1; UNLOCK_ALLOCATOR(); From 03ceaca19c06732381b39d5353f05d1d1805199d Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 19 Apr 2026 23:31:00 -0400 Subject: [PATCH 135/407] wayland: Calculate the fullscreen exclusive pointer scale from the viewport dimensions Fixes the pointer scale when using the aspect-correct scaling mode. --- src/video/wayland/SDL_waylandwindow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 20da36b633..43ccce42e7 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -362,8 +362,8 @@ static void ConfigureWindowGeometry(SDL_Window *window) data->current.logical_height = window->current_fullscreen_mode.h; } - data->pointer_scale.x = (double)window_width / (double)data->current.logical_width; - data->pointer_scale.y = (double)window_height / (double)data->current.logical_height; + data->pointer_scale.x = (double)window_width / (double)viewport_width; + data->pointer_scale.y = (double)window_height / (double)viewport_height; } } else { if (!data->scale_to_display) { From 03f1a84302cfd1ab25a68924bd1168a2b0ed7682 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 19 Apr 2026 23:18:12 -0400 Subject: [PATCH 136/407] wayland: Fix scaled cursor image selection When the pointer isn't being scaled, make sure the cursor scale factor is set to that of the window to avoid blurry cursors on high-DPI desktops, and use the inverse of the pointer scale value when selecting buffers for size-adjusted cursors. Fixes a regression from adjusting custom cursor sizes when using scale to display mode, and ensures that the best buffer size for the scaled cursor is always selected. --- src/video/wayland/SDL_waylandmouse.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index 2ae9a418ae..1a23544d64 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -1104,13 +1104,27 @@ static void Wayland_CursorStateSetCursor(SDL_WaylandCursorState *state, const Wa dst_height = dst_width; } else { /* If viewports aren't available, the scale is always 1.0. - * The dimensions are scaled by the pointer scale, so custom cursors will be scaled relative to the window size. + * + * If the pointer scale values are 1.0, the preferred backing buffer scale is the window scale. + * + * If the pointer is scaled, the dimensions are scaled by the pointer scale, so custom cursors will be scaled + * relative to the viewport size. */ - state->scale = viddata->viewporter && focus ? SDL_min(focus->pointer_scale.x, focus->pointer_scale.y) : 1.0; - dst_width = SDL_max((int)SDL_lround((double)cursor_data->cursor_data.custom.width / state->scale), 1); - dst_height = SDL_max((int)SDL_lround((double)cursor_data->cursor_data.custom.height / state->scale), 1); - hot_x = (int)SDL_lround((double)cursor_data->cursor_data.custom.hot_x / state->scale); - hot_y = (int)SDL_lround((double)cursor_data->cursor_data.custom.hot_y / state->scale); + if (!focus || (focus->pointer_scale.x == 1.0 && focus->pointer_scale.y == 1.0)) { + state->scale = viddata->viewporter && focus ? focus->scale_factor : 1.0; + dst_width = cursor_data->cursor_data.custom.width; + dst_height = cursor_data->cursor_data.custom.height; + hot_x = cursor_data->cursor_data.custom.hot_x; + hot_y = cursor_data->cursor_data.custom.hot_y; + } else { + // The preferred buffer scale is the inverse of the pointer scale. + state->scale = 1.0 / SDL_min(focus->pointer_scale.x, focus->pointer_scale.y); + dst_width = SDL_max((int)SDL_lround((double)cursor_data->cursor_data.custom.width / focus->pointer_scale.x), 1); + dst_height = SDL_max((int)SDL_lround((double)cursor_data->cursor_data.custom.height / focus->pointer_scale.y), 1); + hot_x = (int)SDL_lround((double)cursor_data->cursor_data.custom.hot_x / focus->pointer_scale.x); + hot_y = (int)SDL_lround((double)cursor_data->cursor_data.custom.hot_y / focus->pointer_scale.y); + } + } state->current_cursor = cursor_data; From 76aa12701a5f0166c1b0cec038ea97759a098b07 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 20 Apr 2026 10:33:10 -0400 Subject: [PATCH 137/407] hints: Correct the cursor DPI scaling hint Support for this hint was removed from Wayland shortly after it was added, but the documentation was never updated to reflect this. --- include/SDL3/SDL_hints.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index d01f36f8a9..369dc7e921 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -2838,7 +2838,7 @@ extern "C" { * (default) * - "1": Cursors will automatically match the display content scale (e.g. a * 2x sized cursor will be used when the window is on a monitor with 200% - * scale). This is currently implemented on Windows and Wayland. + * scale). This is currently implemented on Windows. * * This hint needs to be set before creating cursors. * From 3b89c7b537c0e13f7a09361d5c14161aeee9564f Mon Sep 17 00:00:00 2001 From: atiradonet <129443089+atiradonet@users.noreply.github.com> Date: Tue, 21 Apr 2026 02:04:24 +1000 Subject: [PATCH 138/407] joystick: Add VIRPIL Controls flight stick and throttle device IDs. (#15418) VIRPIL Controls (VID 0x3344) flight sticks are misclassified as gamepads by SDL's axis-count heuristic because they report exactly 6 axes, matching SDL_GAMEPAD_AXIS_COUNT. Adding them to the appropriate device lists ensures correct classification. Tested on Linux (Fedora 43, kernel 6.19) with: - R-VPC Stick MT-50CM3 (PID 0x4391) -> SDL_JOYSTICK_TYPE_FLIGHT_STICK - L-VPC Stick MT-50CM3 (PID 0x8390) -> SDL_JOYSTICK_TYPE_FLIGHT_STICK - VPC VMAX Prime Throttle (PID 0x0196) -> SDL_JOYSTICK_TYPE_THROTTLE --- src/joystick/SDL_joystick.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 414fffad39..61af6d6e81 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -476,6 +476,8 @@ static Uint32 initial_flightstick_devices[] = { MAKE_VIDPID(0x10f5, 0x7084), // Turtle Beach VelocityOne MAKE_VIDPID(0x231d, 0x0126), // Gunfighter Mk.III 'Space Combat Edition' (right) MAKE_VIDPID(0x231d, 0x0127), // Gunfighter Mk.III 'Space Combat Edition' (left) + MAKE_VIDPID(0x3344, 0x4391), // VIRPIL Controls R-VPC Stick MT-50CM3 + MAKE_VIDPID(0x3344, 0x8390), // VIRPIL Controls L-VPC Stick MT-50CM3 MAKE_VIDPID(0x362c, 0x0001), // Yawman Arrow }; static SDL_vidpid_list flightstick_devices = { @@ -523,6 +525,7 @@ static Uint32 initial_throttle_devices[] = { MAKE_VIDPID(0x044f, 0x0404), // HOTAS Warthog Throttle MAKE_VIDPID(0x0738, 0xa221), // Saitek Pro Flight X-56 Rhino Throttle MAKE_VIDPID(0x10f5, 0x7085), // Turtle Beach VelocityOne Throttle + MAKE_VIDPID(0x3344, 0x0196), // VIRPIL Controls VPC VMAX Prime Throttle }; static SDL_vidpid_list throttle_devices = { SDL_HINT_JOYSTICK_THROTTLE_DEVICES, 0, 0, NULL, From 700280a15025f2b7fbfbe03aa114dc5093584e22 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 12 Apr 2026 11:01:33 +0800 Subject: [PATCH 139/407] tray:unix: Rework the tray structures to have an 'internal' member Currently, the SDL_Tray* structs in the unix backend are subclassed for each implementation (only dbus so far). This means that the DBus-specific members are in their own structs (SDL_Tray*DBus), which all are required to have the corresponding 'parent' struct as their first member, so that they can be cast easily and used in the more generic code. However, other SDL systems which have pluggable backends work the other way around: the 'generic' struct has an 'internal' member, which individual drivers can use to store a pointer to any internal state. This is a bit simpler to wrap one's head around -- particularly because it's consistent -- but does typically involve more memory allocations. Change the unix/DBus tray implementations to use an 'internal' pointer to match other subsystems. --- src/tray/unix/SDL_dbustray.c | 186 ++++++++++++++++++++--------------- src/tray/unix/SDL_unixtray.h | 8 ++ 2 files changed, 113 insertions(+), 81 deletions(-) diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index f7e8cf54bd..0885da8f01 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -34,15 +34,11 @@ typedef struct SDL_TrayDriverDBus { - SDL_TrayDriver class_parent; - SDL_DBusContext *dbus; } SDL_TrayDriverDBus; typedef struct SDL_TrayDBus { - SDL_Tray class_parent; - DBusConnection *connection; char *service_name; @@ -59,8 +55,6 @@ typedef struct SDL_TrayDBus typedef struct SDL_TrayMenuDBus { - SDL_TrayMenu class_parent; - SDL_ListNode *menu; const char *menu_path; @@ -69,10 +63,8 @@ typedef struct SDL_TrayMenuDBus typedef struct SDL_TrayEntryDBus { - SDL_TrayEntry class_parent; - SDL_MenuItem *item; - SDL_TrayMenuDBus *sub_menu; + SDL_TrayMenu *sub_menu; } SDL_TrayEntryDBus; #define SNI_INTERFACE "org.kde.StatusNotifierItem" @@ -95,7 +87,7 @@ static DBusHandlerResult TrayHandleGetAllProps(SDL_Tray *tray, SDL_TrayDBus *tra dbus_uint32_t uint32_val; dbus_bool_t bool_value; - menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; empty = ""; driver->dbus->message_iter_init(msg, &iter); @@ -156,7 +148,7 @@ static DBusHandlerResult TrayHandleGetAllProps(SDL_Tray *tray, SDL_TrayDBus *tra driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); key = "ItemIsMenu"; - menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; if (menu_dbus && menu_dbus->menu_path) { bool_value = TRUE; } else { @@ -241,7 +233,7 @@ static DBusHandlerResult TrayHandleGetProp(SDL_Tray *tray, SDL_TrayDBus *tray_db const char *empty; dbus_bool_t bool_value; - menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; empty = ""; driver->dbus->message_iter_init(msg, &iter); @@ -347,8 +339,8 @@ static DBusHandlerResult TrayMessageHandler(DBusConnection *connection, DBusMess DBusMessage *reply; tray = user_data; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; if (driver->dbus->message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) { return TrayHandleGetProp(tray, tray_dbus, driver, msg); @@ -425,6 +417,7 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) #define CLEANUP() \ SDL_free(tray_dbus->tooltip); \ SDL_DestroySurface(tray_dbus->surface); \ + SDL_free(tray); \ SDL_free(tray_dbus) #define CLEANUP2() \ dbus_driver->dbus->connection_close(tray_dbus->connection); \ @@ -436,14 +429,19 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) /* Allocate the tray structure */ tray_dbus = SDL_malloc(sizeof(SDL_TrayDBus)); - tray = &tray_dbus->class_parent; if (!tray_dbus) { return NULL; } + tray = SDL_malloc(sizeof(SDL_Tray)); + if (!tray) { + CLEANUP(); + return NULL; + } /* Populate */ tray->menu = NULL; tray->driver = driver; + tray->internal = tray_dbus; if (tooltip) { tray_dbus->tooltip = SDL_strdup(tooltip); } else { @@ -453,7 +451,7 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) tray_dbus->block = false; /* Connect */ - dbus_driver = (SDL_TrayDriverDBus *)driver; + dbus_driver = (SDL_TrayDriverDBus *)driver->internal; dbus_driver->dbus->error_init(&err); tray_dbus->connection = dbus_driver->dbus->bus_get_private(DBUS_BUS_SESSION, &err); if (dbus_driver->dbus->error_is_set(&err)) { @@ -487,7 +485,7 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) /* Create object */ object_path = SNI_OBJECT_PATH; vtable.message_function = TrayMessageHandler; - bool_status = dbus_driver->dbus->connection_try_register_object_path(tray_dbus->connection, object_path, &vtable, tray_dbus, &err); + bool_status = dbus_driver->dbus->connection_try_register_object_path(tray_dbus->connection, object_path, &vtable, tray, &err); if (dbus_driver->dbus->error_is_set(&err)) { SDL_SetError("Unable to create tray: %s", err.message); dbus_driver->dbus->error_free(&err); @@ -531,7 +529,7 @@ void DestroyMenu(SDL_TrayMenu *menu) return; } - menu_dbus = (SDL_TrayMenuDBus *)menu; + menu_dbus = (SDL_TrayMenuDBus *)menu->internal; if (menu_dbus->menu) { SDL_ListNode *cursor; @@ -539,14 +537,16 @@ void DestroyMenu(SDL_TrayMenu *menu) cursor = menu_dbus->menu; while (cursor) { SDL_MenuItem *item; - SDL_TrayEntryDBus *entry; + SDL_TrayEntry *entry; + SDL_TrayEntryDBus *entry_dbus; item = cursor->entry; entry = item->udata; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; - if (entry->sub_menu) { - DestroyMenu((SDL_TrayMenu *)entry->sub_menu); - entry->sub_menu = NULL; + if (entry_dbus->sub_menu) { + DestroyMenu(entry_dbus->sub_menu); + entry_dbus->sub_menu = NULL; } SDL_free(item); SDL_free(entry); @@ -561,6 +561,7 @@ void DestroyMenu(SDL_TrayMenu *menu) } SDL_free(menu_dbus); + SDL_free(menu); } void DestroyTray(SDL_Tray *tray) @@ -568,8 +569,8 @@ void DestroyTray(SDL_Tray *tray) SDL_TrayDBus *tray_dbus; SDL_TrayDriverDBus *driver; - driver = (SDL_TrayDriverDBus *)tray->driver; - tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + tray_dbus = (SDL_TrayDBus *)tray->internal; /* Destroy connection */ driver->dbus->connection_flush(tray_dbus->connection); @@ -596,8 +597,8 @@ void UpdateTray(SDL_Tray *tray) SDL_TrayDBus *tray_dbus; SDL_TrayDriverDBus *driver; - driver = (SDL_TrayDriverDBus *)tray->driver; - tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + tray_dbus = (SDL_TrayDBus *)tray->internal; if (!SDL_ObjectValid(tray, SDL_OBJECT_TYPE_TRAY)) { return; @@ -627,8 +628,8 @@ void SetTrayIcon(SDL_Tray *tray, SDL_Surface *surface) SDL_TrayDriverDBus *driver; DBusMessage *signal; - driver = (SDL_TrayDriverDBus *)tray->driver; - tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + tray_dbus = (SDL_TrayDBus *)tray->internal; if (tray_dbus->surface) { SDL_DestroySurface(tray_dbus->surface); @@ -647,8 +648,8 @@ void SetTrayTooltip(SDL_Tray *tray, const char *text) SDL_TrayDriverDBus *driver; DBusMessage *signal; - driver = (SDL_TrayDriverDBus *)tray->driver; - tray_dbus = (SDL_TrayDBus *)tray; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + tray_dbus = (SDL_TrayDBus *)tray->internal; if (tray_dbus->tooltip) { SDL_free(tray_dbus->tooltip); @@ -671,16 +672,22 @@ SDL_TrayMenu *CreateTrayMenu(SDL_Tray *tray) SDL_TrayMenuDBus *menu_dbus; menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); - tray->menu = &menu_dbus->class_parent; if (!menu_dbus) { SDL_SetError("Unable to create tray menu: allocation failure!"); return NULL; } + tray->menu = SDL_malloc(sizeof(SDL_TrayMenu)); + if (!tray->menu) { + SDL_free(menu_dbus); + SDL_SetError("Unable to create tray menu: allocation failure!"); + return NULL; + } menu_dbus->menu = NULL; menu_dbus->menu_path = NULL; tray->menu->parent_tray = tray; tray->menu->parent_entry = NULL; + tray->menu->internal = menu_dbus; menu_dbus->array_representation = NULL; return tray->menu; @@ -692,19 +699,25 @@ SDL_TrayMenu *CreateTraySubmenu(SDL_TrayEntry *entry) SDL_TrayMenu *menu; SDL_TrayEntryDBus *entry_dbus; - entry_dbus = (SDL_TrayEntryDBus *)entry; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; menu_dbus = SDL_malloc(sizeof(SDL_TrayMenuDBus)); - menu = &menu_dbus->class_parent; if (!menu_dbus) { SDL_SetError("Unable to create tray submenu: allocation failure!"); return NULL; } + menu = SDL_malloc(sizeof(SDL_TrayMenu)); + if (!menu) { + SDL_free(menu_dbus); + SDL_SetError("Unable to create tray submenu: allocation failure!"); + return NULL; + } menu_dbus->menu = NULL; menu_dbus->menu_path = NULL; menu->parent_tray = entry->parent->parent_tray; menu->parent_entry = entry; - entry_dbus->sub_menu = menu_dbus; + menu->internal = menu_dbus; + entry_dbus->sub_menu = menu; menu_dbus->array_representation = NULL; return menu; @@ -714,18 +727,17 @@ SDL_TrayMenu *GetTraySubmenu(SDL_TrayEntry *entry) { SDL_TrayEntryDBus *entry_dbus; - entry_dbus = (SDL_TrayEntryDBus *)entry; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; - return (SDL_TrayMenu *)entry_dbus->sub_menu; + return entry_dbus->sub_menu; } bool TrayRightClickHandler(SDL_ListNode *menu, void *udata) { - SDL_TrayDBus *tray_dbus; + SDL_Tray *tray = (SDL_Tray *)udata; + SDL_TrayDBus *tray_dbus = (SDL_TrayDBus *)tray->internal; - tray_dbus = (SDL_TrayDBus *)udata; - - return tray_dbus->r_cb(tray_dbus->udata, (SDL_Tray *)tray_dbus); + return tray_dbus->r_cb(tray_dbus->udata, tray); } void TraySendNewMenu(SDL_Tray *tray, const char *new_path) @@ -735,9 +747,9 @@ void TraySendNewMenu(SDL_Tray *tray, const char *new_path) SDL_TrayMenuDBus *menu_dbus; DBusMessage *signal; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; driver->dbus->connection_flush(tray_dbus->connection); @@ -807,18 +819,24 @@ SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, bool update; tray = menu->parent_tray; - menu_dbus = (SDL_TrayMenuDBus *)menu; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; + menu_dbus = (SDL_TrayMenuDBus *)menu->internal; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; entry_dbus = SDL_malloc(sizeof(SDL_TrayEntryDBus)); - entry = &entry_dbus->class_parent; if (!entry_dbus) { SDL_SetError("Unable to create tray entry: allocation failure!"); return NULL; } + entry = SDL_malloc(sizeof(SDL_TrayEntry)); + if (!entry) { + SDL_free(entry_dbus); + SDL_SetError("Unable to create tray entry: allocation failure!"); + return NULL; + } entry->parent = menu; + entry->internal = entry_dbus; entry_dbus->item = SDL_DBus_CreateMenuItem(); entry_dbus->item->utf8 = label; if (!label) { @@ -832,7 +850,7 @@ SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, entry_dbus->item->cb_data = NULL; entry_dbus->item->cb = NULL; entry_dbus->item->sub_menu = NULL; - entry_dbus->item->udata = entry_dbus; + entry_dbus->item->udata = entry; entry_dbus->sub_menu = NULL; if (menu_dbus->menu) { @@ -850,14 +868,14 @@ SDL_TrayEntry *InsertTrayEntryAt(SDL_TrayMenu *menu, int pos, const char *label, if (menu->parent_entry) { SDL_TrayEntryDBus *parent_entry_dbus; - parent_entry_dbus = (SDL_TrayEntryDBus *)menu->parent_entry; + parent_entry_dbus = (SDL_TrayEntryDBus *)menu->parent_entry->internal; parent_entry_dbus->item->sub_menu = menu_dbus->menu; } if (update) { SDL_TrayMenuDBus *main_menu_dbus; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); } else { menu_dbus->menu_path = SDL_DBus_ExportMenu(driver->dbus, tray_dbus->connection, menu_dbus->menu); @@ -882,7 +900,7 @@ SDL_TrayEntry **GetTrayEntries(SDL_TrayMenu *menu, int *count) int sz; int i; - menu_dbus = (SDL_TrayMenuDBus *)menu; + menu_dbus = (SDL_TrayMenuDBus *)menu->internal; if (menu_dbus->array_representation) { SDL_free(menu_dbus->array_representation); @@ -922,11 +940,11 @@ void RemoveTrayEntry(SDL_TrayEntry *entry) const char *old_path; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - entry_dbus = (SDL_TrayEntryDBus *)entry; - menu_dbus = (SDL_TrayMenuDBus *)entry->parent; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; + menu_dbus = (SDL_TrayMenuDBus *)entry->parent->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; tray_dbus->block = true; if (menu_dbus->menu->entry == entry_dbus->item && menu_dbus->menu->next) { @@ -939,9 +957,10 @@ void RemoveTrayEntry(SDL_TrayEntry *entry) } driver->dbus->connection_flush(tray_dbus->connection); - DestroyMenu((SDL_TrayMenu *)entry_dbus->sub_menu); + DestroyMenu(entry_dbus->sub_menu); SDL_ListRemove(&menu_dbus->menu, entry_dbus->item); SDL_free(entry_dbus->item); + SDL_free(entry_dbus); SDL_free(entry); if (old_path) { @@ -969,10 +988,10 @@ void SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void SDL_TrayMenuDBus *main_menu_dbus; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - entry_dbus = (SDL_TrayEntryDBus *)entry; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; entry_dbus->item->cb = EntryCallback; entry_dbus->item->cb_data = userdata; @@ -990,10 +1009,10 @@ void SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) SDL_TrayMenuDBus *main_menu_dbus; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - entry_dbus = (SDL_TrayEntryDBus *)entry; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; entry_dbus->item->utf8 = label; @@ -1002,7 +1021,7 @@ void SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) const char *GetTrayEntryLabel(SDL_TrayEntry *entry) { - return ((SDL_TrayEntryDBus *)entry)->item->utf8; + return ((SDL_TrayEntryDBus *)entry->internal)->item->utf8; } void SetTrayEntryChecked(SDL_TrayEntry *entry, bool val) @@ -1014,10 +1033,10 @@ void SetTrayEntryChecked(SDL_TrayEntry *entry, bool val) SDL_TrayMenuDBus *main_menu_dbus; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - entry_dbus = (SDL_TrayEntryDBus *)entry; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; if (val) { entry_dbus->item->flags |= SDL_MENU_ITEM_FLAGS_CHECKED; @@ -1030,7 +1049,7 @@ void SetTrayEntryChecked(SDL_TrayEntry *entry, bool val) bool GetTrayEntryChecked(SDL_TrayEntry *entry) { - return ((SDL_TrayEntryDBus *)entry)->item->flags & SDL_MENU_ITEM_FLAGS_CHECKED; + return ((SDL_TrayEntryDBus *)entry->internal)->item->flags & SDL_MENU_ITEM_FLAGS_CHECKED; } void SetTrayEntryEnabled(SDL_TrayEntry *entry, bool val) @@ -1042,10 +1061,10 @@ void SetTrayEntryEnabled(SDL_TrayEntry *entry, bool val) SDL_TrayMenuDBus *main_menu_dbus; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - entry_dbus = (SDL_TrayEntryDBus *)entry; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + entry_dbus = (SDL_TrayEntryDBus *)entry->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; if (!val) { entry_dbus->item->flags |= SDL_MENU_ITEM_FLAGS_DISABLED; @@ -1058,7 +1077,7 @@ void SetTrayEntryEnabled(SDL_TrayEntry *entry, bool val) bool GetTrayEntryEnabled(SDL_TrayEntry *entry) { - return !(((SDL_TrayEntryDBus *)entry)->item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); + return !(((SDL_TrayEntryDBus *)entry->internal)->item->flags & SDL_MENU_ITEM_FLAGS_DISABLED); } void ClickTrayEntry(SDL_TrayEntry *entry) @@ -1066,7 +1085,7 @@ void ClickTrayEntry(SDL_TrayEntry *entry) SDL_TrayEntryDBus *dbus_entry; SDL_TrayCallback entry_cb; - dbus_entry = (SDL_TrayEntryDBus *)entry; + dbus_entry = (SDL_TrayEntryDBus *)entry->internal; if (dbus_entry->item->type == SDL_MENU_ITEM_TYPE_CHECKBOX) { SDL_Tray *tray; SDL_TrayDriverDBus *driver; @@ -1074,9 +1093,9 @@ void ClickTrayEntry(SDL_TrayEntry *entry) SDL_TrayMenuDBus *main_menu_dbus; tray = entry->parent->parent_tray; - tray_dbus = (SDL_TrayDBus *)tray; - driver = (SDL_TrayDriverDBus *)tray->driver; - main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu; + tray_dbus = (SDL_TrayDBus *)tray->internal; + driver = (SDL_TrayDriverDBus *)tray->driver->internal; + main_menu_dbus = (SDL_TrayMenuDBus *)tray->menu->internal; dbus_entry->item->flags ^= SDL_MENU_ITEM_FLAGS_CHECKED; SDL_DBus_UpdateMenu(driver->dbus, tray_dbus->connection, main_menu_dbus->menu, main_menu_dbus->menu_path, TrayNewMenuOnMenuUpdateCallback, tray, SDL_DBUS_UPDATE_MENU_FLAGS_NONE); @@ -1143,13 +1162,18 @@ SDL_TrayDriver *SDL_Tray_CreateDBusDriver(void) /* Allocate the driver struct */ dbus_driver = SDL_malloc(sizeof(SDL_TrayDriverDBus)); - driver = &dbus_driver->class_parent; if (!dbus_driver) { return NULL; } + driver = SDL_malloc(sizeof(SDL_TrayDriver)); + if (!driver) { + SDL_free(dbus_driver); + return NULL; + } /* Populate */ dbus_driver->dbus = ctx; + driver->internal = dbus_driver; driver->name = "dbus"; driver->count = 0; driver->CreateTray = CreateTray; diff --git a/src/tray/unix/SDL_unixtray.h b/src/tray/unix/SDL_unixtray.h index 1a31ffc1b5..14491be361 100644 --- a/src/tray/unix/SDL_unixtray.h +++ b/src/tray/unix/SDL_unixtray.h @@ -54,17 +54,23 @@ typedef struct SDL_TrayDriver void (*SetTrayEntryCallback)(SDL_TrayEntry *, SDL_TrayCallback, void *); void (*DestroyDriver)(struct SDL_TrayDriver *); + + void *internal; } SDL_TrayDriver; struct SDL_TrayMenu { SDL_Tray *parent_tray; SDL_TrayEntry *parent_entry; + + void *internal; }; struct SDL_TrayEntry { SDL_TrayMenu *parent; + + void *internal; }; struct SDL_Tray @@ -72,6 +78,8 @@ struct SDL_Tray SDL_TrayDriver *driver; SDL_TrayMenu *menu; + + void *internal; }; #ifdef SDL_USE_LIBDBUS From 125ed508c2fafba26ecf6615e136aaf54c90da52 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 20 Apr 2026 12:41:48 -0400 Subject: [PATCH 140/407] dbus: Return false if the screensaver inhibitor interface is unavailable Returning true with an unavailable interface in no-op cases can prevent fallback to other inhibition methods. If the inhibitor interface was previously tried and marked as unavailable, just return false. --- src/core/linux/SDL_dbus.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 1b3f56e73c..af791b764e 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -612,8 +612,14 @@ done: bool SDL_DBus_ScreensaverInhibit(bool inhibit) { + static bool interface_unavailable = false; const char *default_inhibit_reason = "Playing a game"; + // If the interface was previously queried and is unavailable, return false. + if (interface_unavailable) { + return false; + } + if ((inhibit && (screensaver_cookie != 0 || inhibit_handle)) || (!inhibit && (screensaver_cookie == 0 && !inhibit_handle))) { return true; } @@ -664,6 +670,8 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit) if (SDL_DBus_CallWithBasicReply(dbus.session_conn, &reply, msg, DBUS_TYPE_OBJECT_PATH, &reply_path)) { inhibit_handle = SDL_strdup(reply_path); result = true; + } else { + interface_unavailable = true; } SDL_DBus_FreeReply(&reply); dbus.message_unref(msg); @@ -690,6 +698,7 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit) if (!SDL_DBus_CallMethod(NULL, bus_name, path, interface, "Inhibit", DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID, DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) { + interface_unavailable = true; return false; } return (screensaver_cookie != 0); From 0231ff03dee7ae2400ebdf274627052b32790a04 Mon Sep 17 00:00:00 2001 From: som3a-dev Date: Fri, 17 Apr 2026 23:32:43 +0200 Subject: [PATCH 141/407] (video) fix SDL_GetClosestFullscreenDisplayMode aspect ratio & refresh rate picking logic --- src/video/SDL_video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 764eee219d..e3c4f66185 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1416,14 +1416,14 @@ bool SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, if (closest) { float current_aspect_ratio = (float)mode->w / mode->h; float closest_aspect_ratio = (float)closest->w / closest->h; - if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) < SDL_fabsf(aspect_ratio - current_aspect_ratio)) { - // The mode we already found has a better aspect ratio match + if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) <= SDL_fabsf(aspect_ratio - current_aspect_ratio)) { + // The mode we already found has a similar or better aspect ratio match continue; } if (mode->w == closest->w && mode->h == closest->h && - SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) { - /* We already found a mode and the new mode is further from our + SDL_fabsf(closest->refresh_rate - refresh_rate) <= SDL_fabsf(mode->refresh_rate - refresh_rate)) { + /* We already found a mode and the new mode's refresh rate is the same or is further away from our * refresh rate target */ continue; } From 85b36937a985c12dee7edc4dd6e1efcfaa508c99 Mon Sep 17 00:00:00 2001 From: Marco Burato Date: Mon, 20 Apr 2026 19:53:25 +0200 Subject: [PATCH 142/407] macOS mouse scroll fix (#15404) * macOS: fix vertical/horizontal scrolling on GCMouse API * macOS: use AppKit events for mouse scrolling as GCMouse scroll events are buggy --- src/video/cocoa/SDL_cocoamouse.m | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 88f0744d39..8fb9cc2328 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -33,6 +33,8 @@ #define DEBUG_COCOAMOUSE #endif +//#define USE_GCMOUSE_SCROLL + #ifdef DEBUG_COCOAMOUSE #define DLog(fmt, ...) printf("%s: " fmt "\n", SDL_FUNCTION, ##__VA_ARGS__) #else @@ -262,6 +264,9 @@ static id cocoa_mouse_disconnect_observer = nil; // Atomic for thread-safe access during high-frequency mouse input static SDL_AtomicInt cocoa_gcmouse_relative_mode; static bool cocoa_has_gcmouse = false; + + +#ifdef USE_GCMOUSE_SCROLL static SDL_MouseWheelDirection cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; static void Cocoa_UpdateGCMouseScrollDirection(void) @@ -281,6 +286,7 @@ static void Cocoa_UpdateGCMouseScrollDirection(void) cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; } } +#endif static bool Cocoa_SetGCMouseRelativeMode(bool enabled) { @@ -348,13 +354,20 @@ static void Cocoa_OnGCMouseConnected(GCMouse *mouse) } }; + #ifdef USE_GCMOUSE_SCROLL + /* + 18/04/2026 + There seems to be a bug in the CGMouse API, at least when using some mouse types. + An event is fired only for the first scroll in one direction. Repeated 1-step + scrolls in the same direction do not raise an event. + Observed on macOS 26.3.1 with 2 different USB mice. + */ mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + DLog("GCMouse scroll: %f, %f", xValue, yValue); Uint64 timestamp = SDL_GetTicksNS(); - // Raw scroll values: vertical in first axis, horizontal in second. - // Vertical values are inverted compared to SDL conventions. - float vertical = -xValue; - float horizontal = yValue; + float vertical = yValue; + float horizontal = xValue; if (cocoa_mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { vertical = -vertical; @@ -365,7 +378,8 @@ static void Cocoa_OnGCMouseConnected(GCMouse *mouse) cocoa_mouse_scroll_direction); }; Cocoa_UpdateGCMouseScrollDirection(); - + #endif // USE_GCMOUSE_SCROLL + // Use high-priority queue for low-latency input dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL); @@ -852,10 +866,12 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event) void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) { + #ifdef USE_GCMOUSE_SCROLL // GCMouse handles scroll events directly, skip NSEvent path to avoid duplicates if (Cocoa_HasGCMouse()) { return; } + #endif SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID; SDL_MouseWheelDirection direction; From 1675c8267ede3d12d26a362161eed2dda0813079 Mon Sep 17 00:00:00 2001 From: Hayden Gray <35206453+A1029384756@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:50:22 -0400 Subject: [PATCH 143/407] [tray/dbus] set tray session name to app subname in flatpak env (#15393) * [tray/dbus] set tray session name to app subname in flatpak env * [tray/dbus] have dbus service name come from the app id. app id falls back to flatpak if in a flatpak environment * [tray/dbus] change dbus menu path to work with apparmor --- src/core/linux/SDL_dbus.c | 2 +- src/core/unix/SDL_appid.c | 6 ++++++ src/tray/unix/SDL_dbustray.c | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index af791b764e..2416907fc6 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -53,7 +53,7 @@ static unsigned int screensaver_cookie = 0; static SDL_DBusContext dbus; #define DBUS_MENU_INTERFACE "com.canonical.dbusmenu" -#define DBUS_MENU_OBJECT_PATH "/Menu" +#define DBUS_MENU_OBJECT_PATH "/StatusNotifierItem/menu" #define SDL_DBUS_UPDATE_MENU_FLAG_DO_NOT_REPLACE (1 << 0) static const char *menu_introspect = ""; diff --git a/src/core/unix/SDL_appid.c b/src/core/unix/SDL_appid.c index 3b85cbc876..afe157f2cd 100644 --- a/src/core/unix/SDL_appid.c +++ b/src/core/unix/SDL_appid.c @@ -61,6 +61,12 @@ const char *SDL_GetAppID(void) { const char *id_str = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING); +#ifdef SDL_PLATFORM_LINUX + if (!id_str) { + id_str = SDL_getenv("FLATPAK_ID"); + } +#endif + if (!id_str) { // If the hint isn't set, try to use the application's executable name id_str = SDL_GetExeName(); diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index 0885da8f01..c2c66679e7 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -28,6 +28,7 @@ #ifdef SDL_USE_LIBDBUS #include "../../video/SDL_surface_c.h" +#include "../../core/unix/SDL_appid.h" #include "../SDL_tray_utils.h" #include "SDL_unixtray.h" #include @@ -468,7 +469,11 @@ SDL_Tray *CreateTray(SDL_TrayDriver *driver, SDL_PropertiesID props) /* Request name */ driver->count++; - SDL_asprintf(&tray_dbus->service_name, "org.kde.StatusNotifierItem-%d-%d", getpid(), driver->count); + if (SDL_GetSandbox() == SDL_SANDBOX_FLATPAK) { + SDL_asprintf(&tray_dbus->service_name, "%s.tray%d", SDL_GetAppID(), driver->count); + } else { + SDL_asprintf(&tray_dbus->service_name, "org.kde.StatusNotifierItem-%d-%d", getpid(), driver->count); + } status = dbus_driver->dbus->bus_request_name(tray_dbus->connection, tray_dbus->service_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if (dbus_driver->dbus->error_is_set(&err)) { SDL_SetError("Unable to create tray: %s", err.message); From eacfe835e7c1bf8e59e91f788a86227510852b34 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Tue, 21 Apr 2026 10:51:43 +0200 Subject: [PATCH 144/407] Fix potential leak in camera example --- examples/camera/01-read-and-draw/read-and-draw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/camera/01-read-and-draw/read-and-draw.c b/examples/camera/01-read-and-draw/read-and-draw.c index 7682da95de..b3649f4b58 100644 --- a/examples/camera/01-read-and-draw/read-and-draw.c +++ b/examples/camera/01-read-and-draw/read-and-draw.c @@ -44,6 +44,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) return SDL_APP_FAILURE; } else if (devcount == 0) { SDL_Log("Couldn't find any camera devices! Please connect a camera and try again."); + SDL_free(devices); return SDL_APP_FAILURE; } From 651136ac7a461ac55ba07a637efff7cdecf411e2 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Tue, 21 Apr 2026 15:45:33 +0500 Subject: [PATCH 145/407] Add trigger rumble support to Emscripten joysticks This PR adds trigger rumble support to the Emscripten joystick backend. --- src/joystick/emscripten/SDL_sysjoystick.c | 72 ++++++++++++--------- src/joystick/emscripten/SDL_sysjoystick_c.h | 6 ++ 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 5d831bddbb..15d116f725 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -448,7 +448,6 @@ static SDL_JoystickID EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index) static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) { SDL_joylist_item *item = JoystickByDeviceIndex(device_index); - bool rumble_available = false; if (!item) { return SDL_SetError("No such device"); @@ -466,22 +465,24 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) joystick->nbuttons = item->nbuttons; joystick->naxes = item->naxes; - rumble_available = MAIN_THREAD_EM_ASM_INT({ - let gamepads = navigator['getGamepads'](); - if (!gamepads) { - return 0; - } - let gamepad = gamepads[$0]; - if (!gamepad || !gamepad['vibrationActuator']) { - return 0; - } - return 1; + item->rumble_available = MAIN_THREAD_EM_ASM_INT({ + let gamepad = navigator['getGamepads']()[$0]; + return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects']['includes']('dual-rumble'); }, item->index); - if (rumble_available) { + if (item->rumble_available) { SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true); } + item->trigger_rumble_available = MAIN_THREAD_EM_ASM_INT({ + let gamepad = navigator['getGamepads']()[$0]; + return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects']['includes']('trigger-rumble'); + }, item->index); + + if (item->trigger_rumble_available) { + SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, true); + } + return true; } @@ -582,36 +583,49 @@ static SDL_GUID EMSCRIPTEN_JoystickGetDeviceGUID(int device_index) return JoystickByDeviceIndex(device_index)->guid; } -static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +static bool Emscripten_UpdateRumble(SDL_joylist_item *item) { - SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; - - // clang-format off bool result = MAIN_THREAD_EM_ASM_INT({ - let gamepads = navigator['getGamepads'](); - if (!gamepads) { - return 0; + let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return false; } - let gamepad = gamepads[$0]; - if (!gamepad || !gamepad['vibrationActuator']) { - return 0; - } - + // We check if rumble is available in EMSCRIPTEN_JoystickRumble() and EMSCRIPTEN_JoystickRumbleTriggers(). + // From my testing using "dual-rumble" here covers both main rumble and trigger rumble. gamepad['vibrationActuator']['playEffect']('dual-rumble', { 'startDelay': 0, 'duration': 3000, - 'weakMagnitude': $2 / 0xFFFF, - 'strongMagnitude': $1 / 0xFFFF, + 'weakMagnitude': $1 / 0xFFFF, + 'strongMagnitude': $2 / 0xFFFF, + 'leftTrigger': $3 / 0xFFFF, + 'rightTrigger': $4 / 0xFFFF, }); - return 1; - }, item->index, low_frequency_rumble, high_frequency_rumble); + return true; + }, item->index, item->weak_magnitude_rumble, item->strong_magnitude_rumble, item->left_trigger_rumble, item->right_trigger_rumble); return result; } +static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; + if (!item || !item->rumble_available) { + return SDL_Unsupported(); + } + item->strong_magnitude_rumble = low_frequency_rumble; + item->weak_magnitude_rumble = high_frequency_rumble; + return Emscripten_UpdateRumble(item); +} + static bool EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { - return SDL_Unsupported(); + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; + if (!item || !item->trigger_rumble_available) { + return SDL_Unsupported(); + } + item->left_trigger_rumble = left_rumble; + item->right_trigger_rumble = right_rumble; + return Emscripten_UpdateRumble(item); } static bool EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) diff --git a/src/joystick/emscripten/SDL_sysjoystick_c.h b/src/joystick/emscripten/SDL_sysjoystick_c.h index df1fda85ae..c23d544748 100644 --- a/src/joystick/emscripten/SDL_sysjoystick_c.h +++ b/src/joystick/emscripten/SDL_sysjoystick_c.h @@ -46,6 +46,12 @@ typedef struct SDL_joylist_item double analogButton[64]; EM_BOOL digitalButton[64]; Uint8 hat; // there is (currently) only ever one of these, faked from the d-pad buttons. + bool rumble_available; + bool trigger_rumble_available; + Uint16 weak_magnitude_rumble; + Uint16 strong_magnitude_rumble; + Uint16 left_trigger_rumble; + Uint16 right_trigger_rumble; struct SDL_joylist_item *next; } SDL_joylist_item; From 387439d00917c6e416592aaa467dce617e6024b5 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 21 Apr 2026 10:02:22 -0400 Subject: [PATCH 146/407] dialog: Use case-insensitive filter matching on portal dialogs On most implementations, filter pattern matching is case-sensitive. For case-insensitive matching of a pattern such as '*.png', the pattern *.[pP][nN][gG]' must be used. --- src/dialog/unix/SDL_portaldialog.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/dialog/unix/SDL_portaldialog.c b/src/dialog/unix/SDL_portaldialog.c index 7949a330d1..c0f957c8e2 100644 --- a/src/dialog/unix/SDL_portaldialog.c +++ b/src/dialog/unix/SDL_portaldialog.c @@ -86,10 +86,25 @@ static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, co dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter.name); dbus->message_iter_open_container(&filter_entry, DBUS_TYPE_ARRAY, "(us)", &filter_array); - patterns = SDL_strdup(filter.pattern); + /* Copy the filter string, converting to a case-insensitive version. + * For example, for case-insensitive matching of '*.png', the pattern '*.[pP][nN][gG]' is used. + */ + const size_t len = SDL_strlen(filter.pattern) + 1; + patterns = SDL_malloc(len * 4); // Single characters may be expanded to 4 characters. if (!patterns) { goto cleanup; } + for (size_t i = 0, p = 0; i < len; ++i) { + if ((filter.pattern[i] >= 'a' && filter.pattern[i] <= 'z') || + (filter.pattern[i] >= 'A' && filter.pattern[i] <= 'Z')) { + patterns[p++] = '['; + patterns[p++] = SDL_tolower(filter.pattern[i]); + patterns[p++] = SDL_toupper(filter.pattern[i]); + patterns[p++] = ']'; + } else { + patterns[p++] = filter.pattern[i]; + } + } pattern = SDL_strtok_r(patterns, ";", &state); while (pattern) { From 60a59fa55795409d80cd08b3509ac413d3488d5d Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Tue, 21 Apr 2026 11:33:40 +0500 Subject: [PATCH 147/407] Include OS detection in Emscripten joystick GUID This PR modifies the Emscripten joystick backend to detect the user's OS and store its ID in the GUID, because different OSes might need different mappings for the same controllers. I'm not sure if different browsers on the same OS can also have different mappings, but if they can, browser detection can be added to the GUID too if needed. This PR also makes the GUID use `SDL_HARDWARE_BUS_USB` instead of `SDL_HARDWARE_BUS_UNKNOWN`, similarly to how Android and MFI backends always use `SDL_HARDWARE_BUS_BLUETOOTH` and GameInput, XInput, and RawInput backends always use `SDL_HARDWARE_BUS_USB`. --- src/joystick/emscripten/SDL_sysjoystick.c | 41 ++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 15d116f725..adf471a199 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -100,11 +100,33 @@ static int SDL_IsEmscriptenJoystickXInput(int device_index) }, device_index); } +static int SDL_GetEmscriptenOSID() +{ + return MAIN_THREAD_EM_ASM_INT({ + const os = ([ + 'Android', + 'Linux', + 'iPhone', + 'Macintosh', + 'Windows', + ]); + const ua = navigator['userAgent']; + for (let i = 0; i < os.length; i++) { + if (ua['indexOf'](os[i]) >= 0) { + return i + 1; + } + } + return 0; + }); +} + static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { SDL_joylist_item *item; int i; + Uint16 bus; Uint16 vendor, product; + Uint8 os_id; bool is_xinput; SDL_LockJoysticks(); @@ -121,6 +143,7 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep SDL_zerop(item); item->index = gamepadEvent->index; + bus = SDL_HARDWARE_BUS_UNKNOWN; vendor = SDL_GetEmscriptenJoystickVendor(gamepadEvent->index); product = SDL_GetEmscriptenJoystickProduct(gamepadEvent->index); is_xinput = SDL_IsEmscriptenJoystickXInput(gamepadEvent->index); @@ -130,6 +153,21 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep vendor = USB_VENDOR_MICROSOFT; product = USB_PRODUCT_XBOX360_XUSB_CONTROLLER; } + + os_id = SDL_GetEmscriptenOSID(); + + if (os_id != 0) { + if (os_id == 1 || os_id == 3) { // Android or iOS (mobile) + bus = SDL_HARDWARE_BUS_BLUETOOTH; + } else { // Desktop + bus = SDL_HARDWARE_BUS_USB; + } + } + + if (SDL_strcmp(gamepadEvent->mapping, "standard") == 0) { + // We should differentiate between devices that are mapped or unmapped by the browser. + os_id += 0x80; + } item->name = SDL_CreateJoystickName(vendor, product, NULL, gamepadEvent->id); if (!item->name) { @@ -138,9 +176,10 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep } if (vendor && product) { - item->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_UNKNOWN, vendor, product, 0, NULL, item->name, 0, 0); + item->guid = SDL_CreateJoystickGUID(bus, vendor, product, 0, NULL, gamepadEvent->id, 0, os_id); } else { item->guid = SDL_CreateJoystickGUIDForName(item->name); + item->guid.data[15] = os_id; } if (is_xinput) { From 726e82d0f3d99273acb247fee7b6527b751cdde1 Mon Sep 17 00:00:00 2001 From: Semphris Date: Tue, 21 Apr 2026 16:40:57 -0400 Subject: [PATCH 148/407] Update Zenity dialog filters to ignore case --- src/dialog/SDL_dialog_utils.c | 28 +++++++++++++++++--------- src/dialog/SDL_dialog_utils.h | 8 +++++--- src/dialog/unix/SDL_zenitydialog.c | 2 +- src/dialog/windows/SDL_windowsdialog.c | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/dialog/SDL_dialog_utils.c b/src/dialog/SDL_dialog_utils.c index 826cc601c4..5af3b47689 100644 --- a/src/dialog/SDL_dialog_utils.c +++ b/src/dialog/SDL_dialog_utils.c @@ -27,7 +27,8 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, const char *separator, const char *suffix, const char *filt_prefix, const char *filt_separator, const char *filt_suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix) + const char *ext_separator, const char *ext_suffix, + bool anycase) { char *combined; char *new_combined; @@ -52,7 +53,7 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, converted = convert_filter(*f, ntf, filt_prefix, filt_separator, filt_suffix, ext_prefix, ext_separator, - ext_suffix); + ext_suffix, anycase); if (!converted) { SDL_free(combined); @@ -97,7 +98,8 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf, const char *prefix, const char *separator, const char *suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix) + const char *ext_separator, const char *ext_suffix, + bool anycase) { char *converted; char *name_filtered; @@ -105,7 +107,7 @@ char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf, char *list; list = convert_ext_list(filter.pattern, ext_prefix, ext_separator, - ext_suffix); + ext_suffix, anycase); if (!list) { return NULL; @@ -145,7 +147,7 @@ char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf, } char *convert_ext_list(const char *list, const char *prefix, - const char *separator, const char *suffix) + const char *separator, const char *suffix, bool anycase) { char *converted; int semicolons; @@ -158,7 +160,7 @@ char *convert_ext_list(const char *list, const char *prefix, } total_length = - SDL_strlen(list) - semicolons // length of list contents + (SDL_strlen(list) - semicolons) * 4 // length of list contents (including "a" -> "[aA]") + semicolons * SDL_strlen(separator) // length of separators + SDL_strlen(prefix) + SDL_strlen(suffix) // length of prefix/suffix + 1; // terminating null byte @@ -179,9 +181,17 @@ char *convert_ext_list(const char *list, const char *prefix, SDL_strlcat(converted, "*", total_length); } else { for (const char *c = list; *c; c++) { - if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') - || (*c >= '0' && *c <= '9') || *c == '-' || *c == '_' - || *c == '.') { + if (anycase && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z'))) { + char str[5]; + str[0] = '['; + str[1] = *c; + str[2] = *c ^ 0x20; // ASCII case toggle + str[3] = ']'; + str[4] = '\0'; + SDL_strlcat(converted, str, total_length); + } else if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') + || (*c >= '0' && *c <= '9') || *c == '-' || *c == '_' + || *c == '.') { char str[2]; str[0] = *c; str[1] = '\0'; diff --git a/src/dialog/SDL_dialog_utils.h b/src/dialog/SDL_dialog_utils.h index 773fb967bc..c1ad9237d6 100644 --- a/src/dialog/SDL_dialog_utils.h +++ b/src/dialog/SDL_dialog_utils.h @@ -37,19 +37,21 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, const char *separator, const char *suffix, const char *filt_prefix, const char *filt_separator, const char *filt_suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix); + const char *ext_separator, const char *ext_suffix, + bool anycase); // Converts one filter into a single string. // [filter name][filter extension list] char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf, const char *prefix, const char *separator, const char *suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix); + const char *ext_separator, const char *ext_suffix, + bool anycase); // Converts the extension list of a filter into a single string. // [extension]{[extension]...} char *convert_ext_list(const char *list, const char *prefix, - const char *separator, const char *suffix); + const char *separator, const char *suffix, bool anycase); /* Must be used if convert_* functions aren't used */ // Returns an error message if there's a problem, NULL otherwise diff --git a/src/dialog/unix/SDL_zenitydialog.c b/src/dialog/unix/SDL_zenitydialog.c index 6cd310ed93..7478a48217 100644 --- a/src/dialog/unix/SDL_zenitydialog.c +++ b/src/dialog/unix/SDL_zenitydialog.c @@ -192,7 +192,7 @@ static zenityArgs *create_zenity_args(SDL_FileDialogType type, SDL_DialogFileCal char *filter_str = convert_filter(filters[i], zenity_clean_name, "--file-filter=", " | ", "", - "*.", " *.", ""); + "*.", " *.", "", true); if (!filter_str) { while (i--) { diff --git a/src/dialog/windows/SDL_windowsdialog.c b/src/dialog/windows/SDL_windowsdialog.c index 400fcf03ad..99a49384d6 100644 --- a/src/dialog/windows/SDL_windowsdialog.c +++ b/src/dialog/windows/SDL_windowsdialog.c @@ -1143,7 +1143,7 @@ wchar_t *win_get_filters(const SDL_DialogFileFilter *filters, int nfilters) // suffix needs two null bytes in case the filter list is empty char *filterlist = convert_filters(filters, nfilters, clear_filt_names, "", "", "\x01\x01", "", "\x01", - "\x01", "*.", ";*.", ""); + "\x01", "*.", ";*.", "", false); if (!filterlist) { return NULL; From f8d5628163b487ab473a1cd848d3ddd1fe8f66f9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 21 Apr 2026 19:40:57 -0700 Subject: [PATCH 149/407] Fixed building with older versions of GameInput --- src/joystick/gdk/SDL_gameinputjoystick.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index 5d373a2550..bb511dda2b 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -419,9 +419,11 @@ static bool GAMEINPUT_JoystickInit(void) if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) { kind |= GameInputKindController; } +#if GAMEINPUT_API_VERSION >= 3 if (GAMEINPUT_IsRawGameInputEnabled()) { kind |= GameInputKindRawDeviceReport; } +#endif hr = g_pGameInput->RegisterDeviceCallback(NULL, kind, @@ -701,7 +703,8 @@ static bool GAMEINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool ena static void GAMEINPUT_GuitarUpdate(SDL_Joystick *joystick, IGameInputReading *reading, Uint64 timestamp) { - IGameInputRawDeviceReport* rawState; +#if GAMEINPUT_API_VERSION >= 3 + IGameInputRawDeviceReport *rawState; if (reading->GetRawReport(&rawState)) { static WORD s_GuitarButtons[] = { 0x0010, // SDL_GAMEPAD_BUTTON_SOUTH @@ -753,6 +756,7 @@ static void GAMEINPUT_GuitarUpdate(SDL_Joystick *joystick, IGameInputReading *re SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, effects_mappings[rawData[4] >> 4]); } } +#endif // GAMEINPUT_API_VERSION >= 3 } static void GAMEINPUT_GamepadUpdate(SDL_Joystick *joystick, IGameInputReading *reading, Uint64 timestamp) { From 7b23cd62ca0c94192b002d16e3f40180734b2567 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 23 Apr 2026 13:23:07 -0700 Subject: [PATCH 150/407] Revert "(video) fix SDL_GetClosestFullscreenDisplayMode aspect ratio & refresh rate picking logic" This reverts commit 0231ff03dee7ae2400ebdf274627052b32790a04. This causes SDL to return 1024x768 when asking for a best fit to 640x480 (thanks @AJenbo), so I'm reverting this until we can investigate more. --- src/video/SDL_video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index e3c4f66185..764eee219d 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1416,14 +1416,14 @@ bool SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, if (closest) { float current_aspect_ratio = (float)mode->w / mode->h; float closest_aspect_ratio = (float)closest->w / closest->h; - if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) <= SDL_fabsf(aspect_ratio - current_aspect_ratio)) { - // The mode we already found has a similar or better aspect ratio match + if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) < SDL_fabsf(aspect_ratio - current_aspect_ratio)) { + // The mode we already found has a better aspect ratio match continue; } if (mode->w == closest->w && mode->h == closest->h && - SDL_fabsf(closest->refresh_rate - refresh_rate) <= SDL_fabsf(mode->refresh_rate - refresh_rate)) { - /* We already found a mode and the new mode's refresh rate is the same or is further away from our + SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) { + /* We already found a mode and the new mode is further from our * refresh rate target */ continue; } From 9fa9edeadb846722429994a797ce293a30ec684d Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Thu, 23 Apr 2026 23:25:40 +0200 Subject: [PATCH 151/407] Prefer higher color depths in SDL_GetClosestFullscreenDisplayMode() --- src/video/SDL_video.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 764eee219d..9026e47fad 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1421,11 +1421,16 @@ bool SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, continue; } - if (mode->w == closest->w && mode->h == closest->h && - SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) { - /* We already found a mode and the new mode is further from our - * refresh rate target */ - continue; + if (mode->w == closest->w && mode->h == closest->h) { + if (SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) { + /* We already found a mode and the new mode is further from our + * refresh rate target */ + continue; + } + if (SDL_BYTESPERPIXEL(closest->format) >= SDL_BYTESPERPIXEL(mode->format)) { + // Prefer the highest color depth + continue; + } } } From 2858a32723924f2015ce44452b45505b02994103 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 23 Apr 2026 18:25:38 -0500 Subject: [PATCH 152/407] atomic: Use __atomic_thread_fence() when available This avoids requiring inline assembly for each architecture. It also fixes some weakly ordered architectures which lacked said inline assembly (RISC-V, MIPS, LoongArch, etc) and were thus disasterously broken. --- include/SDL3/SDL_atomic.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index 1ec0753da3..bbd5828df3 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -275,6 +275,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); */ #define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction() +#elif SDL_HAS_BUILTIN(__atomic_thread_fence) || (defined(__GNUC__) && (__GNUC__ >= 5)) +#define SDL_MemoryBarrierRelease() __atomic_thread_fence(__ATOMIC_RELEASE) +#define SDL_MemoryBarrierAcquire() __atomic_thread_fence(__ATOMIC_ACQUIRE) #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") From a8ecd677edc2d3a83939d4a749710762eca944f0 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 24 Apr 2026 01:54:49 +0200 Subject: [PATCH 153/407] Add DOS platform support (DJGPP) (#15377) * dos: Some initial work. * dos: Turn off buffer on stdio SDL_IOStreams. Seeking breaks otherwise. We might be able to just fflush() before or seeking instead? * dos: Audio implementation using the Sound Blaster 16. * dos: remove audio Pump interface. Turns out DosBox-X was having trouble with the Sound Blaster or something; standard DosBox works correctly directly from the interrupt handler, and without doubling the buffer size. * dos: just dump and restore the stdio buffer when seeking. This is MUCH faster than just leaving buffering disabled, and also works around getting bogus reads after an fseek. SDL_LoadWAV on test/sample.wav no longer takes several seconds to finish, and comes up with the correct data. I wonder if we're triggering this in LoadWAV because we're malloc'ing data between seeks/reads, and it's causing the djgpp transfer buffer to change. Or maybe the Fat DS trick is confusing it? I don't know, I haven't had time to debug it, it might just be a legit libc bug in djgpp too, for all I know. * dos: Protect audio device "thread" iterations when streams are locked. This uses an old trick we used in SDL 1.2 for MacOS Classic, which did its audio callback in a hardware interrupt. If the audio is locked when the interrupt fires, make a note of it and return immediately. When the lock is released, if the interrupt has been fired, run the audio device iteration right then. Since there isn't a big device lock in SDL3 (available to the app, at least), this keeps a counter of when any SDL_AudioStream is locked, which is probably good enough. * dos: Implemented initial video subsystem. This uses VESA interfaces to manage the display and works with the software renderer. Events aren't hooked up yet, so prepare to close DosBox on each run. :) * dos: Whoops, forgot to add these to revision control. Core and Main support. * dos: Wired up basic filesystem support. This gets most of the rendering examples, which use SDL_GetBasePath() to find textures to load, working. * dos: Fixed compiler warning. * dos: Initial mouse support! * dos: Move interrupt hooking code into core/dos. * dos: Initial keyboard support! * dos: Use a simple ring buffer for keyboard events. Of course Quake 1 solved this better, haha. It's smart: less memory, dirt simple, and you don't even have to worry about synchronizing with the interrupt handler, because it's safe for both sides no matter when an interrupt fires. * ci: add djgpp job [sdl-ci-filter djgpp] [sdl-ci-artifacts] * dos: Fix build issues after rebase onto current main - SDL_runapp.c: Add SDL_PLATFORM_DOS to the exclusion list so the generic SDL_RunApp() is disabled when the DOS-specific one is compiled. - SDL.c: Exclude SDL_Gtk_Quit() on DOS. DJGPP defines __unix__ which sets SDL_PLATFORM_UNIX, but DOS has no GTK/display server. The GTK source is not compiled (CMake UNIX is false for DOS) so this was a link error. - sdlplatform.cmake: Add DOS case to SDL_DetectCMakePlatform so the platform is properly detected from CMAKE_SYSTEM_NAME=DOS. - i586-pc-msdosdjgpp.cmake: Add i386-pc-msdosdjgpp-gcc as a fallback compiler name, since some DJGPP toolchain builds use the i386 prefix. * Add 8-bit palette support to DOS VESA driver * Add VBE page-flipping, state restore, and robust keyboard handling - Implement double-buffered page-flipping for VBE modes with >1 image page - Save and restore full VBE state on video init/quit for clean mode switching - Improve DOS keyboard handling: support extended scancodes and Pause key - Lock ISR code/data to prevent page faults during interrupts - Always vsync when blitting in single-buffered modes to reduce tearing * Refactor Sound Blaster audio mixing to main loop Move audio mixing out of IRQ handler to main loop for improved stability and to avoid reentrancy issues. Add SDL_DOS_PumpAudio function, update DMA buffer handling, and adjust sample rate to 22050 Hz. Silence stale DMA buffer halves to prevent stutter during load. * Add DOS timer support and update build config * Add support for pre-SB16 8-bit mono Sound Blaster audio Detect SB version and select 8-bit mono or 16-bit stereo mode. Handle DMA and DSP setup for both SB16 and pre-SB16 hardware. Add FORCE_SB_8BIT option for testing in DOSBox. * Add SB Pro stereo support and simplify IRQ handler * Add DOS joystick driver support * Improve DOS hardware handling and clarify memory allocation - Poll Sound Blaster DSP status instead of fixed delay after speaker-on - Clarify DPMI conventional memory is always locked; update comments - Document and justify DMA memory allocation strategy - Free IRET wrapper after restoring interrupt vector to avoid leaks - Throttle joystick axis polling to ~60 Hz to reduce BIOS timing loop cost - Always poll joystick buttons directly for responsiveness * Query and use mouse sensitivity from INT 33h function 0x1B * Add support for VESA banked framebuffer modes Implement banked framebuffer access for VBE 1.2+ modes without LFB. Detect and initialize banked modes, copy framebuffer data using bank switching, and blank the framebuffer on mode set. Page-flipping is disabled in banked mode. * Add optional vsync to page flipping in DOS VESA driver * Add cooperative threading support for DOS platform * Move SoundBlaster audio mixing to SDL audio thread * Fix DOS platform comments and workarounds for DJGPP support * Fix SoundBlaster IRQ handling and DMA setup for DOS - Pass IRQ number to DOS_EndOfInterrupt and handle slave PIC EOI - Validate DMA channel from BLASTER variable - Correct DMA page register selection for SB16 - Improve BLASTER variable parsing and error messages - Unmask/mask IRQs on correct PIC in DOS_HookInterrupt - Rename SDL_dosjoystick.c to SDL_sysjoystick.c - Include SDL_main_callbacks.h in SDL_sysmain_runapp.c - Add include guard to SDL_systhread_c.h * Add DOS platform options and preseed cache for DJGPP Disable unsupported SDL features when building for DOS. Add PreseedDOSCache.cmake to pre-populate CMake cache variables for DJGPP. * cmake: use a 8.3 naming scheme for tests on DOS * Apply code style * Update include/SDL3/SDL_platform_defines.h Co-authored-by: Anonymous Maarten * Code review clean up - Split DOS VESA mode-setting into its own file - Replace magic numbers with named constants - Update copyright dates to 2026 - Substract time taken by other threads form delays * Fix DOS bugs and improve compatibility - Disable fseeko64 for DJGPP due to broken implementation - Refactor DOS timer delay to always yield and avoid busy-waiting - Fix animated cursor rendering in DOS VESA backend - Always set display mode when creating DOS VESA window - Work around DJGPP allowing invalid file access in testfile.c - Bump max threads to 16 - Apply workarounds for threading tests * Add DOS platform documentation and fix a few issues - Fix fullscreen default resolution - Improve best mode matching - Fix builds on GCC older than 7.0 - Fix text input events * Fix keyboard mapping of "*" * Fix running, and existing, under PCem * Apply suggestions from code review Co-authored-by: Cameron Cawley * Pre-mix audio in ring buffer and copy to DMA via IRQ thread * Video fixes and optimizations * DOS: Fix Intel 740 and VGA compatability * DOS: Update readme * DOS: Fix thread ID, get GPU name * DOS: Cap mouse range * DOS: Map test resources to 8.3 names * DOS: Skip unsupported WM color modes * Fix "windowed" resolution selection * DOS: Hide INDEX8 modes behind SDL_DOS_ALLOW_INDEX8_MODES * Remove SDL_HINT_DOS_ALLOW_INDEX8_MODES and order modes logically * Don't convert cursor if dest is not INDEX8 --------- Co-authored-by: Ryan C. Gordon Co-authored-by: Anonymous Maarten Co-authored-by: Cameron Cawley Co-authored-by: Gleb Mazovetskiy Co-authored-by: Jay Petacat Tested-by: Cameron Cawley --- .../actions/setup-djgpp-toolchain/action.yml | 66 ++ .github/workflows/create-test-plan.py | 16 + .github/workflows/generic.yml | 4 + CMakeLists.txt | 65 +- build-scripts/djgpp-platform-overrides.cmake | 17 + build-scripts/i586-pc-msdosdjgpp.cmake | 82 ++ cmake/PreseedDOSCache.cmake | 208 ++++ cmake/macros.cmake | 2 +- cmake/sdlplatform.cmake | 2 + docs/README-dos.md | 90 ++ include/SDL3/SDL_hints.h | 17 + include/SDL3/SDL_main.h | 13 + include/SDL3/SDL_platform_defines.h | 10 + include/build_config/SDL_build_config.h.cmake | 7 +- src/SDL.c | 2 + src/audio/SDL_audio.c | 3 + src/audio/SDL_sysaudio.h | 1 + src/audio/dos/SDL_dosaudio_sb.c | 631 ++++++++++++ src/audio/dos/SDL_dosaudio_sb.h | 47 + src/core/dos/SDL_dos.c | 142 +++ src/core/dos/SDL_dos.h | 156 +++ src/core/dos/SDL_dos_scheduler.c | 318 ++++++ src/core/dos/SDL_dos_scheduler.h | 107 ++ src/dynapi/SDL_dynapi.h | 2 + src/filesystem/dos/SDL_sysfilesystem.c | 105 ++ src/joystick/SDL_joystick.c | 3 + src/joystick/SDL_sysjoystick.h | 1 + src/joystick/dos/SDL_sysjoystick.c | 342 +++++++ src/main/SDL_runapp.c | 3 +- src/main/dos/SDL_sysmain_runapp.c | 51 + src/stdlib/SDL_string.c | 2 +- src/thread/SDL_thread_c.h | 2 + src/thread/dos/SDL_sysmutex.c | 122 +++ src/thread/dos/SDL_syssem.c | 115 +++ src/thread/dos/SDL_systhread.c | 87 ++ src/thread/dos/SDL_systhread_c.h | 28 + src/thread/dos/SDL_systls.c | 63 ++ src/time/unix/SDL_systime.c | 2 + src/timer/dos/SDL_systimer.c | 70 ++ src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 3 + src/video/dos/SDL_dosevents.c | 397 +++++++ src/video/dos/SDL_dosevents_c.h | 31 + src/video/dos/SDL_dosframebuffer.c | 969 ++++++++++++++++++ src/video/dos/SDL_dosframebuffer_c.h | 34 + src/video/dos/SDL_dosmodes.c | 688 +++++++++++++ src/video/dos/SDL_dosmodes.h | 50 + src/video/dos/SDL_dosmouse.c | 170 +++ src/video/dos/SDL_dosmouse.h | 39 + src/video/dos/SDL_dosvideo.c | 356 +++++++ src/video/dos/SDL_dosvideo.h | 89 ++ test/CMakeLists.txt | 195 ++-- test/testfile.c | 8 + test/testime.c | 4 + test/testsem.c | 4 + test/testutils.c | 55 + test/testwm.c | 3 + test/torturethread.c | 8 +- 58 files changed, 6012 insertions(+), 96 deletions(-) create mode 100644 .github/actions/setup-djgpp-toolchain/action.yml create mode 100644 build-scripts/djgpp-platform-overrides.cmake create mode 100644 build-scripts/i586-pc-msdosdjgpp.cmake create mode 100644 cmake/PreseedDOSCache.cmake create mode 100644 docs/README-dos.md create mode 100644 src/audio/dos/SDL_dosaudio_sb.c create mode 100644 src/audio/dos/SDL_dosaudio_sb.h create mode 100644 src/core/dos/SDL_dos.c create mode 100644 src/core/dos/SDL_dos.h create mode 100644 src/core/dos/SDL_dos_scheduler.c create mode 100644 src/core/dos/SDL_dos_scheduler.h create mode 100644 src/filesystem/dos/SDL_sysfilesystem.c create mode 100644 src/joystick/dos/SDL_sysjoystick.c create mode 100644 src/main/dos/SDL_sysmain_runapp.c create mode 100644 src/thread/dos/SDL_sysmutex.c create mode 100644 src/thread/dos/SDL_syssem.c create mode 100644 src/thread/dos/SDL_systhread.c create mode 100644 src/thread/dos/SDL_systhread_c.h create mode 100644 src/thread/dos/SDL_systls.c create mode 100644 src/timer/dos/SDL_systimer.c create mode 100644 src/video/dos/SDL_dosevents.c create mode 100644 src/video/dos/SDL_dosevents_c.h create mode 100644 src/video/dos/SDL_dosframebuffer.c create mode 100644 src/video/dos/SDL_dosframebuffer_c.h create mode 100644 src/video/dos/SDL_dosmodes.c create mode 100644 src/video/dos/SDL_dosmodes.h create mode 100644 src/video/dos/SDL_dosmouse.c create mode 100644 src/video/dos/SDL_dosmouse.h create mode 100644 src/video/dos/SDL_dosvideo.c create mode 100644 src/video/dos/SDL_dosvideo.h diff --git a/.github/actions/setup-djgpp-toolchain/action.yml b/.github/actions/setup-djgpp-toolchain/action.yml new file mode 100644 index 0000000000..7b10dc8afb --- /dev/null +++ b/.github/actions/setup-djgpp-toolchain/action.yml @@ -0,0 +1,66 @@ +name: 'Setup DJGPP toolchain' +description: 'Download DJGPP and setup CMake toolchain' +runs: + using: 'composite' + steps: + - name: 'Calculate variables' + id: calc + shell: sh + run: | + version="12.2.0" + case "${{ runner.os }}-${{ runner.arch }}" in + "Linux-X86") + archive="djgpp-linux32-gcc1220.tar.bz2" + ;; + "Linux-X64") + archive="djgpp-linux64-gcc1220.tar.bz2" + ;; + "macOS-X86" | "macOS-X64" | "macOS-ARM64") + archive="djgpp-osx-gcc1220.tar.bz2" + ;; + "Windows-X86" | "Windows-X64") + archive="djgpp-mingw-gcc1220.zip" + ;; + *) + echo "Unsupported ${{ runner.os }}-${{ runner.arch }}" + exit 1; + ;; + esac + echo "url=https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/${archive}" >> ${GITHUB_OUTPUT} + echo "archive=${archive}" >> ${GITHUB_OUTPUT} + echo "version=${version}" >> ${GITHUB_OUTPUT} + echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT} + - name: 'Restore cached ${{ steps.calc.outputs.archive }}' + id: cache-restore + uses: actions/cache/restore@v4 + with: + path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Download DJGPP ${{ steps.calc.outputs.version }} for ${{ runner.os }} (${{ runner.arch }})' + if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} + shell: pwsh + run: | + Invoke-WebRequest "${{ steps.calc.outputs.url }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" + - name: 'Cache ${{ steps.calc.outputs.archive }}' + if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} + uses: actions/cache/save@v4 + with: + path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Extract DJGP archive' + shell: pwsh + run: | + $archive = "${{ steps.calc.outputs.archive }}"; + if ($archive.EndsWith(".bz2")) { + # Remove ".bz2" suffix + $tar_archive = $archive.Substring(0, $archive.Length - 4) + 7z "-o${{ runner.temp }}" x "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" + 7z "-o${{ runner.temp }}" x "${{ runner.temp }}/$tar_archive" + } else { + 7z "-o${{ runner.temp }}" x "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" + } + - name: 'Set output variables' + id: final + shell: pwsh + run: | + echo "${{ runner.temp }}/djgpp/bin" >> $env:GITHUB_PATH diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index f84ca1b153..c0e847c05f 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -58,6 +58,7 @@ class SdlPlatform(Enum): NetBSD = "netbsd" OpenBSD = "openbsd" NGage = "ngage" + DJGPP = "djgpp" class Msys2Platform(Enum): @@ -149,6 +150,7 @@ JOB_SPECS = { "openbsd": JobSpec(name="OpenBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.OpenBSD, artifact="SDL-openbsd-x64", ), "freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ), "ngage": JobSpec(name="N-Gage", os=JobOs.WindowsLatest, platform=SdlPlatform.NGage, artifact="SDL-ngage", ), + "djgpp": JobSpec(name="DOS (DJGPP)", os=JobOs.UbuntuLatest, platform=SdlPlatform.DJGPP, artifact="SDL-djgpp", ), } @@ -821,6 +823,20 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args job.setup_gage_sdk_path = "C:/ngagesdk" job.cmake_toolchain_file = "C:/ngagesdk/cmake/ngage-toolchain.cmake" job.test_pkg_config = False + case SdlPlatform.DJGPP: + build_parallel = False + job.ccache = True + job.apt_packages = ["ccache", "libfl-dev"] # djgpp needs libfl.so.2 + job.cmake_build_type = "Release" + job.setup_ninja = True + job.static_lib = StaticLibType.A + job.shared_lib = None + job.clang_tidy = False + job.werror = False # FIXME: enable SDL_WERROR + job.shared = False + job.run_tests = False + job.test_pkg_config = False + job.cmake_toolchain_file = "$GITHUB_WORKSPACE/build-scripts/i586-pc-msdosdjgpp.cmake" case _: raise ValueError(f"Unsupported platform={spec.platform}") diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 82fcbaf156..10f241c023 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -100,6 +100,10 @@ jobs: uses: ./.github/actions/setup-loongarch64-toolchain id: setup-loongarch64-toolchain if: ${{ matrix.platform.platform == 'loongarch64' }} + - name: 'Set up DJGPP toolchain' + uses: ./.github/actions/setup-djgpp-toolchain + id: setup-djgpp-toolchain + if: ${{ matrix.platform.platform == 'djgpp' }} - name: 'Setup Intel oneAPI toolchain' id: intel if: ${{ matrix.platform.intel }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 111e0cb0b1..86b0214b85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ include("${SDL3_SOURCE_DIR}/cmake/3rdparty.cmake") include("${SDL3_SOURCE_DIR}/cmake/PreseedMSVCCache.cmake") include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake") include("${SDL3_SOURCE_DIR}/cmake/PreseedNokiaNGageCache.cmake") +include("${SDL3_SOURCE_DIR}/cmake/PreseedDOSCache.cmake") SDL_DetectCompiler() SDL_DetectTargetCPUArchitectures(SDL_CPUS) @@ -163,7 +164,7 @@ endif() # The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, # so we'll just use libusb when it's available. libusb does not support iOS, # so we default to yes on iOS. -if(IOS OR TVOS OR VISIONOS OR WATCHOS OR ANDROID OR NGAGE) +if(IOS OR TVOS OR VISIONOS OR WATCHOS OR ANDROID OR NGAGE OR DOS) set(SDL_HIDAPI_LIBUSB_AVAILABLE FALSE) else() set(SDL_HIDAPI_LIBUSB_AVAILABLE TRUE) @@ -207,7 +208,7 @@ if(EMSCRIPTEN) set(SDL_SHARED_AVAILABLE OFF) endif() -if(VITA OR PSP OR PS2 OR N3DS OR RISCOS OR NGAGE) +if(VITA OR PSP OR PS2 OR N3DS OR RISCOS OR NGAGE OR DOS) set(SDL_SHARED_AVAILABLE OFF) endif() @@ -425,6 +426,21 @@ if(VITA) set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF) endif() +if(DOS) + set(SDL_GPU OFF) + set(SDL_CAMERA OFF) + set(SDL_HAPTIC OFF) + set(SDL_HIDAPI OFF) + set(SDL_POWER OFF) + set(SDL_SENSOR OFF) + set(SDL_DIALOG OFF) + set(SDL_DUMMYCAMERA OFF) + set(SDL_OFFSCREEN OFF) + set(SDL_RENDER_GPU OFF) + set(SDL_TRAY OFF) + set(SDL_PROCESS OFF) +endif() + if (NGAGE) set(SDL_GPU OFF) set(SDL_CAMERA OFF) @@ -3332,6 +3348,51 @@ elseif(N3DS) "${SDL3_SOURCE_DIR}/src/io/n3ds/*.h" ) +elseif(DOS) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/dos/*.c") + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/dos/*.c") + + set(SDL_AUDIO_DRIVER_DOS_SOUNDBLASTER 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/audio/dos/*.c") + set(HAVE_SDL_AUDIO TRUE) + + set(SDL_VIDEO_DRIVER_DOSVESA 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/dos/*.c") + set(HAVE_SDL_VIDEO TRUE) + + set(SDL_FSOPS_POSIX 1) + sdl_sources("${SDL3_SOURCE_DIR}/src/filesystem/posix/SDL_sysfsops.c") + set(HAVE_SDL_FSOPS TRUE) + + set(SDL_FILESYSTEM_DOS 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/dos/*.c") + set(HAVE_SDL_FILESYSTEM TRUE) + + # Wall-clock time (SDL_GetDateTimeLocalized etc.) reuses the Unix implementation; + # DJGPP provides gettimeofday/localtime so this works as-is. + set(SDL_TIME_UNIX 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/unix/*.c") + set(HAVE_SDL_TIME TRUE) + + set(SDL_TIMER_DOS 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/timer/dos/*.c") + set(HAVE_SDL_TIMERS TRUE) + + set(SDL_JOYSTICK_DOS 1) + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/joystick/dos/*.c") + set(HAVE_SDL_JOYSTICK TRUE) + + set(SDL_THREAD_DOS 1) + sdl_glob_sources( + "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_syscond.c" + "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_syscond_c.h" + "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_sysrwlock.c" + "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_sysrwlock_c.h" + "${SDL3_SOURCE_DIR}/src/thread/dos/*.c" + "${SDL3_SOURCE_DIR}/src/thread/dos/*.h" + ) + set(HAVE_SDL_THREADS TRUE) + elseif(NGAGE) enable_language(CXX) diff --git a/build-scripts/djgpp-platform-overrides.cmake b/build-scripts/djgpp-platform-overrides.cmake new file mode 100644 index 0000000000..c919f843f5 --- /dev/null +++ b/build-scripts/djgpp-platform-overrides.cmake @@ -0,0 +1,17 @@ +# DJGPP platform overrides for DOS +# +# CMake's built-in Platform/DOS.cmake assumes OpenWatcom naming conventions +# (no prefix, .lib suffix, CMAKE_LINK_LIBRARY_SUFFIX=".lib"). DJGPP uses +# standard Unix/GCC conventions for its system libraries (lib prefix, .a +# suffix — e.g. libm.a). +# +# This file is loaded via CMAKE_USER_MAKE_RULES_OVERRIDE in the toolchain +# file, which runs *after* the platform module has set its defaults, giving +# us the final say on these variables. + +set(CMAKE_STATIC_LIBRARY_PREFIX "lib") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") +set(CMAKE_LINK_LIBRARY_SUFFIX "") +set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib") +set(CMAKE_EXECUTABLE_SUFFIX ".exe") \ No newline at end of file diff --git a/build-scripts/i586-pc-msdosdjgpp.cmake b/build-scripts/i586-pc-msdosdjgpp.cmake new file mode 100644 index 0000000000..8a4e765f14 --- /dev/null +++ b/build-scripts/i586-pc-msdosdjgpp.cmake @@ -0,0 +1,82 @@ +set(CMAKE_SYSTEM_NAME DOS) + +set(DJGPP TRUE) + +# CMake's Platform/DOS.cmake assumes OpenWatcom naming conventions (no prefix, +# .lib suffix). DJGPP uses standard Unix/GCC conventions for its system +# libraries (lib prefix, .a suffix — e.g. libm.a), so we override the platform +# defaults via CMAKE_USER_MAKE_RULES_OVERRIDE, which runs *after* the platform +# module has set its defaults, giving us the final say on these variables. +# The path must be cached because CMake re-parses the toolchain file during +# try_compile, where CMAKE_CURRENT_LIST_DIR may point elsewhere. +set(DJGPP_PLATFORM_OVERRIDES "${CMAKE_CURRENT_LIST_DIR}/djgpp-platform-overrides.cmake" CACHE FILEPATH "" FORCE) +set(CMAKE_USER_MAKE_RULES_OVERRIDE "${DJGPP_PLATFORM_OVERRIDES}") + +set(CMAKE_STATIC_LIBRARY_PREFIX "lib") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") +set(CMAKE_IMPORT_LIBRARY_PREFIX "lib") +set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a") +set(CMAKE_EXECUTABLE_SUFFIX ".exe") +set(CMAKE_LINK_LIBRARY_SUFFIX "") +set(CMAKE_DL_LIBS "") + +set(CMAKE_FIND_LIBRARY_PREFIXES "lib") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + +# +# CMake toolchain file for DJGPP. Usage: +# +# 1. Download and extract DGJPP +# 2. Add directory containing i586-pc-msdosdjgpp-gcc to PATH environment variable +# 3. When configuring your CMake project, specify the toolchain file like this: +# +# cmake -DCMAKE_TOOLCHAIN_FILE=path/to/i586-pc-msdosdjgpp.cmake ... +# + +# specify the cross compiler +find_program(CMAKE_C_COMPILER NAMES "i586-pc-msdosdjgpp-gcc" "i386-pc-msdosdjgpp-gcc" REQUIRED) +find_program(CMAKE_CXX_COMPILER NAMES "i586-pc-msdosdjgpp-g++" "i386-pc-msdosdjgpp-g++" REQUIRED) + +execute_process(COMMAND "${CMAKE_C_COMPILER}" -print-search-dirs + RESULT_VARIABLE CC_SEARCH_DIRS_RESULT + OUTPUT_VARIABLE CC_SEARCH_DIRS_OUTPUT) + +if(CC_SEARCH_DIRS_RESULT) + message(FATAL_ERROR "Could not determine search dirs") +endif() + +string(REGEX MATCH ".*libraries: (.*).*" CC_SD_LIBS "${CC_SEARCH_DIRS_OUTPUT}") +string(STRIP "${CMAKE_MATCH_1}" CC_SEARCH_DIRS) +string(REPLACE ":" ";" CC_SEARCH_DIRS "${CC_SEARCH_DIRS}") + +foreach(CC_SEARCH_DIR ${CC_SEARCH_DIRS}) + if(CC_SEARCH_DIR MATCHES "=.*") + string(REGEX MATCH "=(.*)" CC_LIB "${CC_SEARCH_DIR}") + set(CC_SEARCH_DIR "${CMAKE_MATCH_1}") + endif() + if(IS_DIRECTORY "${CC_SEARCH_DIR}") + if(IS_DIRECTORY "${CC_SEARCH_DIR}/../include" OR IS_DIRECTORY "${CC_SEARCH_DIR}/../lib" OR IS_DIRECTORY "${CC_SEARCH_DIR}/../bin") + list(APPEND CC_ROOTS "${CC_SEARCH_DIR}/..") + else() + list(APPEND CC_ROOTS "${CC_SEARCH_DIR}") + endif() + endif() +endforeach() + +list(APPEND CMAKE_FIND_ROOT_PATH ${CC_ROOTS}) + +# search for programs in the host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# for libraries, headers and packages in the target directories +if(NOT DEFINED CACHE{CMAKE_FIND_ROOT_PATH_MODE_LIBRARY}) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +endif() +if(NOT DEFINED CACHE{CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() +if(NOT DEFINED CACHE{CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +endif() \ No newline at end of file diff --git a/cmake/PreseedDOSCache.cmake b/cmake/PreseedDOSCache.cmake new file mode 100644 index 0000000000..e5a37a41ca --- /dev/null +++ b/cmake/PreseedDOSCache.cmake @@ -0,0 +1,208 @@ +if(CMAKE_SYSTEM_NAME STREQUAL "DOS") + function(SDL_Preseed_CMakeCache) + # SIMD intrinsics: disabled for DOS regardless of compiler version. + # The DJGPP cross-compiler can *compile* SSE/AVX/MMX, but no real DOS + # target machine supports them. Enabling these caused audio breakage. + set(COMPILER_SUPPORTS_ARMNEON "" CACHE INTERNAL "Test COMPILER_SUPPORTS_ARMNEON") + set(COMPILER_SUPPORTS_AVX "" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX") + set(COMPILER_SUPPORTS_AVX2 "" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX2") + set(COMPILER_SUPPORTS_AVX512F "" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX512F") + set(COMPILER_SUPPORTS_MMX "" CACHE INTERNAL "Test COMPILER_SUPPORTS_MMX") + set(COMPILER_SUPPORTS_SSE "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE") + set(COMPILER_SUPPORTS_SSE2 "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE2") + set(COMPILER_SUPPORTS_SSE3 "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE3") + set(COMPILER_SUPPORTS_SSE4_1 "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_1") + set(COMPILER_SUPPORTS_SSE4_2 "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_2") + + check_c_source_compiles(" + #if !defined(__GNUC__) || (__GNUC__ < 7) + #error Preseeding is only supported for DJGPP GCC 7 or newer + #endif + int main(int argc, char **argv) { return 0; } + " CAN_PRESEED + ) + if(CAN_PRESEED) + set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS") + set(COMPILER_SUPPORTS_GCC_ATOMICS "" CACHE INTERNAL "Test COMPILER_SUPPORTS_GCC_ATOMICS") + set(COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET") + set(HAVE_CLANG_COMMENT_BLOCK_COMMANDS "" CACHE INTERNAL "Test HAVE_CLANG_COMMENT_BLOCK_COMMANDS") + set(HAVE_ALLOCA_H "" CACHE INTERNAL "Have include alloca.h") + set(HAVE_LIBM "1" CACHE INTERNAL "Have library m") + set(HAVE_POSIX_SPAWN "" CACHE INTERNAL "Have symbol posix_spawn") + set(HAVE_FSEEKO "1" CACHE INTERNAL "Have symbol fseeko") + set(HAVE_OFF64_T "1" CACHE INTERNAL "Have symbol off64_t") + set(LIBC_HAS_ABS "1" CACHE INTERNAL "Have symbol abs") + set(LIBC_HAS_ACOS "1" CACHE INTERNAL "Have symbol acos") + set(LIBC_HAS_ACOSF "1" CACHE INTERNAL "Have symbol acosf") + set(LIBC_HAS_ASIN "1" CACHE INTERNAL "Have symbol asin") + set(LIBC_HAS_ASINF "1" CACHE INTERNAL "Have symbol asinf") + set(LIBC_HAS_ATAN "1" CACHE INTERNAL "Have symbol atan") + set(LIBC_HAS_ATAN2 "1" CACHE INTERNAL "Have symbol atan2") + set(LIBC_HAS_ATAN2F "1" CACHE INTERNAL "Have symbol atan2f") + set(LIBC_HAS_ATANF "1" CACHE INTERNAL "Have symbol atanf") + set(LIBC_HAS_ATOF "1" CACHE INTERNAL "Have symbol atof") + set(LIBC_HAS_ATOI "1" CACHE INTERNAL "Have symbol atoi") + set(LIBC_HAS_BCOPY "1" CACHE INTERNAL "Have symbol bcopy") + set(LIBC_HAS_CALLOC "" CACHE INTERNAL "Have symbol calloc") + set(LIBC_HAS_CEIL "1" CACHE INTERNAL "Have symbol ceil") + set(LIBC_HAS_CEILF "1" CACHE INTERNAL "Have symbol ceilf") + set(LIBC_HAS_COPYSIGN "1" CACHE INTERNAL "Have symbol copysign") + set(LIBC_HAS_COPYSIGNF "1" CACHE INTERNAL "Have symbol copysignf") + set(LIBC_HAS_COS "1" CACHE INTERNAL "Have symbol cos") + set(LIBC_HAS_COSF "1" CACHE INTERNAL "Have symbol cosf") + set(LIBC_HAS_EXP "1" CACHE INTERNAL "Have symbol exp") + set(LIBC_HAS_EXPF "1" CACHE INTERNAL "Have symbol expf") + set(LIBC_HAS_FABS "1" CACHE INTERNAL "Have symbol fabs") + set(LIBC_HAS_FABSF "1" CACHE INTERNAL "Have symbol fabsf") + set(LIBC_HAS_FLOAT_H "1" CACHE INTERNAL "Have include float.h") + set(LIBC_HAS_FLOOR "1" CACHE INTERNAL "Have symbol floor") + set(LIBC_HAS_FLOORF "1" CACHE INTERNAL "Have symbol floorf") + set(LIBC_HAS_FMOD "1" CACHE INTERNAL "Have symbol fmod") + set(LIBC_HAS_FMODF "1" CACHE INTERNAL "Have symbol fmodf") + set(LIBC_HAS_FOPEN64 "" CACHE INTERNAL "Have symbol fopen64") + set(LIBC_HAS_FREE "" CACHE INTERNAL "Have symbol free") + set(LIBC_HAS_FSEEKO "1" CACHE INTERNAL "Have symbol fseeko") + set(LIBC_HAS_FSEEKO64 "" CACHE INTERNAL "Have symbol fseeko64 (broken in DJGPP)") + set(LIBC_HAS_GETENV "1" CACHE INTERNAL "Have symbol getenv") + set(LIBC_HAS_ICONV_H "" CACHE INTERNAL "Have include iconv.h") + set(LIBC_HAS_INDEX "1" CACHE INTERNAL "Have symbol index") + set(LIBC_HAS_INTTYPES_H "1" CACHE INTERNAL "Have include inttypes.h") + set(LIBC_HAS_ISINF "1" CACHE INTERNAL "Have include isinf(double)") + set(LIBC_ISINF_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isinf(float)") + set(LIBC_HAS_ISINFF "1" CACHE INTERNAL "Have include isinff(float)") + set(LIBC_HAS_ISNAN "1" CACHE INTERNAL "Have include isnan(double)") + set(LIBC_ISNAN_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isnan(float)") + set(LIBC_HAS_ISNANF "1" CACHE INTERNAL "Have include isnanf(float)") + set(LIBC_HAS_ITOA "1" CACHE INTERNAL "Have symbol itoa") + set(LIBC_HAS_LIMITS_H "1" CACHE INTERNAL "Have include limits.h") + set(LIBC_HAS_LOG "1" CACHE INTERNAL "Have symbol log") + set(LIBC_HAS_LOG10 "1" CACHE INTERNAL "Have symbol log10") + set(LIBC_HAS_LOG10F "1" CACHE INTERNAL "Have symbol log10f") + set(LIBC_HAS_LOGF "1" CACHE INTERNAL "Have symbol logf") + set(LIBC_HAS_LROUND "1" CACHE INTERNAL "Have symbol lround") + set(LIBC_HAS_LROUNDF "1" CACHE INTERNAL "Have symbol lroundf") + set(LIBC_HAS_MALLOC "1" CACHE INTERNAL "Have symbol malloc") + set(LIBC_HAS_MALLOC_H "1" CACHE INTERNAL "Have include malloc.h") + set(LIBC_HAS_MATH_H "1" CACHE INTERNAL "Have include math.h") + set(LIBC_HAS_MEMCMP "1" CACHE INTERNAL "Have symbol memcmp") + set(LIBC_HAS_MEMCPY "1" CACHE INTERNAL "Have symbol memcpy") + set(LIBC_HAS_MEMMOVE "1" CACHE INTERNAL "Have symbol memmove") + set(LIBC_HAS_MEMORY_H "1" CACHE INTERNAL "Have include memory.h") + set(LIBC_HAS_MEMSET "1" CACHE INTERNAL "Have symbol memset") + set(LIBC_HAS_MODF "1" CACHE INTERNAL "Have symbol modf") + set(LIBC_HAS_MODFF "1" CACHE INTERNAL "Have symbol modff") + set(LIBC_HAS_POW "1" CACHE INTERNAL "Have symbol pow") + set(LIBC_HAS_POWF "1" CACHE INTERNAL "Have symbol powf") + set(LIBC_HAS_PUTENV "1" CACHE INTERNAL "Have symbol putenv") + set(LIBC_HAS_REALLOC "" CACHE INTERNAL "Have symbol realloc") + set(LIBC_HAS_RINDEX "1" CACHE INTERNAL "Have symbol rindex") + set(LIBC_HAS_ROUND "1" CACHE INTERNAL "Have symbol round") + set(LIBC_HAS_ROUNDF "1" CACHE INTERNAL "Have symbol roundf") + set(LIBC_HAS_SCALBN "1" CACHE INTERNAL "Have symbol scalbn") + set(LIBC_HAS_SCALBNF "1" CACHE INTERNAL "Have symbol scalbnf") + set(LIBC_HAS_SETENV "1" CACHE INTERNAL "Have symbol setenv") + set(LIBC_HAS_SIGNAL_H "1" CACHE INTERNAL "Have include signal.h") + set(LIBC_HAS_SIN "1" CACHE INTERNAL "Have symbol sin") + set(LIBC_HAS_SINF "1" CACHE INTERNAL "Have symbol sinf") + set(LIBC_HAS_SQR "" CACHE INTERNAL "Have symbol sqr") + set(LIBC_HAS_SQRT "1" CACHE INTERNAL "Have symbol sqrt") + set(LIBC_HAS_SQRTF "1" CACHE INTERNAL "Have symbol sqrtf") + set(LIBC_HAS_SSCANF "1" CACHE INTERNAL "Have symbol sscanf") + set(LIBC_HAS_STDARG_H "1" CACHE INTERNAL "Have include stdarg.h") + set(LIBC_HAS_STDBOOL_H "1" CACHE INTERNAL "Have include stdbool.h") + set(LIBC_HAS_STDDEF_H "1" CACHE INTERNAL "Have include stddef.h") + set(LIBC_HAS_STDINT_H "1" CACHE INTERNAL "Have include stdint.h") + set(LIBC_HAS_STDIO_H "1" CACHE INTERNAL "Have include stdio.h") + set(LIBC_HAS_STDLIB_H "1" CACHE INTERNAL "Have include stdlib.h") + set(LIBC_HAS_STRCASESTR "" CACHE INTERNAL "Have symbol strcasestr") + set(LIBC_HAS_STRCHR "1" CACHE INTERNAL "Have symbol strchr") + set(LIBC_HAS_STRCMP "1" CACHE INTERNAL "Have symbol strcmp") + set(LIBC_HAS_STRINGS_H "1" CACHE INTERNAL "Have include strings.h") + set(LIBC_HAS_STRING_H "1" CACHE INTERNAL "Have include string.h") + set(LIBC_HAS_STRLCAT "1" CACHE INTERNAL "Have symbol strlcat") + set(LIBC_HAS_STRLCPY "1" CACHE INTERNAL "Have symbol strlcpy") + set(LIBC_HAS_STRLEN "1" CACHE INTERNAL "Have symbol strlen") + set(LIBC_HAS_STRNCMP "1" CACHE INTERNAL "Have symbol strncmp") + set(LIBC_HAS_STRNLEN "1" CACHE INTERNAL "Have symbol strnlen") + set(LIBC_HAS_STRNSTR "" CACHE INTERNAL "Have symbol strnstr") + set(LIBC_HAS_STRPBRK "1" CACHE INTERNAL "Have symbol strpbrk") + set(LIBC_HAS_STRRCHR "1" CACHE INTERNAL "Have symbol strrchr") + set(LIBC_HAS_STRSTR "1" CACHE INTERNAL "Have symbol strstr") + set(LIBC_HAS_STRTOD "1" CACHE INTERNAL "Have symbol strtod") + set(LIBC_HAS_STRTOK_R "1" CACHE INTERNAL "Have symbol strtok_r") + set(LIBC_HAS_STRTOL "1" CACHE INTERNAL "Have symbol strtol") + set(LIBC_HAS_STRTOLL "1" CACHE INTERNAL "Have symbol strtoll") + set(LIBC_HAS_STRTOUL "1" CACHE INTERNAL "Have symbol strtoul") + set(LIBC_HAS_STRTOULL "1" CACHE INTERNAL "Have symbol strtoull") + set(LIBC_HAS_SYS_TYPES_H "1" CACHE INTERNAL "Have include sys/types.h") + set(LIBC_HAS_TAN "1" CACHE INTERNAL "Have symbol tan") + set(LIBC_HAS_TANF "1" CACHE INTERNAL "Have symbol tanf") + set(LIBC_HAS_TIME_H "1" CACHE INTERNAL "Have include time.h") + set(LIBC_HAS_TRUNC "1" CACHE INTERNAL "Have symbol trunc") + set(LIBC_HAS_TRUNCF "1" CACHE INTERNAL "Have symbol truncf") + set(LIBC_HAS_UNSETENV "1" CACHE INTERNAL "Have symbol unsetenv") + set(LIBC_HAS_VSNPRINTF "1" CACHE INTERNAL "Have symbol vsnprintf") + set(LIBC_HAS_VSSCANF "1" CACHE INTERNAL "Have symbol vsscanf") + set(LIBC_HAS_WCHAR_H "1" CACHE INTERNAL "Have include wchar.h") + set(LIBC_HAS_WCSCMP "" CACHE INTERNAL "Have symbol wcscmp") + set(LIBC_HAS_WCSDUP "" CACHE INTERNAL "Have symbol wcsdup") + set(LIBC_HAS_WCSLCAT "" CACHE INTERNAL "Have symbol wcslcat") + set(LIBC_HAS_WCSLCPY "" CACHE INTERNAL "Have symbol wcslcpy") + set(LIBC_HAS_WCSLEN "" CACHE INTERNAL "Have symbol wcslen") + set(LIBC_HAS_WCSNCMP "" CACHE INTERNAL "Have symbol wcsncmp") + set(LIBC_HAS_WCSNLEN "" CACHE INTERNAL "Have symbol wcsnlen") + set(LIBC_HAS_WCSSTR "" CACHE INTERNAL "Have symbol wcsstr") + set(LIBC_HAS_WCSTOL "" CACHE INTERNAL "Have symbol wcstol") + set(LIBC_HAS__EXIT "1" CACHE INTERNAL "Have symbol _Exit") + set(LIBC_HAS__I64TOA "" CACHE INTERNAL "Have symbol _i64toa") + set(LIBC_HAS__LTOA "" CACHE INTERNAL "Have symbol _ltoa") + set(LIBC_HAS__STRREV "" CACHE INTERNAL "Have symbol _strrev") + set(LIBC_HAS__UITOA "" CACHE INTERNAL "Have symbol _uitoa") + set(LIBC_HAS__ULTOA "" CACHE INTERNAL "Have symbol _ultoa") + set(LIBC_HAS__WCSDUP "" CACHE INTERNAL "Have symbol _wcsdup") + set(LIBC_IS_GLIBC "" CACHE INTERNAL "Have symbol __GLIBC__") + set(HAVE_GCC_WALL "1" CACHE INTERNAL "Test HAVE_GCC_WALL") + set(HAVE_GCC_WUNDEF "1" CACHE INTERNAL "Test HAVE_GCC_WUNDEF") + set(HAVE_GCC_WFLOAT_CONVERSION "1" CACHE INTERNAL "Test HAVE_GCC_WFLOAT_CONVERSION") + set(HAVE_GCC_NO_STRICT_ALIASING "1" CACHE INTERNAL "Test HAVE_GCC_NO_STRICT_ALIASING") + set(HAVE_GCC_WDOCUMENTATION "" CACHE INTERNAL "Test HAVE_GCC_WDOCUMENTATION") + set(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND "" CACHE INTERNAL "Test HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND") + set(HAVE_GCC_COMMENT_BLOCK_COMMANDS "" CACHE INTERNAL "Test HAVE_GCC_COMMENT_BLOCK_COMMANDS") + set(HAVE_GCC_WSHADOW "1" CACHE INTERNAL "Test HAVE_GCC_WSHADOW") + set(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS "1" CACHE INTERNAL "Test HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS") + set(HAVE_GCC_WIMPLICIT_FALLTHROUGH "1" CACHE INTERNAL "Test HAVE_GCC_WIMPLICIT_FALLTHROUGH") + set(HAVE_GCC_FVISIBILITY "" CACHE INTERNAL "Test HAVE_GCC_FVISIBILITY") + set(HAVE_ST_MTIM "" CACHE INTERNAL "Test HAVE_ST_MTIM") + set(HAVE_LD_VERSION_SCRIPT "1" CACHE INTERNAL "Test HAVE_LD_VERSION_SCRIPT") + set(HAVE_WL_VERSION_SCRIPT "1" CACHE INTERNAL "Test HAVE_WL_VERSION_SCRIPT") + set(LINKER_SUPPORTS_VERSION_SCRIPT "1" CACHE INTERNAL "Test LINKER_SUPPORTS_VERSION_SCRIPT") + set(LINKER_SUPPORTS_WL_NO_UNDEFINED "1" CACHE INTERNAL "Test LINKER_SUPPORTS_WL_NO_UNDEFINED") + set(ICONV_IN_LIBC "" CACHE INTERNAL "Test ICONV_IN_LIBC") + set(ICONV_IN_LIBICONV "" CACHE INTERNAL "Test ICONV_IN_LIBICONV") + set(HAVE_GETPAGESIZE "1" CACHE INTERNAL "Have symbol getpagesize") + set(HAVE_SIGACTION "1" CACHE INTERNAL "Have symbol sigaction") + set(HAVE_SA_SIGACTION "" CACHE INTERNAL "Have symbol sa_sigaction") + set(HAVE_SETJMP "1" CACHE INTERNAL "Have symbol setjmp") + set(HAVE_NANOSLEEP "" CACHE INTERNAL "Have symbol nanosleep") + set(HAVE_GMTIME_R "1" CACHE INTERNAL "Have symbol gmtime_r") + set(HAVE_LOCALTIME_R "1" CACHE INTERNAL "Have symbol localtime_r") + set(HAVE_NL_LANGINFO "" CACHE INTERNAL "Have symbol nl_langinfo") + set(HAVE_SYSCONF "1" CACHE INTERNAL "Have symbol sysconf") + set(HAVE_SYSCTLBYNAME "" CACHE INTERNAL "Have symbol sysctlbyname") + set(HAVE_GETAUXVAL "" CACHE INTERNAL "Have symbol getauxval") + set(HAVE_ELF_AUX_INFO "" CACHE INTERNAL "Have symbol elf_aux_info") + set(HAVE_POLL "" CACHE INTERNAL "Have symbol poll") + set(HAVE_MEMFD_CREATE "" CACHE INTERNAL "Have symbol memfd_create") + set(HAVE_POSIX_FALLOCATE "" CACHE INTERNAL "Have symbol posix_fallocate") + set(HAVE_DLOPEN_IN_LIBC "" CACHE INTERNAL "Have symbol dlopen") + set(HAVE_GETHOSTNAME "1" CACHE INTERNAL "Have symbol gethostname") + set(HAVE_SIGTIMEDWAIT "" CACHE INTERNAL "Have symbol sigtimedwait") + set(HAVE_PPOLL "" CACHE INTERNAL "Have symbol ppoll") + set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR "" CACHE INTERNAL "Have symbol addchdir") + set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP "" CACHE INTERNAL "Have symbol addchdir_np") + set(HAVE_FDATASYNC "" CACHE INTERNAL "Have symbol fdatasync") + set(HAVE_GETRESUID "" CACHE INTERNAL "Have symbol getresuid") + set(HAVE_GETRESGID "" CACHE INTERNAL "Have symbol getresgid") + endif() + endfunction() +endif() diff --git a/cmake/macros.cmake b/cmake/macros.cmake index e64f0b4d39..b39bd5d83f 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -425,7 +425,7 @@ function(SDL_PrintSummary) message(STATUS "") endif() - if(UNIX AND NOT (ANDROID OR APPLE OR EMSCRIPTEN OR HAIKU OR RISCOS)) + if(UNIX AND NOT (ANDROID OR APPLE OR EMSCRIPTEN OR HAIKU OR RISCOS OR DJGPP)) if(NOT (HAVE_X11 OR HAVE_WAYLAND)) if(NOT SDL_UNIX_CONSOLE_BUILD) message(FATAL_ERROR diff --git a/cmake/sdlplatform.cmake b/cmake/sdlplatform.cmake index f16fe3f2ef..6c60e0a2b3 100644 --- a/cmake/sdlplatform.cmake +++ b/cmake/sdlplatform.cmake @@ -22,6 +22,8 @@ function(SDL_DetectCMakePlatform) set(sdl_cmake_platform Haiku) elseif(NINTENDO_3DS) set(sdl_cmake_platform n3ds) + elseif(CMAKE_SYSTEM_NAME STREQUAL "DOS") + set(sdl_cmake_platform dos) elseif(NGAGESDK) set(sdl_cmake_platform ngage) elseif(PS2) diff --git a/docs/README-dos.md b/docs/README-dos.md new file mode 100644 index 0000000000..4fd4c10271 --- /dev/null +++ b/docs/README-dos.md @@ -0,0 +1,90 @@ +# DOS + +SDL port for MS-DOS using the [DJGPP](https://www.delorie.com/djgpp/) GCC cross-compiler. + +## Building + +To build for DOS, make sure you have a DJGPP cross-compiler in your PATH and run: + +```bash +cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=build-scripts/i586-pc-msdosdjgpp.cmake -DCMAKE_BUILD_TYPE=Release +cmake --build build +``` + +The toolchain file looks for `i586-pc-msdosdjgpp-gcc` or `i386-pc-msdosdjgpp-gcc` in PATH. + +## Running + +DOS executables require a DPMI host. Place `CWSDPMI.EXE` next to your executable. + +To run in DOSBox: + +```bash +dosbox myapp.exe +``` + +## System Requirements + +| Component | Minimum | +| --------- | ------------------------------ | +| CPU | i386 or higher | +| RAM | 4 MB | +| Video | VGA (256-color mode 13h) | +| Audio | Sound Blaster | +| DPMI | CWSDPMI.exe or compatible host | + +Higher resolutions (640×480 and above) require a VESA VBE 1.2+ compatible video card. + +## Notes + +### Memory Model + +The DOS port produces 32-bit protected-mode DPMI executables. It uses the "fat DS" nearptr trick (`__djgpp_nearptr_enable()`) to convert physical addresses to usable C pointers. This allows direct access to the VESA linear framebuffer and DMA buffers from C code without segment descriptor manipulation. + +SDL on DOS requires the fat DS trick. `SDL_RunApp()` enables it automatically via `SDL_main.h`. If you define `SDL_MAIN_HANDLED`, you must call `__djgpp_nearptr_enable()` yourself before initializing SDL, or video initialization will fail with a clear error message. + +### Threading + +DOS has no OS-level threads. SDL on DOS implements cooperative threading via a mini-scheduler that uses `setjmp`/`longjmp` for context switching. Threads are never preempted mid-instruction. Context switches occur only at explicit yield points such as `SDL_Delay` and the event pump, so make sure your main loop calls `SDL_PumpEvents` or `SDL_Delay` regularly. `SDL_Delay(0)` yields to other threads without sleeping and is safe to call in tight loops. In some cases, like a load screen, a longer delay (e.g. `SDL_Delay(16)`) may be needed to give background threads enough CPU time. + +### Video + +The video driver supports VGA mode 13h (320×200×256) on any VGA card, and higher resolutions via VESA BIOS Extensions (VBE 1.2+). Both linear framebuffer (VBE 2.0+) and banked framebuffer modes are supported. Hardware page-flipping is used for tear-free rendering when available. + +Only software rendering is supported. There is no GPU renderer. + +All video modes are effectively fullscreen. When creating a window, the driver selects the closest available video mode to the requested size. + +8-bit indexed color (INDEX8) modes with programmable VGA DAC palettes are supported but will only be used when explicitly requested via the `SDL_PIXELFORMAT` window creation property. + +EGA and CGA cards are not supported. The driver detects VGA hardware at initialization and will fail with a clear error message if VGA is not present. + +#### Direct Framebuffer Hint + +Setting `SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER` to `"1"` before calling `SDL_GetWindowSurface()` enables a fast path that skips the normal surface copy. `SDL_UpdateWindowSurface()` copies the system-RAM surface directly to VRAM via `dosmemput` and only programs the VGA DAC palette when it changes. Page flipping is done without waiting for vblank. No software cursor compositing is performed. + +This mode is designed for applications like Quake that manage their own rendering and want maximum frame throughput. The trade-offs are: + +- No vsync. Tearing is expected. +- No software cursor. The application must draw its own cursor if needed. +- Reading back the surface may be slow on real hardware (uncached VRAM). + +The hint must be set before the first call to `SDL_GetWindowSurface()`. Changing it after that has no effect. + +### Audio + +Sound Blaster support is available for SB16 (16-bit stereo), SB Pro (8-bit stereo), and SB 2.0/1.x (8-bit mono). Configured automatically from the `BLASTER` environment variable. + +A ring buffer sits between the SDL audio pipeline and the DMA hardware. The audio thread fills the ring buffer cooperatively, and the Sound Blaster IRQ handler copies data from the ring buffer to the DMA buffer directly. This gives roughly 45 ms of cushion before audio would stutter. If your game runs at 22 fps or above, audio will be glitch-free with no extra effort. Below 20 fps, adding a `SDL_Delay(0)` in the middle of your game loop should be enough to keep the ring buffer fed. + +Audio recording is not implemented. + +### Input + +- Keyboard: IRQ1-driven with full extended scancode (0xE0 prefix) support. +- Mouse: INT 33h mouse driver with relative motion via mickeys. +- Joystick: gameport joystick via BIOS INT 15h (axes) and direct port 0x201 reads (buttons) with software calibration. + +### Limitations + +- No shared library / dynamic loading support (no `SDL_LoadObject`). DXE support may be added in the future. diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 369dc7e921..377226f057 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -724,6 +724,23 @@ extern "C" { */ #define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" +/** + * A variable that enables a fast framebuffer path on DOS. + * + * When set to "1", SDL_UpdateWindowSurface() copies the system-RAM surface + * directly to VRAM and skips software cursor compositing and vsync. + * + * The variable can be set to the following values: + * + * - "0": Use the normal path with cursor compositing and vsync. (default) + * - "1": Use the fast direct-to-VRAM path when available. + * + * This hint must be set before the first call to SDL_GetWindowSurface(). + * + * \since This hint is available since SDL 3.6.0. + */ +#define SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER "SDL_DOS_ALLOW_DIRECT_FRAMEBUFFER" + /** * Set the level of checking for invalid parameters passed to SDL functions. * diff --git a/include/SDL3/SDL_main.h b/include/SDL3/SDL_main.h index 805c8899ab..64daa42c39 100644 --- a/include/SDL3/SDL_main.h +++ b/include/SDL3/SDL_main.h @@ -219,6 +219,19 @@ void reset_IOP(); \ void reset_IOP() {} + #elif defined(SDL_PLATFORM_DOS) + /* + On DOS, SDL provides a main function that sets up memory + page locking (code, data, stack are locked, future + malloc calls are not locked), and sets up the "fat DS" + trick, so we can use C pointers from protected mode that + access conventional memory. SDL _requires_ the "fat DS" + trick! + + If you provide this yourself, you may define SDL_MAIN_HANDLED + */ + #define SDL_MAIN_AVAILABLE + #elif defined(SDL_PLATFORM_3DS) /* On N3DS, SDL provides a main function that sets up the screens diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h index 526bc0eaa1..23ff34ce10 100644 --- a/include/SDL3/SDL_platform_defines.h +++ b/include/SDL3/SDL_platform_defines.h @@ -484,6 +484,16 @@ #define SDL_PLATFORM_NGAGE 1 #endif +#ifdef __MSDOS__ + +/** + * A preprocessor macro that is only defined if compiling for MS-DOS. + * + * \since This macro is available since SDL 3.6.0. + */ +#define SDL_PLATFORM_DOS 1 +#endif + #ifdef __GNU__ /** diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 267e941c4f..e7d0b34f42 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -292,7 +292,7 @@ #cmakedefine SDL_AUDIO_DRIVER_N3DS 1 #cmakedefine SDL_AUDIO_DRIVER_NGAGE 1 #cmakedefine SDL_AUDIO_DRIVER_QNX 1 - +#cmakedefine SDL_AUDIO_DRIVER_DOS_SOUNDBLASTER 1 #cmakedefine SDL_AUDIO_DRIVER_PRIVATE 1 /* Enable various input drivers */ @@ -303,6 +303,7 @@ #cmakedefine SDL_HAVE_MACHINE_JOYSTICK_H 1 #cmakedefine SDL_JOYSTICK_ANDROID 1 #cmakedefine SDL_JOYSTICK_DINPUT 1 +#cmakedefine SDL_JOYSTICK_DOS 1 #cmakedefine SDL_JOYSTICK_DUMMY 1 #cmakedefine SDL_JOYSTICK_EMSCRIPTEN 1 #cmakedefine SDL_JOYSTICK_GAMEINPUT 1 @@ -370,6 +371,7 @@ #cmakedefine SDL_THREAD_PSP 1 #cmakedefine SDL_THREAD_PS2 1 #cmakedefine SDL_THREAD_N3DS 1 +#cmakedefine SDL_THREAD_DOS 1 #cmakedefine SDL_THREAD_PRIVATE 1 @@ -392,6 +394,7 @@ #cmakedefine SDL_TIMER_PSP 1 #cmakedefine SDL_TIMER_PS2 1 #cmakedefine SDL_TIMER_N3DS 1 +#cmakedefine SDL_TIMER_DOS 1 #cmakedefine SDL_TIMER_PRIVATE 1 @@ -448,6 +451,7 @@ #cmakedefine SDL_VIDEO_DRIVER_X11_XSYNC 1 #cmakedefine SDL_VIDEO_DRIVER_X11_XTEST 1 #cmakedefine SDL_VIDEO_DRIVER_QNX 1 +#cmakedefine SDL_VIDEO_DRIVER_DOSVESA 1 #cmakedefine SDL_VIDEO_DRIVER_PRIVATE 1 @@ -520,6 +524,7 @@ #cmakedefine SDL_FILESYSTEM_PSP 1 #cmakedefine SDL_FILESYSTEM_PS2 1 #cmakedefine SDL_FILESYSTEM_N3DS 1 +#cmakedefine SDL_FILESYSTEM_DOS 1 #cmakedefine SDL_FILESYSTEM_PRIVATE 1 diff --git a/src/SDL.c b/src/SDL.c index 2d62cf42c6..350ca34b34 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -771,6 +771,8 @@ const char *SDL_GetPlatform(void) return "Linux"; #elif defined(__MINT__) return "Atari MiNT"; +#elif defined(SDL_PLATFORM_MSDOS) + return "MS-DOS"; #elif defined(SDL_PLATFORM_MACOS) return "macOS"; #elif defined(SDL_PLATFORM_NETBSD) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 8b82eff33f..d642016541 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -92,6 +92,9 @@ static const AudioBootStrap *const bootstrap[] = { #ifdef SDL_AUDIO_DRIVER_QNX &QSAAUDIO_bootstrap, #endif +#ifdef SDL_AUDIO_DRIVER_DOS_SOUNDBLASTER + &DOSSOUNDBLASTER_bootstrap, +#endif #ifdef SDL_AUDIO_DRIVER_DISK &DISKAUDIO_bootstrap, #endif diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 9104be82a3..858354a9aa 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -390,5 +390,6 @@ extern AudioBootStrap N3DSAUDIO_bootstrap; extern AudioBootStrap NGAGEAUDIO_bootstrap; extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; extern AudioBootStrap QSAAUDIO_bootstrap; +extern AudioBootStrap DOSSOUNDBLASTER_bootstrap; #endif // SDL_sysaudio_h_ diff --git a/src/audio/dos/SDL_dosaudio_sb.c b/src/audio/dos/SDL_dosaudio_sb.c new file mode 100644 index 0000000000..881750d1d4 --- /dev/null +++ b/src/audio/dos/SDL_dosaudio_sb.c @@ -0,0 +1,631 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_AUDIO_DRIVER_DOS_SOUNDBLASTER + +#include "../../core/dos/SDL_dos.h" +#include "../../core/dos/SDL_dos_scheduler.h" +#include "SDL_dosaudio_sb.h" + +// Set to 1 to force 8-bit mono (pre-SB16) code path even on SB16 hardware. +// Useful for testing in DOSBox which always emulates an SB16 (DSP 4.x). +#define FORCE_SB_8BIT 0 + +static int soundblaster_base_port = -1; +static int soundblaster_irq = -1; +static int soundblaster_dma_channel = -1; +static int soundblaster_highdma_channel = -1; +static int soundblaster_version = -1; +static int soundblaster_version_minor = -1; +static bool soundblaster_is_sb16 = false; // false when FORCE_SB_8BIT or DSP < 4 +static Uint8 soundblaster_silence_value = 0; + +static void ResetSoundBlasterDSP(void) +{ + // reset the DSP. + const int reset_port = soundblaster_base_port + 0x6; + outportb(reset_port, 1); + SDL_DelayPrecise(3000); // wait at least 3 microseconds for hardware to see it. + outportb(reset_port, 0); +} + +static bool ReadSoundBlasterReady(void) +{ + const int ready_port = soundblaster_base_port + 0xE; + return ((inportb(ready_port) & (1 << 7)) != 0); +} + +static void WriteSoundBlasterDSP(const Uint8 val) +{ + const int port = soundblaster_base_port + 0xC; + int timeout = 100000; + while ((inportb(port) & (1 << 7)) && --timeout > 0) { /* spin until ready or timeout */ + } + outportb(port, val); +} + +static Uint8 ReadSoundBlasterDSP(void) +{ + const int query_port = soundblaster_base_port + 0xA; + int timeout = 100000; + while (!ReadSoundBlasterReady() && --timeout > 0) { /* spin until ready or timeout */ + } + return (Uint8)inportb(query_port); +} + +// The ISR copies audio from a pre-allocated ring buffer directly into the +// DMA half-buffer. The SDL audio thread fills the ring buffer cooperatively +// (using the full SDL pipeline with all its allocations and mutexes), and +// the ISR just does a memcpy (no SDL calls, no DPMI, no allocator). + +// Number of DMA half-buffers that fit in the ring. Must be a power of two. +// 4 chunks is ~45 ms at 44100 Hz, enough headroom for 22 fps frame times. +#define RING_BUFFER_CHUNKS 4 + +// All of the following statics are memory-locked, making them safe to access +// from the ISR without risking a page fault or DPMI re-entrance. + +// ISR-cached copies of device state (avoids chasing heap pointers in IRQ context). +static volatile int isr_irq_ack_port = 0; + +// ISR-visible ring buffer state (all memory-locked). +static volatile int isr_ring_read = 0; +static volatile int isr_ring_write = 0; +static int isr_ring_size = 0; // ring_size (power-of-2 bytes) +static int isr_ring_mask = 0; // ring_size - 1 +static int isr_chunk_size = 0; // one DMA half-buffer, in bytes +static Uint8 *isr_ring_buffer = NULL; // the ring itself (allocated and locked) +static Uint8 *isr_dma_buffer = NULL; // pointer to the DMA double-buffer +static int isr_dma_halfdma = 0; // half the DMA buffer size, in bytes +static int isr_dma_channel = 0; +static bool isr_is_16bit = false; +static Uint8 isr_silence_value = 0; + +// Copy `len` bytes from the ring buffer at position `pos` into `dst`, +// handling the power-of-2 wrap. All pointers are memory-locked. +static void RingCopyOut(Uint8 *dst, int pos, int len) +{ + const int mask = isr_ring_mask; + const int start = pos & mask; + const int first = (start + len <= isr_ring_size) ? len : (isr_ring_size - start); + SDL_memcpy(dst, isr_ring_buffer + start, first); + if (first < len) { + SDL_memcpy(dst + first, isr_ring_buffer, len - first); + } +} +static void RingCopyOut_End(void) {} + +// Determine which DMA half-buffer the hardware is NOT currently playing +// (i.e. the one we should fill). Uses ISR-cached statics so we don't +// chase any heap pointers. +static Uint8 *ISR_GetDMAHalf(void) +{ + int count; + if (isr_is_16bit) { + outportb(0xD8, 0x00); + count = (int)inportb(0xC0 + (isr_dma_channel - 4) * 4 + 2); + count += (int)inportb(0xC0 + (isr_dma_channel - 4) * 4 + 2) << 8; + return isr_dma_buffer + (count < (isr_dma_halfdma / 2) ? 0 : isr_dma_halfdma); + } else { + outportb(0x0C, 0x00); + count = (int)inportb(isr_dma_channel * 2 + 1); + count += (int)inportb(isr_dma_channel * 2 + 1) << 8; + return isr_dma_buffer + (count < isr_dma_halfdma ? 0 : isr_dma_halfdma); + } +} +static void ISR_GetDMAHalf_End(void) {} + +// The IRQ handler. Copies one chunk from the ring buffer into the DMA +// half-buffer that the hardware isn't currently playing. If the ring is +// empty it fills with silence (no stutter, just a brief gap). +// +// This function touches ONLY memory-locked data and does ONLY port I/O and +// memcpy. No DPMI, no malloc, no mutex, no FPU. +static void SoundBlasterIRQHandler(void) +{ + // Acknowledge hardware first. + inportb(isr_irq_ack_port); + DOS_EndOfInterrupt(soundblaster_irq); + + Uint8 *dma_dst = ISR_GetDMAHalf(); + + // How many bytes are available in the ring? + const int avail = isr_ring_write - isr_ring_read; // both are monotonic + + if (avail >= isr_chunk_size) { + RingCopyOut(dma_dst, isr_ring_read, isr_chunk_size); + isr_ring_read += isr_chunk_size; + } else { + // Ring underrun: fill with silence so we don't replay stale audio. + SDL_memset(dma_dst, isr_silence_value, isr_chunk_size); + } +} +static void SoundBlasterIRQHandler_End(void) {} + +// Wait until the ring buffer has room for one more chunk. +// The audio thread keeps yielding so the game's main thread can run while +// we wait. Because the ISR is steadily draining the ring, this only blocks +// when the ring is completely full, which is a good problem to have. +static bool DOSSOUNDBLASTER_WaitDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + const int size = hidden->ring_size; + + for (;;) { + // Available space = ring_size - (write - read). + // ring_write is ours (audio thread only), ring_read is advanced by + // the ISR. Read the ISR's copy so we see the latest drain position. + const int used = hidden->ring_write - isr_ring_read; + if ((size - used) >= hidden->chunk_size) { + return true; // room for at least one chunk + } + DOS_Yield(); + } +} + +static bool DOSSOUNDBLASTER_OpenDevice(SDL_AudioDevice *device) +{ + const bool is_sb16 = soundblaster_is_sb16; + + if (is_sb16) { + // SB16 (DSP >= 4): 16-bit stereo signed + device->spec.format = SDL_AUDIO_S16LE; + device->spec.channels = 2; + } else if (soundblaster_version >= 3) { + // SB Pro (DSP 3.x): 8-bit stereo unsigned. + // Max 22050 Hz in stereo (hardware interleaves L/R at double the rate). + device->spec.format = SDL_AUDIO_U8; + device->spec.channels = 2; + } else { + // SB 2.0 (DSP 2.x) and SB 1.x: 8-bit mono unsigned. + device->spec.format = SDL_AUDIO_U8; + device->spec.channels = 1; + } + + // Accept whatever frequency SDL3's audio layer passes in. For SB16 (DSP >= 4) + // the hardware supports 5000–44100 Hz via DSP command 0x41. For pre-SB16, + // clamp to hardware limits: + // SB 1.x: max ~23 kHz mono + // SB 2.0 (DSP 2.x): max 44100 Hz mono (high-speed), ~23 kHz normal + // SB Pro (DSP 3.x): max 22050 Hz stereo, max 44100 Hz mono + if (!is_sb16 && device->spec.freq > 22050) { + device->spec.freq = 22050; // clamp to safe max for pre-SB16 + } + device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq); + + // Calculate the final parameters for this audio specification + SDL_UpdatedAudioDeviceFormat(device); + + SDL_Log("SOUNDBLASTER: Opening at %d Hz, %d channels, format 0x%X, %d sample frames (DSP %d.%d, %s)", + device->spec.freq, device->spec.channels, device->spec.format, device->sample_frames, + soundblaster_version, soundblaster_version_minor, is_sb16 ? "SB16" : "pre-SB16"); + + if (device->buffer_size > (32 * 1024)) { + return SDL_SetError("Buffer size is too large (choose smaller audio format and/or fewer sample frames)"); // DMA buffer has to fit in 64K segment, so buffer_size has to be half that, as we double it. + } + + // Initialize all variables that we clean on shutdown + struct SDL_PrivateAudioData *hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (!hidden) { + return false; + } + + device->hidden = hidden; + hidden->is_16bit = is_sb16; + + ResetSoundBlasterDSP(); + + // allocate conventional memory for the DMA buffer. + hidden->dma_channel = is_sb16 ? soundblaster_highdma_channel : soundblaster_dma_channel; + if (hidden->dma_channel < 0) { + SDL_free(hidden); + return SDL_SetError("No %s DMA channel configured in BLASTER environment variable", + is_sb16 ? "high (16-bit)" : "low (8-bit)"); + } + hidden->dma_buflen = device->buffer_size * 2; + hidden->dma_buffer = (Uint8 *)DOS_AllocateDMAMemory(hidden->dma_buflen, &hidden->dma_seginfo); + if (!hidden->dma_buffer) { + return SDL_SetError("Couldn't allocate Sound Blaster DMA buffer!"); + } + + SDL_Log("SOUNDBLASTER: Allocated %d bytes of conventional memory at segment %d (ptr=%p)", (int)hidden->dma_buflen, (int)hidden->dma_seginfo.rm_segment, hidden->dma_buffer); + + // silence the DMA buffer to start + SDL_memset(hidden->dma_buffer, soundblaster_silence_value, hidden->dma_buflen); + + // set up DMA controller. + const Uint32 physical = DOS_LinearToPhysical(hidden->dma_buffer); + const Uint8 physical_page = (physical >> 16) & 0xFF; + + if (is_sb16) { + // High DMA (16-bit, channels 5-7): ports in 0xC0-0xDF range, counts in words. + const int dma_words = (hidden->dma_buflen / 2) - 1; + outportb(0xD4, 0x04 | hidden->dma_channel); // mask the DMA channel + outportb(0xD6, 0x58 | (hidden->dma_channel - 4)); // mode: single, read, auto-init + static const int high_page_ports[] = { 0, 0, 0, 0, 0, 0x8B, 0x89, 0x8A }; // DMA page register ports for channels 5-7 + outportb(high_page_ports[hidden->dma_channel], physical_page); // page to transfer + outportb(0xD8, 0x00); // clear the flip-flop + outportb(0xC0 + (hidden->dma_channel - 4) * 4, (Uint8)((physical >> 1) & 0xFF)); // offset low (word address) + outportb(0xC0 + (hidden->dma_channel - 4) * 4, (Uint8)((physical >> 9) & 0xFF)); // offset high + outportb(0xD8, 0x00); // clear the flip-flop + outportb(0xC0 + (hidden->dma_channel - 4) * 4 + 2, (Uint8)(dma_words & 0xFF)); // count low + outportb(0xC0 + (hidden->dma_channel - 4) * 4 + 2, (Uint8)((dma_words >> 8) & 0xFF)); // count high + outportb(0xD4, hidden->dma_channel & ~4); // unmask the DMA channel + } else { + // Low DMA (8-bit, channels 0-3): ports in 0x00-0x0F range, counts in bytes. + static const int page_ports[] = { 0x87, 0x83, 0x81, 0x82 }; // DMA page register ports for channels 0-3 (yes, they're out of order — that's how the IBM PC DMA controller works) + const int dma_bytes = hidden->dma_buflen - 1; + outportb(0x0A, 0x04 | hidden->dma_channel); // mask the DMA channel + outportb(0x0B, 0x58 | hidden->dma_channel); // mode: single, read, auto-init + outportb(page_ports[hidden->dma_channel], physical_page); // page to transfer + outportb(0x0C, 0x00); // clear the flip-flop + outportb(hidden->dma_channel * 2, (Uint8)(physical & 0xFF)); // offset low (byte address) + outportb(hidden->dma_channel * 2, (Uint8)((physical >> 8) & 0xFF)); // offset high + outportb(0x0C, 0x00); // clear the flip-flop + outportb(hidden->dma_channel * 2 + 1, (Uint8)(dma_bytes & 0xFF)); // count low + outportb(hidden->dma_channel * 2 + 1, (Uint8)((dma_bytes >> 8) & 0xFF)); // count high + outportb(0x0A, hidden->dma_channel); // unmask the DMA channel (just the channel number, no bit 2) + } + + // Cache the IRQ ack port so the ISR doesn't chase pointers. + isr_irq_ack_port = is_sb16 ? (soundblaster_base_port + 0x0F) : (soundblaster_base_port + 0x0E); + + // Set up the IRQ-driven ring buffer. + hidden->chunk_size = device->buffer_size; // one DMA half-buffer + + // Ring size must be a power of two and hold RING_BUFFER_CHUNKS chunks. + hidden->ring_size = hidden->chunk_size * RING_BUFFER_CHUNKS; + // Ensure power-of-two (chunk_size itself comes from SDL and may not be). + { + int rs = hidden->ring_size; + rs--; + rs |= rs >> 1; + rs |= rs >> 2; + rs |= rs >> 4; + rs |= rs >> 8; + rs |= rs >> 16; + rs++; + hidden->ring_size = rs; + } + + hidden->ring_buffer = (Uint8 *)SDL_calloc(1, hidden->ring_size); + if (!hidden->ring_buffer) { + return SDL_SetError("Couldn't allocate ring buffer for IRQ-driven audio"); + } + hidden->staging_buffer = (Uint8 *)SDL_calloc(1, hidden->chunk_size); + if (!hidden->staging_buffer) { + return SDL_SetError("Couldn't allocate staging buffer for IRQ-driven audio"); + } + + hidden->ring_read = 0; + hidden->ring_write = 0; + + // Populate ISR-visible statics (all will be memory-locked below). + isr_ring_buffer = hidden->ring_buffer; + isr_ring_read = 0; + isr_ring_write = 0; + isr_ring_size = hidden->ring_size; + isr_ring_mask = hidden->ring_size - 1; + isr_chunk_size = hidden->chunk_size; + isr_dma_buffer = hidden->dma_buffer; + isr_dma_halfdma = hidden->dma_buflen / 2; + isr_dma_channel = hidden->dma_channel; + isr_is_16bit = is_sb16; + isr_silence_value = soundblaster_silence_value; + + // Lock all ISR code and data to prevent page faults during interrupts. + DOS_LockCode(SoundBlasterIRQHandler, SoundBlasterIRQHandler_End); + DOS_LockCode(RingCopyOut, RingCopyOut_End); + DOS_LockCode(ISR_GetDMAHalf, ISR_GetDMAHalf_End); + DOS_LockData(*hidden->ring_buffer, hidden->ring_size); + DOS_LockVariable(isr_ring_read); + DOS_LockVariable(isr_ring_write); + DOS_LockVariable(isr_ring_size); + DOS_LockVariable(isr_ring_mask); + DOS_LockVariable(isr_chunk_size); + DOS_LockVariable(isr_ring_buffer); + DOS_LockVariable(isr_dma_buffer); + DOS_LockVariable(isr_dma_halfdma); + DOS_LockVariable(isr_dma_channel); + DOS_LockVariable(isr_is_16bit); + DOS_LockVariable(isr_silence_value); + DOS_LockVariable(isr_irq_ack_port); + DOS_LockVariable(soundblaster_irq); + + DOS_HookInterrupt(soundblaster_irq, SoundBlasterIRQHandler, &hidden->interrupt_hook); + + WriteSoundBlasterDSP(0xD1); // turn on the speaker + // The speaker-on command takes up to 112 ms to complete on real hardware. + // Poll the DSP write status port (bit 7 clears when the DSP is ready); + // in practice — and always in DOSBox — it completes almost instantly. + { + const int status_port = soundblaster_base_port + 0xC; + const Uint64 deadline = SDL_GetTicksNS() + SDL_MS_TO_NS(112); + while ((inportb(status_port) & 0x80) && (SDL_GetTicksNS() < deadline)) { + SDL_DelayPrecise(SDL_US_TO_NS(100)); // brief yield between polls + } + } + + if (is_sb16) { + // SB16 (DSP >= 4): set output sample rate directly + WriteSoundBlasterDSP(0x41); // set output sampling rate + WriteSoundBlasterDSP((Uint8)(device->spec.freq >> 8)); + WriteSoundBlasterDSP((Uint8)(device->spec.freq & 0xFF)); + + // start 16-bit auto-initialize DMA mode + // half the total buffer per transfer, then convert to samples (divide by 2 because they are 16-bits each). + const int block_size = ((hidden->dma_buflen / 2) / sizeof(Sint16)) - 1; // one less than samples to be transferred. + WriteSoundBlasterDSP(0xB6); // 16-bit output, auto-init, FIFO on + WriteSoundBlasterDSP(0x30); // 16-bit stereo signed PCM + WriteSoundBlasterDSP((Uint8)(block_size & 0xFF)); + WriteSoundBlasterDSP((Uint8)(block_size >> 8)); + } else { + // Pre-SB16 (DSP < 4): set sample rate via Time Constant + // Time Constant = 256 - (1000000 / (channels * freq)) + // In stereo mode the SB Pro interleaves L/R samples, so the effective + // hardware rate is channels * freq. + const int effective_rate = device->spec.channels * device->spec.freq; + const Uint8 time_constant = (Uint8)(256 - (1000000 / effective_rate)); + WriteSoundBlasterDSP(0x40); // set time constant + WriteSoundBlasterDSP(time_constant); + + // SB Pro (DSP 3.x): enable or disable stereo via mixer register 0x0E + if (soundblaster_version >= 3) { + const int mixer_addr = soundblaster_base_port + 0x04; + const int mixer_data = soundblaster_base_port + 0x05; + outportb(mixer_addr, 0x0E); // select output/stereo register + if (device->spec.channels == 2) { + outportb(mixer_data, inportb(mixer_data) | 0x02); // set bit 1 = stereo + } else { + outportb(mixer_data, inportb(mixer_data) & ~0x02); // clear bit 1 = mono + } + } + + // start 8-bit auto-initialize DMA mode + // block_size is in bytes for 8-bit, and it's the half-buffer size minus 1 + const int block_size = (hidden->dma_buflen / 2) - 1; + WriteSoundBlasterDSP(0x48); // set DSP block transfer size + WriteSoundBlasterDSP((Uint8)(block_size & 0xFF)); + WriteSoundBlasterDSP((Uint8)(block_size >> 8)); + // NOTE: DSP 1.x does not support auto-init (0x1C). Those cards are extremely + // rare and would need single-cycle transfers re-triggered from the ISR. + // For now we use 0x1C anyway and hope for the best on DSP 1.x hardware. + WriteSoundBlasterDSP(0x1C); // 8-bit auto-init DMA playback + } + + SDL_Log("SoundBlaster opened!"); + return true; +} + +// Return the staging buffer. The SDL audio pipeline writes the mixed audio +// here; PlayDevice then copies it into the ring buffer. +static Uint8 *DOSSOUNDBLASTER_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + (void)buffer_size; // unchanged, always one chunk + return hidden->staging_buffer; +} + +// Commit the staging buffer into the ring buffer. +// Called by SDL's audio thread after it has written a full chunk. +static bool DOSSOUNDBLASTER_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + const int mask = hidden->ring_size - 1; + const int pos = hidden->ring_write & mask; + const int first = (pos + buffer_size <= hidden->ring_size) ? buffer_size : (hidden->ring_size - pos); + + SDL_memcpy(hidden->ring_buffer + pos, buffer, first); + if (first < buffer_size) { + SDL_memcpy(hidden->ring_buffer, buffer + first, buffer_size - first); + } + + // Advance the write cursor. Interrupts are disabled around the store so + // the ISR never sees a torn write (not strictly necessary on x86 for an + // aligned int, but let's be safe). + DOS_DisableInterrupts(); + hidden->ring_write += buffer_size; + isr_ring_write = hidden->ring_write; + DOS_EnableInterrupts(); + + return true; +} + +static void DOSSOUNDBLASTER_CloseDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + if (hidden) { + // Disable PCM. + if (hidden->is_16bit) { + WriteSoundBlasterDSP(0xDA); // exit 16-bit auto-init DMA + WriteSoundBlasterDSP(0xD3); // turn off the speaker + } else { + WriteSoundBlasterDSP(0xD0); // halt 8-bit DMA + WriteSoundBlasterDSP(0xDA); // exit auto-init DMA + WriteSoundBlasterDSP(0xD3); // turn off the speaker + + // SB Pro: reset stereo bit in mixer register 0x0E + if (soundblaster_version >= 3) { + const int mixer_addr = soundblaster_base_port + 0x04; + const int mixer_data = soundblaster_base_port + 0x05; + outportb(mixer_addr, 0x0E); + outportb(mixer_data, inportb(mixer_data) & ~0x02); // clear stereo bit + } + } + + DOS_UnhookInterrupt(&hidden->interrupt_hook, true); + + // disable DMA — mask the appropriate DMA channel. + if (hidden->dma_buffer) { + if (hidden->is_16bit) { + outportb(0xD4, 0x04 | hidden->dma_channel); // mask high DMA channel (channels 5-7) + } else { + outportb(0x0A, 0x04 | hidden->dma_channel); // mask low DMA channel (channels 0-3) + } + DOS_FreeConventionalMemory(&hidden->dma_seginfo); + } + + // Free ring buffer resources. + if (hidden->ring_buffer) { + SDL_free(hidden->ring_buffer); + } + if (hidden->staging_buffer) { + SDL_free(hidden->staging_buffer); + } + + // Clear ISR-visible statics. + isr_ring_buffer = NULL; + isr_ring_read = 0; + isr_ring_write = 0; + isr_ring_size = 0; + isr_ring_mask = 0; + isr_chunk_size = 0; + isr_dma_buffer = NULL; + isr_dma_halfdma = 0; + isr_irq_ack_port = 0; + + SDL_free(hidden); + } +} + +static bool CheckForSoundBlaster(void) +{ + ResetSoundBlasterDSP(); + + // wait for the DSP to say it's ready. + bool ready = false; + for (int i = 0; i < 300; i++) { // may take up to 100msecs to initialize. We'll give it 300. + SDL_DelayPrecise(1000); + if (ReadSoundBlasterReady()) { + ready = true; + break; + } + } + + if (!ready) { + return SDL_SetError("No SoundBlaster detected on port 0x%X", soundblaster_base_port); // either no SoundBlaster or it's on a different base port. + } else if (ReadSoundBlasterDSP() != 0xAA) { + return SDL_SetError("Not a SoundBlaster at port 0x%X", soundblaster_base_port); // either it's not a SoundBlaster or there's a problem. + } + return true; +} + +static bool IsSoundBlasterPresent(void) +{ + const char *env = SDL_getenv("BLASTER"); + if (!env) { + return SDL_SetError("No BLASTER environment variable to find Sound Blaster"); // definitely doesn't have a Sound Blaster (or they screwed up). + } + + char *copy = SDL_strdup(env); + if (!copy) { + return false; // oh well. + } + + char *str = copy; + char *saveptr = NULL; + + char *token; + while ((token = SDL_strtok_r(str, " ", &saveptr)) != NULL) { + str = NULL; // must be NULL for future calls to tokenize the same string. + char *endp = NULL; + const int base = (SDL_toupper(*token) == 'A') ? 16 : 10; + const int num = (int)SDL_strtol(token + 1, &endp, base); + if ((token[1] == 0) || (*endp != 0)) { // bogus num + continue; + } else if (num < 0) { + continue; + } + + switch (SDL_toupper(*token)) { + case 'A': // Base i/o port (in hex) + soundblaster_base_port = num; + break; + + case 'I': // IRQ + soundblaster_irq = num; + break; + + case 'D': // DMA channel + soundblaster_dma_channel = num; + break; + + case 'H': // High DMA channel + soundblaster_highdma_channel = num; + break; + + // don't care about these. + // case 'M': // mixer chip base port + // case 'P': // MPU-401 base port + // case 'T': // type of device + // case 'E': // EMU8000 base port: an AWE32 thing + default: + break; + } + } + SDL_free(copy); + + if (soundblaster_base_port < 0 || soundblaster_irq < 0 || (soundblaster_dma_channel < 0 && soundblaster_highdma_channel < 0)) { + return SDL_SetError("BLASTER environment variable is incomplete or incorrect"); + } else if (!CheckForSoundBlaster()) { + return false; + } + + WriteSoundBlasterDSP(0xE1); // query DSP version + soundblaster_version = (int)ReadSoundBlasterDSP(); + soundblaster_version_minor = (int)ReadSoundBlasterDSP(); + + SDL_Log("SB: BLASTER env='%s'", env); + SDL_Log("SB: port=0x%X", soundblaster_base_port); + SDL_Log("SB: irq=%d", soundblaster_irq); + SDL_Log("SB: dma8=%d", soundblaster_dma_channel); + SDL_Log("SB: dma16=%d", soundblaster_highdma_channel); + SDL_Log("SB: version=%d.%d", soundblaster_version, soundblaster_version_minor); + + soundblaster_is_sb16 = !FORCE_SB_8BIT && (soundblaster_version >= 4); + soundblaster_silence_value = soundblaster_is_sb16 ? 0x00 : 0x80; // S16LE silence is 0x00, U8 silence is 0x80 + + return true; +} + +static bool DOSSOUNDBLASTER_Init(SDL_AudioDriverImpl *impl) +{ + if (!IsSoundBlasterPresent()) { + return false; + } + + impl->OpenDevice = DOSSOUNDBLASTER_OpenDevice; + impl->WaitDevice = DOSSOUNDBLASTER_WaitDevice; + impl->GetDeviceBuf = DOSSOUNDBLASTER_GetDeviceBuf; + impl->PlayDevice = DOSSOUNDBLASTER_PlayDevice; + impl->CloseDevice = DOSSOUNDBLASTER_CloseDevice; + + impl->OnlyHasDefaultPlaybackDevice = true; + + return true; +} + +AudioBootStrap DOSSOUNDBLASTER_bootstrap = { + "soundblaster", "Sound Blaster", DOSSOUNDBLASTER_Init, false, false +}; + +#endif // SDL_AUDIO_DRIVER_DOS_SOUNDBLASTER diff --git a/src/audio/dos/SDL_dosaudio_sb.h b/src/audio/dos/SDL_dosaudio_sb.h new file mode 100644 index 0000000000..5c03188625 --- /dev/null +++ b/src/audio/dos/SDL_dosaudio_sb.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifndef SDL_dosaudio_sb_h_ +#define SDL_dosaudio_sb_h_ + +#include "../../core/dos/SDL_dos.h" +#include "../SDL_sysaudio.h" + +struct SDL_PrivateAudioData +{ + Uint8 *dma_buffer; + size_t dma_buflen; + int dma_channel; + bool is_16bit; + _go32_dpmi_seginfo dma_seginfo; + DOS_InterruptHook interrupt_hook; + + // IRQ-driven ring buffer + Uint8 *ring_buffer; // pre-allocated, memory-locked ring buffer + volatile int ring_read; // read position (advanced by IRQ handler only) + volatile int ring_write; // write position (advanced by audio thread only) + int ring_size; // total ring buffer size (power-of-2, multiple of chunk_size) + int chunk_size; // == device->buffer_size (one DMA half-buffer worth) + Uint8 *staging_buffer; // audio thread writes here, then commits to ring +}; + +#endif // SDL_dosaudio_sb_h_ diff --git a/src/core/dos/SDL_dos.c b/src/core/dos/SDL_dos.c new file mode 100644 index 0000000000..0ba0773195 --- /dev/null +++ b/src/core/dos/SDL_dos.c @@ -0,0 +1,142 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#if defined(SDL_PLATFORM_DOS) + +#include "SDL_dos.h" + +void *DOS_AllocateConventionalMemory(const int len, _go32_dpmi_seginfo *seginfo) +{ + seginfo->size = (len + 15) / 16; // this is in "paragraphs" + if (_go32_dpmi_allocate_dos_memory(seginfo) != 0) { + SDL_OutOfMemory(); + return NULL; + } + // No need to lock: DPMI 0.9 §3.3 guarantees the first megabyte is always + // committed and locked. CWSDPMI (the DJGPP DPMI host) doesn't support + // virtual memory at all, so conventional memory is never paged out. + return DOS_PhysicalToLinear(seginfo->rm_segment * 16); +} + +void *DOS_AllocateDMAMemory(const int len, _go32_dpmi_seginfo *seginfo) +{ + // ISA DMA transfers cannot cross a 64 KB physical page boundary (hardware + // limitation of the 8237 DMA controller). Allocating 2× the requested size + // guarantees at least one contiguous `len`-byte region that doesn't straddle + // a boundary. This is the standard technique used by Allegro, MIDAS, and + // every other DOS audio library; allocate-check-retry would add complexity + // for zero benefit. + uint8_t *ptr = (uint8_t *)DOS_AllocateConventionalMemory(len * 2, seginfo); + if (!ptr) { + return NULL; + } + + // if we're past the end of a page, use the second half of the block. + const uint32_t physical = (seginfo->rm_segment * 16); + if ((physical >> 16) != ((physical + len) >> 16)) { + ptr += len; + } + return ptr; +} + +void DOS_FreeConventionalMemory(_go32_dpmi_seginfo *seginfo) +{ + _go32_dpmi_free_dos_memory(seginfo); +} + +char *DOS_GetFarPtrCString(const Uint32 segoffset) +{ + if (!segoffset) { // let's just treat this as a NULL pointer. + return NULL; + } + + const unsigned long ofs = (unsigned long)(((segoffset & 0xFFFF0000) >> 12) + (segoffset & 0xFFFF)); + size_t len; + + for (len = 0; _farpeekb(_dos_ds, ofs + len) != '\0'; len++) { + } + + len++; // null terminator. + char *retval = SDL_malloc(len); + if (!retval) { + return NULL; + } + + for (size_t i = 0; i < len; i++) { + retval[i] = (char)_farpeekb(_dos_ds, ofs + i); + } + return retval; +} + +void DOS_HookInterrupt(int irq, DOS_InterruptHookFn fn, DOS_InterruptHook *hook) +{ + SDL_assert(irq >= 0 && irq <= 15); + SDL_assert(fn != NULL); + SDL_assert(hook != NULL); + hook->fn = fn; + hook->irq = irq; + hook->interrupt_vector = DOS_IRQToVector(irq); + hook->irq_handler_seginfo.pm_selector = _go32_my_cs(); + hook->irq_handler_seginfo.pm_offset = (uint32_t)fn; + _go32_dpmi_get_protected_mode_interrupt_vector(hook->interrupt_vector, &hook->original_irq_handler_seginfo); + _go32_dpmi_chain_protected_mode_interrupt_vector(hook->interrupt_vector, &hook->irq_handler_seginfo); + + // enable interrupt on the correct PIC + if (irq > 7) { + outportb(PIC2_DATA, inportb(PIC2_DATA) & ~(1 << (irq - 8))); // unmask on slave PIC + outportb(PIC1_DATA, inportb(PIC1_DATA) & ~(1 << 2)); // ensure cascade (IRQ2) is unmasked + } else { + outportb(PIC1_DATA, inportb(PIC1_DATA) & ~(1 << irq)); // unmask on master PIC + } +} + +void DOS_UnhookInterrupt(DOS_InterruptHook *hook, bool disable_interrupt) +{ + if (!hook || !hook->fn) { + return; + } + + SDL_assert(hook->interrupt_vector > 0); + SDL_assert(hook->irq > 0); + + if (disable_interrupt) { + if (hook->irq > 7) { + outportb(PIC2_DATA, inportb(PIC2_DATA) | (1 << (hook->irq - 8))); // mask on slave PIC + } else { + outportb(PIC1_DATA, inportb(PIC1_DATA) | (1 << hook->irq)); // mask on master PIC + } + } + + _go32_dpmi_set_protected_mode_interrupt_vector(hook->interrupt_vector, &hook->original_irq_handler_seginfo); + + // Note: _go32_dpmi_chain_protected_mode_interrupt_vector internally + // allocates a wrapper, but it is NOT safe to free it with + // _go32_dpmi_free_iret_wrapper — that function expects a wrapper + // allocated by _go32_dpmi_allocate_iret_wrapper, and calling it on + // a chain-allocated wrapper causes a page fault on exit. The wrapper + // is a few bytes of conventional memory that the OS reclaims when the + // process terminates, so the leak is harmless. + + SDL_zerop(hook); +} + +#endif // defined(SDL_PLATFORM_DOS) diff --git a/src/core/dos/SDL_dos.h b/src/core/dos/SDL_dos.h new file mode 100644 index 0000000000..11dc58d5ef --- /dev/null +++ b/src/core/dos/SDL_dos.h @@ -0,0 +1,156 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifndef SDL_dos_h_ +#define SDL_dos_h_ + +#include + +// our MS-DOS port depends on the "fat DS" trick. djgpp docs try to warn you +// away from this, but if it was good enough for Quake 1, it's good enough +// for us! +#include + +// We are obviously a 32-bit protected mode (DPMI) program. +#include + +// this is djgpp-specific. +#include + +// this is DOS PC stuff, like interrupts and Intel i/o ports. +#include + +// 8259 PIC (Programmable Interrupt Controller) ports and commands +#define PIC1_COMMAND 0x20 // master PIC command port +#define PIC1_DATA 0x21 // master PIC data (mask) port +#define PIC2_COMMAND 0xA0 // slave PIC command port +#define PIC2_DATA 0xA1 // slave PIC data (mask) port +#define PIC_EOI 0x20 // end-of-interrupt command + +// Lock a range of code so it won't be paged out during interrupts. +// Usage: DOS_LockCode(function_name, function_end_label) +// The function_end_label must be defined immediately after the function. +#define DOS_LockCode(start, end) \ + _go32_dpmi_lock_code((void *)(start), (char *)(end) - (char *)(start)) + +// Lock a range of data so it won't be paged out during interrupts. +#define DOS_LockData(var, size) \ + _go32_dpmi_lock_data((void *)&(var), (size)) + +// Lock a single variable. +#define DOS_LockVariable(var) \ + DOS_LockData(var, sizeof(var)) + +// Set up for C function definitions, even when using C++ +#ifdef __cplusplus +extern "C" { +#endif + +// This uses the "fat DS" trick to convert a physical address to a valid +// C pointer usable from protected mode. +SDL_FORCE_INLINE void *DOS_PhysicalToLinear(const Uint32 physical) +{ + __djgpp_nearptr_enable(); // We need to re-enable this for large applications to work. + return (void *)(physical + __djgpp_conventional_base); +} + +SDL_FORCE_INLINE Uint32 DOS_LinearToPhysical(void *linear) +{ + return ((Uint32)linear) - __djgpp_conventional_base; +} + +SDL_FORCE_INLINE int DOS_IRQToVector(int irq) +{ + return irq + ((irq > 7) ? 104 : 8); +} + +SDL_FORCE_INLINE void DOS_DisableInterrupts(void) +{ + __asm__ __volatile__("cli\n"); +} + +SDL_FORCE_INLINE void DOS_EnableInterrupts(void) +{ + __asm__ __volatile__("sti\n"); +} + +// Grab a single byte from a segment:offset. +SDL_FORCE_INLINE Uint8 DOS_PeekUint8(const Uint32 segoffset) +{ + return (Uint8)_farpeekb(_dos_ds, ((segoffset & 0xFFFF0000) >> 12) + (segoffset & 0xFFFF)); +} + +// Grab a single 16-bit word from a segment:offset. +SDL_FORCE_INLINE Uint16 DOS_PeekUint16(const Uint32 segoffset) +{ + return (Uint16)_farpeekw(_dos_ds, ((segoffset & 0xFFFF0000) >> 12) + (segoffset & 0xFFFF)); +} + +// Grab a single 32-bit dword from a segment:offset. +SDL_FORCE_INLINE Uint32 DOS_PeekUint32(const Uint32 segoffset) +{ + return (Uint32)_farpeekl(_dos_ds, ((segoffset & 0xFFFF0000) >> 12) + (segoffset & 0xFFFF)); +} + +SDL_FORCE_INLINE void DOS_EndOfInterrupt(int irq) +{ + if (irq > 7) { + outportb(PIC2_COMMAND, PIC_EOI); + } + outportb(PIC1_COMMAND, PIC_EOI); +} + +// Allocate memory under the 640k line; various real mode services and DMA transfers need this. +// malloc() returns data above 640k because we're a protected mode, 32-bit process, so this is +// only for specific needs. +extern void *DOS_AllocateConventionalMemory(const int len, _go32_dpmi_seginfo *seginfo); + +// Allocate conventional memory suitable for DMA transfers. +extern void *DOS_AllocateDMAMemory(const int len, _go32_dpmi_seginfo *seginfo); + +// Free conventional (or DMA, which _is_ conventional) memory. +extern void DOS_FreeConventionalMemory(_go32_dpmi_seginfo *seginfo); + +// Get a SDL_malloc'd copy of a null-terminated string located at a real-mode segment:offset. This makes no promises about character encoding. +char *DOS_GetFarPtrCString(const Uint32 segoffset); + +typedef void (*DOS_InterruptHookFn)(void); +typedef struct DOS_InterruptHook +{ + DOS_InterruptHookFn fn; + int irq; + int interrupt_vector; // this is the _vector_ number, not the IRQ number! + _go32_dpmi_seginfo irq_handler_seginfo; + _go32_dpmi_seginfo original_irq_handler_seginfo; + +} DOS_InterruptHook; + +void DOS_HookInterrupt(int irq, DOS_InterruptHookFn fn, DOS_InterruptHook *hook); // `irq` is the IRQ number, not the interrupt vector number! +void DOS_UnhookInterrupt(DOS_InterruptHook *hook, bool disable_interrupt); + +// Ends C function definitions when using C++ +#ifdef __cplusplus +} +#endif + +#endif // SDL_dos_h_ diff --git a/src/core/dos/SDL_dos_scheduler.c b/src/core/dos/SDL_dos_scheduler.c new file mode 100644 index 0000000000..9c0163ce12 --- /dev/null +++ b/src/core/dos/SDL_dos_scheduler.c @@ -0,0 +1,318 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_DOS + +#include "SDL_dos.h" +#include "SDL_dos_scheduler.h" +#include + +/* DJGPP's jmp_buf is defined as: + typedef struct __jmp_buf { + unsigned long __eax, __ebx, __ecx, __edx, __esi; + unsigned long __edi, __ebp, __esp, __eip, __eflags; + unsigned short __cs, __ds, __es, __fs, __gs, __ss; + unsigned long __sigmask, __signum, __exception_ptr; + unsigned char __fpu_state[108]; + } jmp_buf[1]; + We patch __esp, __ebp, and __eip to bootstrap new thread contexts. */ + +// Thread table — static array, no dynamic allocation needed +static DOS_ThreadContext threads[DOS_MAX_THREADS]; +static int current_thread = 0; // Index of currently running thread +static bool scheduler_initialized = false; + +// Find the next runnable thread using round-robin scheduling. +// Returns thread ID, or -1 if no other thread is runnable. +static int FindNextRunnable(int start) +{ + for (int i = 1; i <= DOS_MAX_THREADS; i++) { + int idx = (start + i) % DOS_MAX_THREADS; + if (threads[idx].state == DOS_THREAD_READY) { + return idx; + } + } + return -1; // No other thread is runnable +} + +// Trampoline function that runs on a new thread's stack. +// This is jumped to from DOS_Yield when the new thread runs for the first time. +// We use a global to pass the thread ID since we just switched stacks. +static volatile int trampoline_thread_id; + +static void ThreadTrampoline(void) +{ + int tid = trampoline_thread_id; + DOS_ThreadContext *ctx = &threads[tid]; + + // Run the user's thread function + int result = ctx->entry_fn(ctx->entry_arg); + + // Thread is done + DOS_ExitThread(result); + + // Should never reach here + for (;;) { + } +} + +void DOS_SchedulerInit(void) +{ + if (scheduler_initialized) { + return; + } + + SDL_memset(threads, 0, sizeof(threads)); + + // Thread 0 is the main thread (already running) + threads[0].state = DOS_THREAD_RUNNING; + threads[0].id = 0; + threads[0].join_waiter = -1; + current_thread = 0; + + scheduler_initialized = true; + + _go32_dpmi_lock_data((void *)threads, sizeof(threads)); + _go32_dpmi_lock_data((void *)¤t_thread, sizeof(current_thread)); + _go32_dpmi_lock_data((void *)&scheduler_initialized, sizeof(scheduler_initialized)); + _go32_dpmi_lock_data((void *)&trampoline_thread_id, sizeof(trampoline_thread_id)); +} + +void DOS_SchedulerQuit(void) +{ + // Clean up any remaining threads + for (int i = 1; i < DOS_MAX_THREADS; i++) { + if (threads[i].state != DOS_THREAD_FREE) { + SDL_assert(threads[i].state == DOS_THREAD_FINISHED); + DOS_DestroyThread(i); + } + } + + scheduler_initialized = false; +} + +int DOS_CreateThread(int (*fn)(void *), void *arg, size_t stack_size) +{ + if (!scheduler_initialized) { + return -1; + } + + // Find a free slot + int tid = -1; + for (int i = 1; i < DOS_MAX_THREADS; i++) { + if (threads[i].state == DOS_THREAD_FREE) { + tid = i; + break; + } + } + + if (tid < 0) { + return -1; // No free slots + } + + if (stack_size == 0) { + stack_size = DOS_DEFAULT_STACK_SIZE; + } + + // Allocate stack + void *stack = SDL_malloc(stack_size); + if (!stack) { + return -1; + } + + // Lock the stack memory so it won't be paged out. + // This is important for context switches — we can't take a page fault + // while switching stacks. + _go32_dpmi_lock_data(stack, stack_size); + + DOS_ThreadContext *ctx = &threads[tid]; + SDL_memset(ctx, 0, sizeof(*ctx)); + ctx->id = tid; + ctx->state = DOS_THREAD_READY; + ctx->stack_base = stack; + ctx->stack_size = stack_size; + ctx->entry_fn = fn; + ctx->entry_arg = arg; + ctx->finished = false; + ctx->join_waiter = -1; + + // Set up the initial context. We use setjmp to save a template context, + // then modify the stack pointer to point to our new stack. + // + // The trick: we setjmp here to capture register state, then manually + // patch the saved __esp and __eip in the jmp_buf struct to point to + // our new stack and trampoline function. + if (setjmp(ctx->env) == 0) { + // Patch the saved context to use our new stack and trampoline. + // Stack grows downward, so SP starts at the top. + // Align to 16 bytes for ABI compliance. + Uint8 *stack_top = (Uint8 *)stack + stack_size; + stack_top = (Uint8 *)((uintptr_t)stack_top & ~0xFUL); // 16-byte align + + // Leave room for a fake return address (the trampoline never returns, + // but the ABI expects one on the stack at function entry) + stack_top -= sizeof(void *); + *(void **)stack_top = NULL; // Fake return address + + ctx->env[0].__esp = (unsigned long)(uintptr_t)stack_top; + ctx->env[0].__ebp = (unsigned long)(uintptr_t)stack_top; + ctx->env[0].__eip = (unsigned long)(uintptr_t)ThreadTrampoline; + } else { + SDL_assert(!"Unreachable"); + } + + return tid; +} + +void DOS_Yield(void) +{ + if (!scheduler_initialized) { + return; + } + + int next = FindNextRunnable(current_thread); + if (next < 0) { + return; // No other runnable thread, continue current + } + + int prev = current_thread; + + // Save current context and switch + if (setjmp(threads[prev].env) == 0) { + // Mark previous thread as READY (unless it's BLOCKED or FINISHED) + if (threads[prev].state == DOS_THREAD_RUNNING) { + threads[prev].state = DOS_THREAD_READY; + } + + // Switch to next thread + current_thread = next; + threads[next].state = DOS_THREAD_RUNNING; + + // For new threads that haven't run yet, set the trampoline ID + trampoline_thread_id = next; + + longjmp(threads[next].env, 1); + } + // else: we've been switched back to — just return +} + +void DOS_ExitThread(int status) +{ + DOS_ThreadContext *ctx = &threads[current_thread]; + ctx->exit_status = status; + ctx->finished = true; + ctx->state = DOS_THREAD_FINISHED; + + // Wake up anyone waiting to join this thread + if (ctx->join_waiter >= 0 && ctx->join_waiter < DOS_MAX_THREADS) { + DOS_WakeThread(ctx->join_waiter); + } + + // Find another thread to run. We can't return — our stack frame + // belongs to the thread that just exited. + int next = FindNextRunnable(current_thread); + if (next >= 0) { + current_thread = next; + threads[next].state = DOS_THREAD_RUNNING; + trampoline_thread_id = next; + longjmp(threads[next].env, 1); + } + + // If no other thread is runnable and we're not the main thread, + // this is a problem. Spin-wait for someone to become runnable. + // (This shouldn't happen in practice — the main thread should + // always be runnable or waiting.) + for (;;) { + __asm__ __volatile__("hlt"); // Wait for interrupt before retrying + next = FindNextRunnable(current_thread); + if (next >= 0) { + current_thread = next; + threads[next].state = DOS_THREAD_RUNNING; + trampoline_thread_id = next; + longjmp(threads[next].env, 1); + } + } +} + +int DOS_JoinThread(int thread_id) +{ + if (thread_id < 0 || thread_id >= DOS_MAX_THREADS) { + return -1; + } + + DOS_ThreadContext *target = &threads[thread_id]; + + // If already finished, just return the status + if (target->finished) { + return target->exit_status; + } + + // Register ourselves as the join waiter + target->join_waiter = current_thread; + + // Block until the target thread finishes + while (!target->finished) { + DOS_BlockCurrentThread(); + } + + return target->exit_status; +} + +int DOS_GetCurrentThreadID(void) +{ + if (!scheduler_initialized) { + return 1; + } + return current_thread + 1; +} + +void DOS_WakeThread(int thread_id) +{ + if (thread_id >= 0 && thread_id < DOS_MAX_THREADS) { + if (threads[thread_id].state == DOS_THREAD_BLOCKED) { + threads[thread_id].state = DOS_THREAD_READY; + } + } +} + +void DOS_BlockCurrentThread(void) +{ + threads[current_thread].state = DOS_THREAD_BLOCKED; + DOS_Yield(); +} + +void DOS_DestroyThread(int thread_id) +{ + if (thread_id <= 0 || thread_id >= DOS_MAX_THREADS) { + return; // Can't destroy main thread (0) or invalid IDs + } + + DOS_ThreadContext *ctx = &threads[thread_id]; + if (ctx->stack_base) { + SDL_free(ctx->stack_base); + ctx->stack_base = NULL; + } + ctx->state = DOS_THREAD_FREE; +} + +#endif // SDL_PLATFORM_DOS diff --git a/src/core/dos/SDL_dos_scheduler.h b/src/core/dos/SDL_dos_scheduler.h new file mode 100644 index 0000000000..7732306aa7 --- /dev/null +++ b/src/core/dos/SDL_dos_scheduler.h @@ -0,0 +1,107 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dos_scheduler_h_ +#define SDL_dos_scheduler_h_ + +#include "SDL_internal.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Maximum number of cooperative threads. DOS doesn't need many — +// typically just main thread + audio thread + maybe a loading thread. +#define DOS_MAX_THREADS 16 + +// Default stack size for new threads (64 KB) +#define DOS_DEFAULT_STACK_SIZE (64 * 1024) + +// Thread states +typedef enum +{ + DOS_THREAD_FREE = 0, // Slot is available + DOS_THREAD_READY, // Runnable + DOS_THREAD_RUNNING, // Currently executing + DOS_THREAD_BLOCKED, // Waiting on a semaphore/mutex + DOS_THREAD_FINISHED // Thread function returned +} DOS_ThreadState; + +// Per-thread context +typedef struct DOS_ThreadContext +{ + jmp_buf env; // Saved CPU state for context switch + DOS_ThreadState state; + int id; // Thread ID (index into thread table) + void *stack_base; // malloc'd stack memory + size_t stack_size; + int exit_status; // Return value from thread function + + // Entry point + int (*entry_fn)(void *); + void *entry_arg; + + // Join support + volatile bool finished; // Set when thread function returns + int join_waiter; // ID of thread waiting in WaitThread, or -1 +} DOS_ThreadContext; + +// Initialize the scheduler. Must be called before any thread operations. +// Registers the calling context as thread 0 (the main thread). +void DOS_SchedulerInit(void); + +// Shut down the scheduler. +void DOS_SchedulerQuit(void); + +// Create a new thread. Returns thread ID (>0) on success, -1 on failure. +// The thread starts in READY state and will run when yielded to. +int DOS_CreateThread(int (*fn)(void *), void *arg, size_t stack_size); + +// Yield the current thread's timeslice. Switches to the next runnable thread +// using round-robin scheduling. If no other thread is runnable, returns +// immediately (no-op). This is the core cooperative scheduling primitive. +void DOS_Yield(void); + +// Mark a thread as finished and yield. Called when a thread's entry +// function returns. +void DOS_ExitThread(int status); + +// Block until the specified thread finishes. Returns the thread's exit status. +int DOS_JoinThread(int thread_id); + +// Get the current thread's ID. +int DOS_GetCurrentThreadID(void); + +// Mark a thread as READY (used by semaphore signal to wake a blocked thread). +void DOS_WakeThread(int thread_id); + +// Mark the current thread as BLOCKED and yield (used by semaphore wait). +void DOS_BlockCurrentThread(void); + +// Destroy a thread's resources (stack, etc). Thread must be FINISHED or FREE. +void DOS_DestroyThread(int thread_id); + +#ifdef __cplusplus +} +#endif + +#endif // SDL_dos_scheduler_h_ \ No newline at end of file diff --git a/src/dynapi/SDL_dynapi.h b/src/dynapi/SDL_dynapi.h index 786d86ee47..2713e3f464 100644 --- a/src/dynapi/SDL_dynapi.h +++ b/src/dynapi/SDL_dynapi.h @@ -65,6 +65,8 @@ #define SDL_DYNAMIC_API 0 // devkitARM doesn't support dynamic linking #elif defined(SDL_PLATFORM_NGAGE) #define SDL_DYNAMIC_API 0 +#elif defined(SDL_PLATFORM_DOS) +#define SDL_DYNAMIC_API 0 // DJGPP doesn't support dynamic linking #elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN) #define SDL_DYNAMIC_API 0 // we need dlopen(), but don't have it.... #endif diff --git a/src/filesystem/dos/SDL_sysfilesystem.c b/src/filesystem/dos/SDL_sysfilesystem.c new file mode 100644 index 0000000000..77a4ef4d24 --- /dev/null +++ b/src/filesystem/dos/SDL_sysfilesystem.c @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_FILESYSTEM_DOS + +#include +#include + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +// System dependent filesystem routines + +#include "../SDL_sysfilesystem.h" + +char *SDL_SYS_GetBasePath(void) +{ + extern const char *SDL_argv0; // from src/main/dos/SDL_sysmain_runapp.c + char *searched = searchpath(SDL_argv0); + if (!searched) { + SDL_SetError("argv[0] not found by searchpath"); + return NULL; + } + + char *fullpath = SDL_strdup(searched); + if (!fullpath) { + return NULL; + } + + // I don't know if this is a good idea. Drop DOS path separators, use Unix style instead. + char *ptr; + for (ptr = fullpath; *ptr; ptr++) { + if (*ptr == '\\') { + *ptr = '/'; + } + } + + // drop the .exe name. + ptr = SDL_strrchr(fullpath, '/'); + if (ptr) { + ptr[1] = '\0'; + } + + return fullpath; +} + +char *SDL_SYS_GetPrefPath(const char *org, const char *app) +{ + char *result = NULL; + size_t len; + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + + const char *base = SDL_GetBasePath(); + if (!base) { + return NULL; + } + + if (!org) { + org = ""; + } + + len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + result = (char *)SDL_malloc(len); + if (result) { + if (*org) { + SDL_snprintf(result, len, "%s%s", base, org); + mkdir(result, 0755); + SDL_snprintf(result, len, "%s%s/%s/", base, org, app); + } else { + SDL_snprintf(result, len, "%s%s/", base, app); + } + + mkdir(result, 0755); + } + + return result; +} + +char *SDL_SYS_GetUserFolder(SDL_Folder folder) +{ + SDL_Unsupported(); + return NULL; +} + +#endif // SDL_FILESYSTEM_DOS diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 61af6d6e81..da778975ea 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -106,6 +106,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = { #ifdef SDL_JOYSTICK_N3DS &SDL_N3DS_JoystickDriver, #endif +#ifdef SDL_JOYSTICK_DOS + &SDL_DOS_JoystickDriver, +#endif #if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED) &SDL_DUMMY_JoystickDriver #endif diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 47ce42cdfa..15659b8cc0 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -263,6 +263,7 @@ extern SDL_JoystickDriver SDL_PSP_JoystickDriver; extern SDL_JoystickDriver SDL_VITA_JoystickDriver; extern SDL_JoystickDriver SDL_N3DS_JoystickDriver; extern SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver; +extern SDL_JoystickDriver SDL_DOS_JoystickDriver; // Ends C function definitions when using C++ #ifdef __cplusplus diff --git a/src/joystick/dos/SDL_sysjoystick.c b/src/joystick/dos/SDL_sysjoystick.c new file mode 100644 index 0000000000..4fde0f0f4a --- /dev/null +++ b/src/joystick/dos/SDL_sysjoystick.c @@ -0,0 +1,342 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_JOYSTICK_DOS + +#include /* for __dpmi_regs, __dpmi_int */ +#include +#include /* for inportb */ + +#include "../SDL_joystick_c.h" +#include "../SDL_sysjoystick.h" + +#define GAMEPORT 0x201 + +/* Gameport status byte button bits (active low) */ +#define GAMEPORT_BUTTON1 0x10 /* bit 4 */ +#define GAMEPORT_BUTTON2 0x20 /* bit 5 */ +#define GAMEPORT_BUTTON3 0x40 /* bit 6 */ +#define GAMEPORT_BUTTON4 0x80 /* bit 7 */ + +/* Static state for detection */ +static bool dos_joystick_detected = false; +static SDL_JoystickID dos_joystick_id = 0; +static SDL_JoystickID dos_next_instance_id = 1; +static Uint64 dos_joystick_next_poll_ns = 0; +#define DOS_JOYSTICK_POLL_INTERVAL_NS SDL_MS_TO_NS(16) /* ~60 Hz is plenty for a 2-axis gameport stick */ + +struct joystick_hwdata +{ + int axis_min[2]; /* minimum raw axis values seen */ + int axis_max[2]; /* maximum raw axis values seen */ + int axis_center[2]; /* center raw axis values (captured on first read) */ + bool calibrated; /* whether we've seen enough range */ +}; + +/* + * Probe for joystick presence using BIOS INT 15h, function 84h, subfunction 0. + * This reads the button state — if the BIOS supports it, a joystick is present. + * Returns true if the BIOS call succeeds (carry flag clear). + */ +static bool ProbeGameport(void) +{ + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x8400; /* INT 15h AH=84h */ + regs.x.dx = 0x0000; /* subfunction 0: read button state */ + __dpmi_int(0x15, ®s); + /* Carry flag set = no joystick BIOS support */ + return !(regs.x.flags & 0x01); +} + +/* + * Read joystick axes using BIOS INT 15h, function 84h, subfunction 1. + * Returns calibrated raw values in AX (X axis) and BX (Y axis). + * This avoids direct port I/O timing loops — the BIOS handles the + * one-shot timer polling internally. + */ +static void ReadGameportAxes(int *axis_x, int *axis_y) +{ + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x8400; /* INT 15h AH=84h */ + regs.x.dx = 0x0001; /* subfunction 1: read axis values */ + __dpmi_int(0x15, ®s); + if (regs.x.flags & 0x01) { + /* BIOS call failed */ + *axis_x = -1; + *axis_y = -1; + } else { + *axis_x = (int)regs.x.ax; /* joystick 1 X axis */ + *axis_y = (int)regs.x.bx; /* joystick 1 Y axis */ + } +} + +static Sint16 CalibrateAxis(int raw, struct joystick_hwdata *hwdata, int axis) +{ + int range; + int centered; + + if (raw < 0) { + return 0; /* axis not connected, report center */ + } + + if (raw < hwdata->axis_min[axis]) { + hwdata->axis_min[axis] = raw; + } + if (raw > hwdata->axis_max[axis]) { + hwdata->axis_max[axis] = raw; + } + + if (!hwdata->calibrated) { + hwdata->axis_center[axis] = raw; + /* Consider calibrated once we've seen some range on either axis */ + if ((hwdata->axis_max[0] - hwdata->axis_min[0]) > 20 || + (hwdata->axis_max[1] - hwdata->axis_min[1]) > 20) { + hwdata->calibrated = true; + } + } + + range = hwdata->axis_max[axis] - hwdata->axis_min[axis]; + if (range < 10) { + range = 10; /* avoid division issues */ + } + + /* Map to -32768..32767 */ + centered = raw - hwdata->axis_center[axis]; + return (Sint16)SDL_clamp(((Sint64)centered * 65535) / range, -32768, 32767); +} + +static bool DOS_JoystickInit(void) +{ + dos_joystick_detected = ProbeGameport(); + if (dos_joystick_detected) { + dos_joystick_id = dos_next_instance_id++; + } + return true; +} + +static int DOS_JoystickGetCount(void) +{ + return dos_joystick_detected ? 1 : 0; +} + +static void DOS_JoystickDetect(void) +{ + /* Don't re-probe every frame — ProbeGameport() does a tight loop of up to + 65536 port reads, which is very expensive and can interfere with SB16 IRQ + timing. DOS gameport joysticks are not hot-pluggable anyway. Detection + happens once in DOS_JoystickInit(). */ +} + +static bool DOS_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + return false; +} + +static const char *DOS_JoystickGetDeviceName(int device_index) +{ + if (device_index == 0 && dos_joystick_detected) { + return "DOS Gameport Joystick"; + } + return NULL; +} + +static const char *DOS_JoystickGetDevicePath(int device_index) +{ + if (device_index == 0 && dos_joystick_detected) { + return "gameport:0x201"; + } + return NULL; +} + +static int DOS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int DOS_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void DOS_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_GUID DOS_JoystickGetDeviceGUID(int device_index) +{ + return SDL_CreateJoystickGUID( + SDL_HARDWARE_BUS_UNKNOWN, /* bus */ + 0x0000, /* vendor */ + 0x0201, /* product (port number) */ + 0x0001, /* version */ + NULL, /* vendor_name */ + "DOS Gameport Joystick", /* product_name */ + 0, /* driver_signature */ + 0 /* driver_data */ + ); +} + +static SDL_JoystickID DOS_JoystickGetDeviceInstanceID(int device_index) +{ + if (device_index == 0 && dos_joystick_detected) { + return dos_joystick_id; + } + return 0; +} + +static bool DOS_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + struct joystick_hwdata *hwdata; + + hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*hwdata)); + if (!hwdata) { + return false; + } + + hwdata->axis_min[0] = INT_MAX; + hwdata->axis_min[1] = INT_MAX; + hwdata->axis_max[0] = 0; + hwdata->axis_max[1] = 0; + hwdata->axis_center[0] = 0; + hwdata->axis_center[1] = 0; + hwdata->calibrated = false; + + joystick->hwdata = hwdata; + joystick->naxes = 2; + joystick->nbuttons = 4; + joystick->nhats = 0; + joystick->nballs = 0; + + return true; +} + +static bool DOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static bool DOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static bool DOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static bool DOS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static bool DOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled) +{ + return SDL_Unsupported(); +} + +static void DOS_JoystickUpdate(SDL_Joystick *joystick) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + int axis_x, axis_y; + Uint8 val; + Uint64 now; + + if (!hwdata) { + return; + } + + /* Buttons are a passive port read (no timing loop), always safe to poll */ + val = inportb(GAMEPORT); + SDL_SendJoystickButton(0, joystick, 0, !(val & GAMEPORT_BUTTON1)); + SDL_SendJoystickButton(0, joystick, 1, !(val & GAMEPORT_BUTTON2)); + SDL_SendJoystickButton(0, joystick, 2, !(val & GAMEPORT_BUTTON3)); + SDL_SendJoystickButton(0, joystick, 3, !(val & GAMEPORT_BUTTON4)); + + /* Throttle axis reads — BIOS INT 15h subfunction 1 does an internal + timing loop that is very expensive. ~60 Hz is more than enough for + a 2-axis analog gameport stick. */ + now = SDL_GetTicksNS(); + if (now < dos_joystick_next_poll_ns) { + return; + } + dos_joystick_next_poll_ns = now + DOS_JOYSTICK_POLL_INTERVAL_NS; + + ReadGameportAxes(&axis_x, &axis_y); + + if (axis_x >= 0) { + Sint16 cal_x = CalibrateAxis(axis_x, hwdata, 0); + SDL_SendJoystickAxis(0, joystick, 0, cal_x); + } + + if (axis_y >= 0) { + Sint16 cal_y = CalibrateAxis(axis_y, hwdata, 1); + SDL_SendJoystickAxis(0, joystick, 1, cal_y); + } +} + +static void DOS_JoystickClose(SDL_Joystick *joystick) +{ + if (joystick->hwdata) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + } +} + +static void DOS_JoystickQuit(void) +{ + dos_joystick_detected = false; + dos_joystick_id = 0; +} + +static bool DOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return false; +} + +SDL_JoystickDriver SDL_DOS_JoystickDriver = { + DOS_JoystickInit, + DOS_JoystickGetCount, + DOS_JoystickDetect, + DOS_JoystickIsDevicePresent, + DOS_JoystickGetDeviceName, + DOS_JoystickGetDevicePath, + DOS_JoystickGetDeviceSteamVirtualGamepadSlot, + DOS_JoystickGetDevicePlayerIndex, + DOS_JoystickSetDevicePlayerIndex, + DOS_JoystickGetDeviceGUID, + DOS_JoystickGetDeviceInstanceID, + DOS_JoystickOpen, + DOS_JoystickRumble, + DOS_JoystickRumbleTriggers, + DOS_JoystickSetLED, + DOS_JoystickSendEffect, + DOS_JoystickSetSensorsEnabled, + DOS_JoystickUpdate, + DOS_JoystickClose, + DOS_JoystickQuit, + DOS_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_DOS */ \ No newline at end of file diff --git a/src/main/SDL_runapp.c b/src/main/SDL_runapp.c index c0ccd8fa6a..108c4c1a36 100644 --- a/src/main/SDL_runapp.c +++ b/src/main/SDL_runapp.c @@ -29,7 +29,8 @@ !defined(SDL_PLATFORM_EMSCRIPTEN) && \ !defined(SDL_PLATFORM_PSP) && \ !defined(SDL_PLATFORM_PS2) && \ - !defined(SDL_PLATFORM_3DS) + !defined(SDL_PLATFORM_3DS) && \ + !defined(SDL_PLATFORM_DOS) int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserved) { diff --git a/src/main/dos/SDL_sysmain_runapp.c b/src/main/dos/SDL_sysmain_runapp.c new file mode 100644 index 0000000000..e41628cfce --- /dev/null +++ b/src/main/dos/SDL_sysmain_runapp.c @@ -0,0 +1,51 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#include "../SDL_main_callbacks.h" + +#ifdef SDL_PLATFORM_DOS + +#include + +// this locks .data, .bss, .text, and the stack. In SDL_RunApp(), we'll adjust this flag so future malloc() calls aren't locked by default. +#include +int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY | _CRT0_FLAG_NONMOVE_SBRK; + +const char *SDL_argv0 = NULL; + +int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void *reserved) +{ + (void)reserved; + _crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; // don't lock further allocations by default...so data, code, and stack are locked but not buffers from future malloc() calls. + + if (!__djgpp_nearptr_enable()) { + fprintf(stderr, "__djgpp_nearptr_enable() failed!\n"); + return 1; + } + + SDL_argv0 = argv ? argv[0] : NULL; + + return SDL_CallMainFunction(argc, argv, mainFunction); +} + +#endif diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 4a870f6e0d..f8813044ee 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -36,7 +36,7 @@ #define SDL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__ #elif defined(SDL_PLATFORM_NGAGE) #define SDL_SIZEOF_WCHAR_T 2 -#elif defined(SDL_PLATFORM_WINDOWS) +#elif defined(SDL_PLATFORM_WINDOWS) || defined(SDL_PLATFORM_DOS) #define SDL_SIZEOF_WCHAR_T 2 #else // assume everything else is UTF-32 (add more tests if compiler-assert fails below!) #define SDL_SIZEOF_WCHAR_T 4 diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 25b7096482..47efd59f0e 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -38,6 +38,8 @@ #include "vita/SDL_systhread_c.h" #elif defined(SDL_THREAD_N3DS) #include "n3ds/SDL_systhread_c.h" +#elif defined(SDL_THREAD_DOS) +#include "dos/SDL_systhread_c.h" #else #error Need thread implementation for this platform #include "generic/SDL_systhread_c.h" diff --git a/src/thread/dos/SDL_sysmutex.c b/src/thread/dos/SDL_sysmutex.c new file mode 100644 index 0000000000..9b138017dc --- /dev/null +++ b/src/thread/dos/SDL_sysmutex.c @@ -0,0 +1,122 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_THREAD_DOS + +/* Mutex implementation for DOS cooperative threading. + Uses cli/sti for atomicity and cooperative yielding for contention. */ + +#include "../../core/dos/SDL_dos.h" +#include "../../core/dos/SDL_dos_scheduler.h" + +#define MUTEX_NO_OWNER -1 + +struct SDL_Mutex +{ + volatile int owner; /* Thread ID of owner, or MUTEX_NO_OWNER if unlocked */ + volatile int recursive; /* Recursion count */ +}; + +SDL_Mutex *SDL_CreateMutex(void) +{ + SDL_Mutex *mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex)); + if (mutex) { + mutex->owner = MUTEX_NO_OWNER; + mutex->recursive = 0; + } + return mutex; +} + +void SDL_DestroyMutex(SDL_Mutex *mutex) +{ + if (mutex) { + SDL_free(mutex); + } +} + +void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS +{ + if (!mutex) { + return; + } + + int tid = DOS_GetCurrentThreadID(); + + for (;;) { + DOS_DisableInterrupts(); + if (mutex->owner == MUTEX_NO_OWNER) { + mutex->owner = tid; + mutex->recursive = 1; + DOS_EnableInterrupts(); + return; + } + if (mutex->owner == tid) { + mutex->recursive++; + DOS_EnableInterrupts(); + return; + } + DOS_EnableInterrupts(); + DOS_Yield(); + } +} + +bool SDL_TryLockMutex(SDL_Mutex *mutex) +{ + if (!mutex) { + return true; + } + + int tid = DOS_GetCurrentThreadID(); + + DOS_DisableInterrupts(); + if (mutex->owner == MUTEX_NO_OWNER) { + mutex->owner = tid; + mutex->recursive = 1; + DOS_EnableInterrupts(); + return true; + } + if (mutex->owner == tid) { + mutex->recursive++; + DOS_EnableInterrupts(); + return true; + } + DOS_EnableInterrupts(); + return false; +} + +void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS +{ + if (!mutex) { + return; + } + + DOS_DisableInterrupts(); + if (mutex->recursive > 1) { + mutex->recursive--; + } else { + mutex->owner = MUTEX_NO_OWNER; + mutex->recursive = 0; + } + DOS_EnableInterrupts(); +} + +#endif /* SDL_THREAD_DOS */ \ No newline at end of file diff --git a/src/thread/dos/SDL_syssem.c b/src/thread/dos/SDL_syssem.c new file mode 100644 index 0000000000..3166b2bce0 --- /dev/null +++ b/src/thread/dos/SDL_syssem.c @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_THREAD_DOS + +/* Semaphore implementation for DOS cooperative threading. + Uses cli/sti for atomicity and cooperative yielding for waits. */ + +#include "../../core/dos/SDL_dos.h" +#include "../../core/dos/SDL_dos_scheduler.h" + +struct SDL_Semaphore +{ + volatile Uint32 count; +}; + +SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_Semaphore *sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem)); + if (sem) { + sem->count = initial_value; + } + return sem; +} + +void SDL_DestroySemaphore(SDL_Semaphore *sem) +{ + if (sem) { + SDL_free(sem); + } +} + +bool SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS) +{ + if (!sem) { + return true; + } + + /* Try-wait (poll): check and decrement if possible */ + if (timeoutNS == 0) { + bool acquired = false; + DOS_DisableInterrupts(); + if (sem->count > 0) { + sem->count--; + acquired = true; + } + DOS_EnableInterrupts(); + return acquired; + } + + /* Indefinite wait (-1) or timed wait */ + Uint64 deadline = 0; + if (timeoutNS > 0) { + deadline = SDL_GetPerformanceCounter() + + (Uint64)((double)timeoutNS * (double)SDL_GetPerformanceFrequency() / 1e9); + } + + for (;;) { + DOS_DisableInterrupts(); + if (sem->count > 0) { + sem->count--; + DOS_EnableInterrupts(); + return true; /* Acquired */ + } + DOS_EnableInterrupts(); + + /* Check timeout */ + if (timeoutNS > 0 && SDL_GetPerformanceCounter() >= deadline) { + return false; /* Timed out */ + } + + /* Yield to other threads instead of busy-spinning */ + DOS_Yield(); + } +} + +Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem) +{ + if (!sem) { + return 0; + } + return sem->count; +} + +void SDL_SignalSemaphore(SDL_Semaphore *sem) +{ + if (!sem) { + return; + } + + DOS_DisableInterrupts(); + sem->count++; + DOS_EnableInterrupts(); +} + +#endif /* SDL_THREAD_DOS */ \ No newline at end of file diff --git a/src/thread/dos/SDL_systhread.c b/src/thread/dos/SDL_systhread.c new file mode 100644 index 0000000000..836bcf0632 --- /dev/null +++ b/src/thread/dos/SDL_systhread.c @@ -0,0 +1,87 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_THREAD_DOS + +/* DOS thread management routines for SDL — cooperative threading via + the DOS mini-scheduler (no OS-level threads on DOS). */ + +#include "../../core/dos/SDL_dos_scheduler.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" + +static int ThreadEntry(void *arg) +{ + SDL_Thread *thread = (SDL_Thread *)arg; + SDL_RunThread(thread); + return 0; +} + +bool SDL_SYS_CreateThread(SDL_Thread *thread, + SDL_FunctionPointer pfnBeginThread, + SDL_FunctionPointer pfnEndThread) +{ + /* Ensure the scheduler is initialized (idempotent) */ + DOS_SchedulerInit(); + + size_t stack_size = thread->stacksize; + + int tid = DOS_CreateThread(ThreadEntry, thread, stack_size); + if (tid < 0) { + return SDL_SetError("DOS_CreateThread() failed — no free thread slots"); + } + + thread->handle = tid; + return true; +} + +void SDL_SYS_SetupThread(const char *name) +{ + /* Nothing to do on DOS */ +} + +SDL_ThreadID SDL_GetCurrentThreadID(void) +{ + return (SDL_ThreadID)DOS_GetCurrentThreadID(); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + DOS_JoinThread(thread->handle); + DOS_DestroyThread(thread->handle); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + /* For cooperative threads, detach is a no-op. The thread will clean + itself up when it finishes. In practice, SDL's thread code handles + the detach lifecycle via atomics in SDL_RunThread. */ +} + +bool SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + /* DOS cooperative scheduler uses round-robin — priority is not + meaningful. Accept any value without error. */ + return true; +} + +#endif /* SDL_THREAD_DOS */ \ No newline at end of file diff --git a/src/thread/dos/SDL_systhread_c.h b/src/thread/dos/SDL_systhread_c.h new file mode 100644 index 0000000000..ba1629e239 --- /dev/null +++ b/src/thread/dos/SDL_systhread_c.h @@ -0,0 +1,28 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_systhread_c_h_ +#define SDL_systhread_c_h_ + +/* DOS thread handle is an integer thread ID from the DOS scheduler */ +typedef int SYS_ThreadHandle; + +#endif /* SDL_systhread_c_h_ */ \ No newline at end of file diff --git a/src/thread/dos/SDL_systls.c b/src/thread/dos/SDL_systls.c new file mode 100644 index 0000000000..5c47596189 --- /dev/null +++ b/src/thread/dos/SDL_systls.c @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_THREAD_DOS + +/* DOS thread-local storage — uses per-thread static array indexed by + the scheduler's thread ID. With only DOS_MAX_THREADS (8) threads, + a simple static array is efficient and avoids any dynamic allocation. */ + +#include "../../core/dos/SDL_dos_scheduler.h" +#include "../SDL_thread_c.h" + +static SDL_TLSData *tls_data[DOS_MAX_THREADS]; + +void SDL_SYS_InitTLSData(void) +{ + SDL_memset(tls_data, 0, sizeof(tls_data)); +} + +SDL_TLSData *SDL_SYS_GetTLSData(void) +{ + int tid = DOS_GetCurrentThreadID(); + if (tid < 0 || tid >= DOS_MAX_THREADS) { + return NULL; + } + return tls_data[tid]; +} + +bool SDL_SYS_SetTLSData(SDL_TLSData *data) +{ + int tid = DOS_GetCurrentThreadID(); + if (tid < 0 || tid >= DOS_MAX_THREADS) { + return SDL_SetError("Invalid thread ID for TLS"); + } + tls_data[tid] = data; + return true; +} + +void SDL_SYS_QuitTLSData(void) +{ + SDL_memset(tls_data, 0, sizeof(tls_data)); +} + +#endif /* SDL_THREAD_DOS */ \ No newline at end of file diff --git a/src/time/unix/SDL_systime.c b/src/time/unix/SDL_systime.c index a3c6b31fc8..b5ae564407 100644 --- a/src/time/unix/SDL_systime.c +++ b/src/time/unix/SDL_systime.c @@ -24,7 +24,9 @@ #include "../SDL_time_c.h" #include +#ifndef SDL_PLATFORM_DOS #include +#endif #include #include #include diff --git a/src/timer/dos/SDL_systimer.c b/src/timer/dos/SDL_systimer.c new file mode 100644 index 0000000000..d47bae177f --- /dev/null +++ b/src/timer/dos/SDL_systimer.c @@ -0,0 +1,70 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_TIMER_DOS + +#include /* delay */ +#include /* uclock, uclock_t, UCLOCKS_PER_SEC */ + +#include "../../core/dos/SDL_dos_scheduler.h" + +/* DJGPP's uclock() reprograms PIT channel 0 for a higher tick rate on first + call, giving ~1.19 MHz resolution (UCLOCKS_PER_SEC == 1193180). This is + the same approach SDL2-dos used and gives sub-microsecond precision without + any extra setup. */ + +Uint64 SDL_GetPerformanceCounter(void) +{ + return (Uint64)uclock(); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return (Uint64)UCLOCKS_PER_SEC; +} + +void SDL_SYS_DelayNS(Uint64 ns) +{ + if (ns == 0) { + DOS_Yield(); + return; + } + + const uclock_t delay_start = uclock(); + const uclock_t target_ticks = (uclock_t)((ns * UCLOCKS_PER_SEC) / SDL_NS_PER_SECOND); + + while ((uclock() - delay_start) < target_ticks) { + /* Always yield first so cooperative threads can run. */ + DOS_Yield(); + + /* If more than 1 ms remains, do a short sleep to avoid burning + 100% CPU when no other threads need to run. DJGPP's delay() + is a busy-wait but it does halt-loop on the PIT, which is + lighter than a tight uclock() poll. */ + uclock_t remaining = target_ticks - (uclock() - delay_start); + if (remaining > (UCLOCKS_PER_SEC / 1000)) { + delay(1); + } + } +} + +#endif /* SDL_TIMER_DOS */ \ No newline at end of file diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 06aba744ad..76d924c25d 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -546,6 +546,7 @@ extern VideoBootStrap Emscripten_bootstrap; extern VideoBootStrap OFFSCREEN_bootstrap; extern VideoBootStrap QNX_bootstrap; extern VideoBootStrap OPENVR_bootstrap; +extern VideoBootStrap DOSVESA_bootstrap; extern bool SDL_UninitializedVideo(void); // Use SDL_OnVideoThread() sparingly, to avoid regressions in use cases that currently happen to work diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 9026e47fad..8308eba5d9 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -149,6 +149,9 @@ static VideoBootStrap *bootstrap[] = { &DUMMY_evdev_bootstrap, #endif #endif +#ifdef SDL_VIDEO_DRIVER_DOSVESA + &DOSVESA_bootstrap, +#endif #ifdef SDL_VIDEO_DRIVER_OPENVR &OPENVR_bootstrap, #endif diff --git a/src/video/dos/SDL_dosevents.c b/src/video/dos/SDL_dosevents.c new file mode 100644 index 0000000000..78a50b649d --- /dev/null +++ b/src/video/dos/SDL_dosevents.c @@ -0,0 +1,397 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_DOSVESA + +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_dosvideo.h" + +#include "../../core/dos/SDL_dos_scheduler.h" +#include "SDL_dosevents_c.h" + +// PS/2 keyboard controller port +#define KBD_DATA_PORT 0x60 + +// Scancode byte structure +#define SCANCODE_MASK 0x7F // bits 0-6: scancode index +#define SCANCODE_RELEASE 0x80 // bit 7: key released (break code) + +// Multi-byte scancode prefixes +#define SCANCODE_PREFIX_EXTENDED 0xE0 // extended key prefix +#define SCANCODE_PREFIX_PAUSE 0xE1 // pause key sequence prefix + +// VGA Input Status Register 1 (for vblank detection) +#define VGA_STATUS_PORT 0x3DA +#define VGA_STATUS_VBLANK 0x08 // bit 3: vertical retrace active + +// Scancode table: https://www.plantation-productions.com/Webster/www.artofasm.com/DOS/pdf/apndxc.pdf +static const SDL_Scancode DOSVESA_ScancodeMapping[] = { // index is the scancode from the IRQ1 handler bitwise-ANDed against 0x7F. + /* 0x00 */ SDL_SCANCODE_UNKNOWN, + /* 0x01 */ SDL_SCANCODE_ESCAPE, + /* 0x02 */ SDL_SCANCODE_1, + /* 0x03 */ SDL_SCANCODE_2, + /* 0x04 */ SDL_SCANCODE_3, + /* 0x05 */ SDL_SCANCODE_4, + /* 0x06 */ SDL_SCANCODE_5, + /* 0x07 */ SDL_SCANCODE_6, + /* 0x08 */ SDL_SCANCODE_7, + /* 0x09 */ SDL_SCANCODE_8, + /* 0x0A */ SDL_SCANCODE_9, + /* 0x0B */ SDL_SCANCODE_0, + /* 0x0C */ SDL_SCANCODE_MINUS, + /* 0x0D */ SDL_SCANCODE_EQUALS, + /* 0x0E */ SDL_SCANCODE_BACKSPACE, + /* 0x0F */ SDL_SCANCODE_TAB, + + /* 0x10 */ SDL_SCANCODE_Q, + /* 0x11 */ SDL_SCANCODE_W, + /* 0x12 */ SDL_SCANCODE_E, + /* 0x13 */ SDL_SCANCODE_R, + /* 0x14 */ SDL_SCANCODE_T, + /* 0x15 */ SDL_SCANCODE_Y, + /* 0x16 */ SDL_SCANCODE_U, + /* 0x17 */ SDL_SCANCODE_I, + /* 0x18 */ SDL_SCANCODE_O, + /* 0x19 */ SDL_SCANCODE_P, + /* 0x1A */ SDL_SCANCODE_LEFTBRACKET, + /* 0x1B */ SDL_SCANCODE_RIGHTBRACKET, + /* 0x1C */ SDL_SCANCODE_RETURN, + /* 0x1D */ SDL_SCANCODE_LCTRL, + /* 0x1E */ SDL_SCANCODE_A, + /* 0x1F */ SDL_SCANCODE_S, + + /* 0x20 */ SDL_SCANCODE_D, + /* 0x21 */ SDL_SCANCODE_F, + /* 0x22 */ SDL_SCANCODE_G, + /* 0x23 */ SDL_SCANCODE_H, + /* 0x24 */ SDL_SCANCODE_J, + /* 0x25 */ SDL_SCANCODE_K, + /* 0x26 */ SDL_SCANCODE_L, + /* 0x27 */ SDL_SCANCODE_SEMICOLON, + /* 0x28 */ SDL_SCANCODE_APOSTROPHE, + /* 0x29 */ SDL_SCANCODE_GRAVE, + /* 0x2A */ SDL_SCANCODE_LSHIFT, + /* 0x2B */ SDL_SCANCODE_BACKSLASH, + /* 0x2C */ SDL_SCANCODE_Z, + /* 0x2D */ SDL_SCANCODE_X, + /* 0x2E */ SDL_SCANCODE_C, + /* 0x2F */ SDL_SCANCODE_V, + + /* 0x30 */ SDL_SCANCODE_B, + /* 0x31 */ SDL_SCANCODE_N, + /* 0x32 */ SDL_SCANCODE_M, + /* 0x33 */ SDL_SCANCODE_COMMA, + /* 0x34 */ SDL_SCANCODE_PERIOD, + /* 0x35 */ SDL_SCANCODE_SLASH, + /* 0x36 */ SDL_SCANCODE_RSHIFT, + /* 0x37 */ SDL_SCANCODE_KP_MULTIPLY, + /* 0x38 */ SDL_SCANCODE_LALT, + /* 0x39 */ SDL_SCANCODE_SPACE, + /* 0x3A */ SDL_SCANCODE_CAPSLOCK, + /* 0x3B */ SDL_SCANCODE_F1, + /* 0x3C */ SDL_SCANCODE_F2, + /* 0x3D */ SDL_SCANCODE_F3, + /* 0x3E */ SDL_SCANCODE_F4, + /* 0x3F */ SDL_SCANCODE_F5, + + /* 0x040 */ SDL_SCANCODE_F6, + /* 0x041 */ SDL_SCANCODE_F7, + /* 0x042 */ SDL_SCANCODE_F8, + /* 0x043 */ SDL_SCANCODE_F9, + /* 0x044 */ SDL_SCANCODE_F10, + /* 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 0x046 */ SDL_SCANCODE_SCROLLLOCK, + /* 0x047 */ SDL_SCANCODE_KP_7, + /* 0x048 */ SDL_SCANCODE_KP_8, + /* 0x049 */ SDL_SCANCODE_KP_9, + /* 0x04A */ SDL_SCANCODE_KP_MINUS, + /* 0x04B */ SDL_SCANCODE_KP_4, + /* 0x04C */ SDL_SCANCODE_KP_5, + /* 0x04D */ SDL_SCANCODE_KP_6, + /* 0x04E */ SDL_SCANCODE_KP_PLUS, + /* 0x04F */ SDL_SCANCODE_KP_1, + + /* 0x050 */ SDL_SCANCODE_KP_2, + /* 0x051 */ SDL_SCANCODE_KP_3, + /* 0x052 */ SDL_SCANCODE_KP_0, + /* 0x053 */ SDL_SCANCODE_KP_PERIOD, + /* 0x054 */ SDL_SCANCODE_UNKNOWN, + /* 0x055 */ SDL_SCANCODE_UNKNOWN, + /* 0x056 */ SDL_SCANCODE_UNKNOWN, + /* 0x057 */ SDL_SCANCODE_F11, + /* 0x058 */ SDL_SCANCODE_F12 +}; + +// Extended scancode table for keys prefixed with 0xE0 +static const SDL_Scancode DOSVESA_ExtendedScancodeMapping[] = { // index is the scancode byte following the 0xE0 prefix, masked with 0x7F. + /* 0x00 */ SDL_SCANCODE_UNKNOWN, + /* 0x01 */ SDL_SCANCODE_UNKNOWN, + /* 0x02 */ SDL_SCANCODE_UNKNOWN, + /* 0x03 */ SDL_SCANCODE_UNKNOWN, + /* 0x04 */ SDL_SCANCODE_UNKNOWN, + /* 0x05 */ SDL_SCANCODE_UNKNOWN, + /* 0x06 */ SDL_SCANCODE_UNKNOWN, + /* 0x07 */ SDL_SCANCODE_UNKNOWN, + /* 0x08 */ SDL_SCANCODE_UNKNOWN, + /* 0x09 */ SDL_SCANCODE_UNKNOWN, + /* 0x0A */ SDL_SCANCODE_UNKNOWN, + /* 0x0B */ SDL_SCANCODE_UNKNOWN, + /* 0x0C */ SDL_SCANCODE_UNKNOWN, + /* 0x0D */ SDL_SCANCODE_UNKNOWN, + /* 0x0E */ SDL_SCANCODE_UNKNOWN, + /* 0x0F */ SDL_SCANCODE_UNKNOWN, + + /* 0x10 */ SDL_SCANCODE_UNKNOWN, + /* 0x11 */ SDL_SCANCODE_UNKNOWN, + /* 0x12 */ SDL_SCANCODE_UNKNOWN, + /* 0x13 */ SDL_SCANCODE_UNKNOWN, + /* 0x14 */ SDL_SCANCODE_UNKNOWN, + /* 0x15 */ SDL_SCANCODE_UNKNOWN, + /* 0x16 */ SDL_SCANCODE_UNKNOWN, + /* 0x17 */ SDL_SCANCODE_UNKNOWN, + /* 0x18 */ SDL_SCANCODE_UNKNOWN, + /* 0x19 */ SDL_SCANCODE_UNKNOWN, + /* 0x1A */ SDL_SCANCODE_UNKNOWN, + /* 0x1B */ SDL_SCANCODE_UNKNOWN, + /* 0x1C */ SDL_SCANCODE_KP_ENTER, + /* 0x1D */ SDL_SCANCODE_RCTRL, + /* 0x1E */ SDL_SCANCODE_UNKNOWN, + /* 0x1F */ SDL_SCANCODE_UNKNOWN, + + /* 0x20 */ SDL_SCANCODE_UNKNOWN, + /* 0x21 */ SDL_SCANCODE_UNKNOWN, + /* 0x22 */ SDL_SCANCODE_UNKNOWN, + /* 0x23 */ SDL_SCANCODE_UNKNOWN, + /* 0x24 */ SDL_SCANCODE_UNKNOWN, + /* 0x25 */ SDL_SCANCODE_UNKNOWN, + /* 0x26 */ SDL_SCANCODE_UNKNOWN, + /* 0x27 */ SDL_SCANCODE_UNKNOWN, + /* 0x28 */ SDL_SCANCODE_UNKNOWN, + /* 0x29 */ SDL_SCANCODE_UNKNOWN, + /* 0x2A */ SDL_SCANCODE_UNKNOWN, // fake left shift, ignore + /* 0x2B */ SDL_SCANCODE_UNKNOWN, + /* 0x2C */ SDL_SCANCODE_UNKNOWN, + /* 0x2D */ SDL_SCANCODE_UNKNOWN, + /* 0x2E */ SDL_SCANCODE_UNKNOWN, + /* 0x2F */ SDL_SCANCODE_UNKNOWN, + + /* 0x30 */ SDL_SCANCODE_UNKNOWN, + /* 0x31 */ SDL_SCANCODE_UNKNOWN, + /* 0x32 */ SDL_SCANCODE_UNKNOWN, + /* 0x33 */ SDL_SCANCODE_UNKNOWN, + /* 0x34 */ SDL_SCANCODE_UNKNOWN, + /* 0x35 */ SDL_SCANCODE_KP_DIVIDE, + /* 0x36 */ SDL_SCANCODE_UNKNOWN, // fake right shift, ignore + /* 0x37 */ SDL_SCANCODE_PRINTSCREEN, + /* 0x38 */ SDL_SCANCODE_RALT, + /* 0x39 */ SDL_SCANCODE_UNKNOWN, + /* 0x3A */ SDL_SCANCODE_UNKNOWN, + /* 0x3B */ SDL_SCANCODE_UNKNOWN, + /* 0x3C */ SDL_SCANCODE_UNKNOWN, + /* 0x3D */ SDL_SCANCODE_UNKNOWN, + /* 0x3E */ SDL_SCANCODE_UNKNOWN, + /* 0x3F */ SDL_SCANCODE_UNKNOWN, + + /* 0x40 */ SDL_SCANCODE_UNKNOWN, + /* 0x41 */ SDL_SCANCODE_UNKNOWN, + /* 0x42 */ SDL_SCANCODE_UNKNOWN, + /* 0x43 */ SDL_SCANCODE_UNKNOWN, + /* 0x44 */ SDL_SCANCODE_UNKNOWN, + /* 0x45 */ SDL_SCANCODE_UNKNOWN, + /* 0x46 */ SDL_SCANCODE_PAUSE, // Ctrl+Break sends E0 46 E0 C6 + /* 0x47 */ SDL_SCANCODE_HOME, + /* 0x48 */ SDL_SCANCODE_UP, + /* 0x49 */ SDL_SCANCODE_PAGEUP, + /* 0x4A */ SDL_SCANCODE_UNKNOWN, + /* 0x4B */ SDL_SCANCODE_LEFT, + /* 0x4C */ SDL_SCANCODE_UNKNOWN, + /* 0x4D */ SDL_SCANCODE_RIGHT, + /* 0x4E */ SDL_SCANCODE_UNKNOWN, + /* 0x4F */ SDL_SCANCODE_END, + + /* 0x50 */ SDL_SCANCODE_DOWN, + /* 0x51 */ SDL_SCANCODE_PAGEDOWN, + /* 0x52 */ SDL_SCANCODE_INSERT, + /* 0x53 */ SDL_SCANCODE_DELETE, + /* 0x54 */ SDL_SCANCODE_UNKNOWN, + /* 0x55 */ SDL_SCANCODE_UNKNOWN, + /* 0x56 */ SDL_SCANCODE_UNKNOWN, + /* 0x57 */ SDL_SCANCODE_UNKNOWN, + /* 0x58 */ SDL_SCANCODE_UNKNOWN, + /* 0x59 */ SDL_SCANCODE_UNKNOWN, + /* 0x5A */ SDL_SCANCODE_UNKNOWN, + /* 0x5B */ SDL_SCANCODE_LGUI, + /* 0x5C */ SDL_SCANCODE_RGUI, + /* 0x5D */ SDL_SCANCODE_APPLICATION +}; + +static Uint8 keyevents_ringbuffer[256]; +static int keyevents_head = 0; +static int keyevents_tail = 0; + +void DOSVESA_PumpEvents(SDL_VideoDevice *device) +{ + /* Give cooperative threads a chance to run. Audio mixing now runs + in its own cooperative thread (via SDL's normal audio thread), + so it will execute during this yield along with loading threads + and anything else that is runnable. */ + DOS_Yield(); + + static bool is_extended = false; + static int pause_sequence_remaining = 0; + + while (keyevents_head != keyevents_tail) { + const Uint8 event = keyevents_ringbuffer[keyevents_tail]; + keyevents_tail = (keyevents_tail + 1) & (SDL_arraysize(keyevents_ringbuffer) - 1); + + // Handle remaining bytes of E1 Pause key sequence (E1 1D 45 E1 9D C5). + if (pause_sequence_remaining > 0) { + pause_sequence_remaining--; + continue; + } + + // Pause key sends a multi-byte sequence: E1 1D 45 E1 9D C5. Emit PAUSE press+release and consume the rest. + if (event == SCANCODE_PREFIX_PAUSE) { + pause_sequence_remaining = 5; // skip the next 5 bytes + SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_PAUSE, true); + SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_PAUSE, false); + continue; + } + + if (event == SCANCODE_PREFIX_EXTENDED) { + is_extended = true; + continue; + } + + const int scancode = (int)(event & SCANCODE_MASK); + const bool pressed = ((event & SCANCODE_RELEASE) == 0); + + SDL_Scancode sc = SDL_SCANCODE_UNKNOWN; + + if (is_extended) { + is_extended = false; + if (scancode < SDL_arraysize(DOSVESA_ExtendedScancodeMapping)) { + sc = DOSVESA_ExtendedScancodeMapping[scancode]; + } + } else { + if (scancode < SDL_arraysize(DOSVESA_ScancodeMapping)) { + sc = DOSVESA_ScancodeMapping[scancode]; + } + } + + if (sc != SDL_SCANCODE_UNKNOWN) { + SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, sc, pressed); + + // Generate text input events for key-down on printable characters. + // SDL keycodes below SDLK_SCANCODE_MASK are Unicode codepoints. + if (pressed) { + SDL_Keymod mod = SDL_GetModState(); + if (!(mod & (SDL_KMOD_CTRL | SDL_KMOD_ALT))) { + SDL_Keycode keycode = SDL_GetKeyFromScancode(sc, mod, false); + if (keycode > 0 && keycode < SDLK_SCANCODE_MASK && !SDL_iscntrl((int)keycode)) { + char text[5]; + char *end = SDL_UCS4ToUTF8((Uint32)keycode, text); + *end = '\0'; + SDL_SendKeyboardText(text); + } + } + } + } + } + + SDL_Mouse *mouse = SDL_GetMouse(); + if (mouse->internal) { // if non-NULL, there's a mouse detected on the system. + __dpmi_regs regs; + + regs.x.ax = 0x3; // read mouse buttons and position. + __dpmi_int(0x33, ®s); + const Uint16 buttons = (int)(Sint16)regs.x.bx; + + SDL_SendMouseButton(0, mouse->focus, SDL_DEFAULT_MOUSE_ID, SDL_BUTTON_LEFT, (buttons & (1 << 0)) != 0); + SDL_SendMouseButton(0, mouse->focus, SDL_DEFAULT_MOUSE_ID, SDL_BUTTON_RIGHT, (buttons & (1 << 1)) != 0); + SDL_SendMouseButton(0, mouse->focus, SDL_DEFAULT_MOUSE_ID, SDL_BUTTON_MIDDLE, (buttons & (1 << 2)) != 0); + + if (!mouse->relative_mode) { + const int x = (int)(Sint16)regs.x.cx; // part of function 0x3's return value. + const int y = (int)(Sint16)regs.x.dx; + SDL_SendMouseMotion(0, mouse->focus, SDL_DEFAULT_MOUSE_ID, false, x, y); + } else { + regs.x.ax = 0xB; // read motion counters + __dpmi_int(0x33, ®s); + // values returned here are -32768 to 32767 + const SDL_VideoData *viddata = device->internal; + const float MICKEYS_PER_HPIXEL = viddata->mickeys_per_hpixel; + const float MICKEYS_PER_VPIXEL = viddata->mickeys_per_vpixel; + const int mickeys_x = (int)(Sint16)regs.x.cx; + const int mickeys_y = (int)(Sint16)regs.x.dx; + SDL_SendMouseMotion(0, mouse->focus, SDL_DEFAULT_MOUSE_ID, true, mickeys_x / MICKEYS_PER_HPIXEL, mickeys_y / MICKEYS_PER_VPIXEL); + } + } +} + +static void KeyboardIRQHandler(void) // this is wrapped in a thing that handles IRET, etc. +{ + keyevents_ringbuffer[keyevents_head] = inportb(KBD_DATA_PORT); + keyevents_head = (keyevents_head + 1) & (SDL_arraysize(keyevents_ringbuffer) - 1); + DOS_EndOfInterrupt(1); +} +static void KeyboardIRQHandler_End(void) {} // end-of-ISR label for memory locking + +void DOSVESA_InitKeyboard(SDL_VideoDevice *device) +{ + SDL_VideoData *data = device->internal; + + // Lock ISR code and data to prevent page faults during interrupts + DOS_LockCode(KeyboardIRQHandler, KeyboardIRQHandler_End); + DOS_LockVariable(keyevents_ringbuffer); + DOS_LockVariable(keyevents_head); + DOS_LockVariable(keyevents_tail); + + DOS_HookInterrupt(1, KeyboardIRQHandler, &data->keyboard_interrupt_hook); +} + +void DOSVESA_QuitKeyboard(SDL_VideoDevice *device) +{ + SDL_VideoData *data = device->internal; + DOS_UnhookInterrupt(&data->keyboard_interrupt_hook, false); + + // Drain the BIOS keyboard buffer so held keys (like ESC) don't + // bleed through to the DOS command line after we exit. + { + __dpmi_regs regs; + for (;;) { + regs.h.ah = 0x01; // BIOS: check for keystroke + __dpmi_int(0x16, ®s); + if (regs.x.flags & 0x40) { // ZF set = buffer empty + break; + } + regs.h.ah = 0x00; // BIOS: read keystroke (removes it) + __dpmi_int(0x16, ®s); + } + } +} + +#endif // SDL_VIDEO_DRIVER_DOSVESA diff --git a/src/video/dos/SDL_dosevents_c.h b/src/video/dos/SDL_dosevents_c.h new file mode 100644 index 0000000000..bbff76f732 --- /dev/null +++ b/src/video/dos/SDL_dosevents_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dosevents_c_h_ +#define SDL_dosevents_c_h_ + +#include "SDL_dosvideo.h" + +void DOSVESA_PumpEvents(SDL_VideoDevice *device); +void DOSVESA_InitKeyboard(SDL_VideoDevice *device); +void DOSVESA_QuitKeyboard(SDL_VideoDevice *device); + +#endif // SDL_dosevents_c_h_ diff --git a/src/video/dos/SDL_dosframebuffer.c b/src/video/dos/SDL_dosframebuffer.c new file mode 100644 index 0000000000..2a707c9526 --- /dev/null +++ b/src/video/dos/SDL_dosframebuffer.c @@ -0,0 +1,969 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_DOSVESA + +#include "../../SDL_properties_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_dosframebuffer_c.h" +#include "SDL_dosmodes.h" +#include "SDL_dosmouse.h" +#include "SDL_dosvideo.h" + +#include // for inportb, outportb +#include // for dosmemput (banked framebuffer writes) + +// note that DOS_SURFACE's value is the same string that the dummy driver uses. +#define DOS_SURFACE "SDL.internal.window.surface" + +// Consolidated framebuffer state (DOS has only one window) +typedef struct DOSFramebufferState +{ + SDL_Surface *surface; // system-RAM surface (app renders here) + SDL_Surface *lfb_surface; // LFB surface (pixels in VRAM), NULL for direct-FB path + bool direct_fb; // true when the fast direct-FB hint path is active + bool use_dosmemput; // true = dosmemput (banked), false = nearptr (LFB) + int vram_pitch; + int vram_w; + int vram_h; + int bpp; // bytes per pixel + + // dosmemput path state (use_dosmemput) + Uint32 vram_phys; // base address for dosmemput (e.g. 0xA0000) + bool banked_multibank; // true if fb doesn't fit in one bank window + Uint32 win_gran_bytes; // bank granularity in bytes + Uint32 win_size_bytes; // bank window size in bytes + Uint32 win_base; // window base address (segment << 4) + Uint32 win_func_ptr; // real-mode far pointer to bank-switch function + + // nearptr path state (use_dosmemput == false) + Uint8 *vram_ptr; // nearptr into VRAM (LFB) + + // Cached per-frame values (set at create time, avoid repeated lookups) + Uint8 *pixels; // == surface->pixels (stable after create) + int src_pitch; // == surface->pitch + Uint32 fb_size; // total framebuffer bytes (pitch * h) for full-surface fast path + bool pitches_match; // src_pitch == vram_pitch (enables single-copy fast path) +} DOSFramebufferState; + +static DOSFramebufferState fb_state; + +// Convert cursor to the current format. +static SDL_Surface *GetConvertedCursorSurface(SDL_CursorData *curdata, SDL_Surface *dst) +{ + SDL_Palette *pal = SDL_GetSurfacePalette(dst); + if (!pal) { + return NULL; + } + + Uint32 pal_version = pal ? pal->version : 0; + + if (curdata->converted_surface && + curdata->converted_surface->format == dst->format && + curdata->converted_palette_version == pal_version) { + return curdata->converted_surface; + } + + SDL_DestroySurface(curdata->converted_surface); + curdata->converted_surface = NULL; + + SDL_Surface *src = curdata->surface; + SDL_assert(src->format == SDL_PIXELFORMAT_ARGB8888); + + int w = src->w; + int h = src->h; + SDL_Surface *conv = SDL_CreateSurface(w, h, dst->format); + if (!conv) { + return NULL; + } + + // Copy the destination palette. + SDL_Palette *conv_pal = SDL_CreateSurfacePalette(conv); + if (conv_pal) { + SDL_SetPaletteColors(conv_pal, pal->colors, 0, pal->ncolors); + } + + // Track which palette indices are used by opaque pixels. + bool used[256]; + SDL_memset(used, 0, sizeof(used)); + + // First pass: blit with BLENDMODE_NONE to get raw color-matched indices. + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); + SDL_BlitSurface(src, NULL, conv, NULL); + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND); + + // Mark which indices are used by non-transparent source pixels. + for (int y = 0; y < h; y++) { + const Uint32 *srcrow = (const Uint32 *)((const Uint8 *)src->pixels + y * src->pitch); + const Uint8 *convrow = (const Uint8 *)conv->pixels + y * conv->pitch; + for (int x = 0; x < w; x++) { + Uint8 srcA = (Uint8)(srcrow[x] >> 24); + if (srcA > 0) { + used[convrow[x]] = true; + } + } + } + + // Find an unused index for the colorkey. + Uint32 colorkey = 0; + for (int i = 0; i < 256; i++) { + if (!used[i]) { + colorkey = (Uint32)i; + break; + } + } + + // Second pass: set transparent pixels to the colorkey index. + for (int y = 0; y < h; y++) { + const Uint32 *srcrow = (const Uint32 *)((const Uint8 *)src->pixels + y * src->pitch); + Uint8 *convrow = (Uint8 *)conv->pixels + y * conv->pitch; + for (int x = 0; x < w; x++) { + Uint8 srcA = (Uint8)(srcrow[x] >> 24); + if (srcA == 0) { + convrow[x] = (Uint8)colorkey; + } + } + } + + SDL_SetSurfaceColorKey(conv, true, colorkey); + SDL_SetSurfaceBlendMode(conv, SDL_BLENDMODE_NONE); + + curdata->converted_surface = conv; + curdata->converted_palette_version = pal_version; + return conv; +} + +// Invalidation (called from SetDisplayMode before freeing DPMI mapping) +void DOSVESA_InvalidateCachedFramebuffer(void) +{ + fb_state.direct_fb = false; + fb_state.vram_ptr = NULL; + fb_state.vram_phys = 0; + fb_state.use_dosmemput = false; + // Clear the LFB surface pointer so UpdateWindowFramebuffer won't try + // to blit into VRAM after the DPMI mapping has been freed. + fb_state.lfb_surface = NULL; +} + +// Create a system-RAM surface (with a blank palette if INDEX8 and update the VGA DAC). +static SDL_Surface *CreateSystemSurface(SDL_VideoData *data, int w, int h, SDL_PixelFormat surface_format) +{ + SDL_Surface *surface = SDL_CreateSurface(w, h, surface_format); + if (!surface) { + return NULL; + } + + // For 8-bit indexed modes, both surfaces need palettes. + // Share the same palette object so palette updates propagate to both. + if (surface_format == SDL_PIXELFORMAT_INDEX8) { + SDL_Palette *palette = SDL_CreateSurfacePalette(surface); + if (palette) { + // Initialize palette to all-black so that transitions start + // from black instead of flashing uninitialized (white) colors. + SDL_Color black[256]; + SDL_memset(black, 0, sizeof(black)); + for (int i = 0; i < 256; i++) { + black[i].a = SDL_ALPHA_OPAQUE; + } + SDL_SetPaletteColors(palette, black, 0, 256); + } + data->palette_version = 0; // force DAC update on first present + + // Also program the VGA DAC to all-black right now, so no flash + // of stale/white palette colors before the first present. + outportb(VGA_DAC_WRITE_INDEX, 0); + for (int i = 0; i < 256; i++) { + outportb(VGA_DAC_DATA, 0); + outportb(VGA_DAC_DATA, 0); + outportb(VGA_DAC_DATA, 0); + } + } + + return surface; +} + +// Normal (non-direct-FB) path: system-RAM surface with optional LFB blit, +// cursor compositing, palette sync, vsync, and page-flipping. +static bool CreateNormalFramebuffer(SDL_VideoDevice *device, SDL_Window *window, + SDL_PixelFormat *format, void **pixels, int *pitch) +{ + SDL_VideoData *data = device->internal; + const SDL_DisplayMode *mode = &data->current_mode; + const SDL_DisplayModeData *mdata = mode->internal; + const SDL_PixelFormat surface_format = mode->format; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); + + SDL_Surface *surface = CreateSystemSurface(data, w, h, surface_format); + if (!surface) { + return false; + } + + SDL_Surface *lfb_surface = NULL; + + if (!data->banked_mode) { + // LFB path: Make a surface that uses video memory directly, ot let SDL do the blitting for us. + // Point the LFB surface at the back page for tear-free double-buffering. + int back_page = data->page_flip_available ? (1 - data->current_page) : 0; + void *lfb_pixels = (Uint8 *)DOS_PhysicalToLinear(data->mapping.address) + data->page_offset[back_page]; + lfb_surface = SDL_CreateSurfaceFrom(mode->w, mode->h, surface_format, lfb_pixels, mdata->pitch); + if (!lfb_surface) { + SDL_DestroySurface(surface); + return false; + } + fb_state.lfb_surface = lfb_surface; + + // Share the palette so updates propagate to both surfaces. + SDL_Palette *src_palette = SDL_GetSurfacePalette(surface); + if (src_palette) { + SDL_SetSurfacePalette(lfb_surface, src_palette); + } + } + + // clear the framebuffer completely, in case another window at a larger size was using this before us. + if (lfb_surface) { + SDL_ClearSurface(lfb_surface, 0.0f, 0.0f, 0.0f, 0.0f); + } + // (For banked mode, the framebuffer was already zeroed in DOSVESA_SetDisplayMode.) + + // Save the info and return! + fb_state.surface = surface; + SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), DOS_SURFACE, surface); + + *format = surface_format; + *pixels = surface->pixels; + *pitch = surface->pitch; + return true; +} + +bool DOSVESA_CreateWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch) +{ + SDL_zero(fb_state); + + SDL_VideoData *data = device->internal; + const SDL_DisplayMode *mode = &data->current_mode; + const SDL_DisplayModeData *mdata = mode->internal; + const SDL_PixelFormat surface_format = mode->format; + int w, h; + + // writing to video RAM shows up as the screen refreshes, done or not, and it might have a weird pitch, so give the app a buffer of system RAM. + SDL_GetWindowSizeInPixels(window, &w, &h); + + // Try to set up fast path where UpdateWindowFramebuffer copies system-RAM directly to VRAM. + if (SDL_GetHintBoolean(SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER, false)) { + int vram_pitch = mdata->pitch; + + // Check if we have any usable VRAM access path (banked or LFB). + bool have_vram = false; + + if (mdata->win_a_segment && mdata->win_size > 0 && + (mdata->win_a_attributes & VBE_WINATTR_USABLE) == VBE_WINATTR_USABLE) { + // Banked window available. Use dosmemput path (preferred). + have_vram = true; + } else if (!data->banked_mode && data->mapping.size) { + // LFB only, use nearptr fallback. + have_vram = true; + } + + if (have_vram) { + SDL_Surface *surface = CreateSystemSurface(data, w, h, surface_format); + if (!surface) { + return false; + } + + SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), DOS_SURFACE, surface); + + fb_state.surface = surface; + fb_state.direct_fb = true; + fb_state.vram_pitch = vram_pitch; + fb_state.vram_w = mdata->w; + fb_state.vram_h = mdata->h; + fb_state.bpp = SDL_BYTESPERPIXEL(surface_format); + fb_state.pixels = (Uint8 *)surface->pixels; + fb_state.src_pitch = surface->pitch; + fb_state.fb_size = (Uint32)vram_pitch * mdata->h; + fb_state.pitches_match = (surface->pitch == vram_pitch); + + // Prefer dosmemput via the banked VGA window (0xA0000). Real + // hardware testing shows dosmemput is significantly faster + // than nearptr writes to DPMI-mapped LFB, even with bank + // switching overhead at higher resolutions. + // + // The banked window always maps to page 0, so page flipping is + // not possible through this path. We accept tearing: the app + // opted into the direct-FB hint for maximum throughput, and + // games like Quake never used page flipping for their software + // renderers anyway. + if (mdata->win_a_segment && mdata->win_size > 0 && + (mdata->win_a_attributes & VBE_WINATTR_USABLE) == VBE_WINATTR_USABLE) { + Uint32 win_bytes = (Uint32)mdata->win_size * 1024; + fb_state.use_dosmemput = true; + fb_state.vram_ptr = NULL; + fb_state.vram_phys = (Uint32)mdata->win_a_segment << 4; + fb_state.win_base = fb_state.vram_phys; + fb_state.win_gran_bytes = (Uint32)mdata->win_granularity * 1024; + fb_state.win_size_bytes = win_bytes; + fb_state.win_func_ptr = mdata->win_func_ptr; + fb_state.banked_multibank = (fb_state.fb_size > win_bytes); + } else if (!data->banked_mode && data->mapping.size) { + // Fallback: nearptr to LFB. + int back_page = data->page_flip_available ? (1 - data->current_page) : 0; + fb_state.vram_ptr = (Uint8 *)DOS_PhysicalToLinear(data->mapping.address) + data->page_offset[back_page]; + fb_state.vram_phys = 0; + fb_state.use_dosmemput = false; + fb_state.banked_multibank = false; + } else { + // No usable VRAM path. Shouldn't happen, but bail out. + SDL_DestroySurface(surface); + return CreateNormalFramebuffer(device, window, format, pixels, pitch); + } + *format = surface_format; + *pixels = surface->pixels; + *pitch = surface->pitch; + return true; + } + // else: couldn't get a direct pointer, fall through to normal path. + } + + return CreateNormalFramebuffer(device, window, format, pixels, pitch); +} + +bool DOSVESA_SetWindowFramebufferVSync(SDL_VideoDevice *device, SDL_Window *window, int vsync) +{ + if (vsync < 0) { + return SDL_SetError("Unsupported vsync type"); + } + SDL_WindowData *data = window->internal; + data->framebuffer_vsync = vsync; + return true; +} + +bool DOSVESA_GetWindowFramebufferVSync(SDL_VideoDevice *device, SDL_Window *window, int *vsync) +{ + if (vsync) { + SDL_WindowData *data = window->internal; + *vsync = data->framebuffer_vsync; + } + return true; +} + +// Switch the VGA bank window if needed. Returns without doing anything +// if the requested bank is already active. +SDL_FORCE_INLINE void SwitchBank(int bank, int *current_bank, Uint32 win_func_ptr) +{ + if (bank == *current_bank) { + return; + } + __dpmi_regs regs; + SDL_zero(regs); + regs.x.bx = 0; // Window A + regs.x.dx = (Uint16)bank; + if (win_func_ptr) { + regs.x.cs = (Uint16)(win_func_ptr >> 16); + regs.x.ip = (Uint16)(win_func_ptr & 0xFFFF); + __dpmi_simulate_real_mode_procedure_retf(®s); + } else { + regs.x.ax = 0x4F05; + __dpmi_int(0x10, ®s); + } + *current_bank = bank; +} + +// Copy a contiguous byte range from system RAM to VRAM through the banked +// window, switching banks as needed. +SDL_FORCE_INLINE void BankedDosmemput(const Uint8 *src, Uint32 total_bytes, Uint32 dst_offset, + Uint32 win_gran_bytes, Uint32 win_size_bytes, + Uint32 win_base, Uint32 win_func_ptr, + int *current_bank) +{ + Uint32 src_off = 0; + while (total_bytes > 0) { + int bank = (int)(dst_offset / win_gran_bytes); + Uint32 off_in_win = dst_offset % win_gran_bytes; + Uint32 avail = win_size_bytes - off_in_win; + Uint32 n = total_bytes; + if (n > avail) { + n = avail; + } + SwitchBank(bank, current_bank, win_func_ptr); + dosmemput(src + src_off, n, win_base + off_in_win); + src_off += n; + dst_offset += n; + total_bytes -= n; + } +} + +// Bank-switched copy of a rectangular region from a system RAM surface to the +// VGA banked window. `src_rect` is in source-surface coordinates; `dst_x` and +// `dst_y` give the top-left of the *surface's* position on screen (the +// centering offset). The routine handles bank boundaries correctly even when a +// scanline spans two banks. +// +// `current_bank` is an in/out parameter so that consecutive calls (one per dirty +// rect) can avoid redundant bank switches when rects happen to fall in the same +// bank. Initialise it to -1 before the first call. +static void BankedFramebufferCopyRect(const SDL_DisplayModeData *mdata, + const SDL_Surface *src, + const SDL_Rect *src_rect, + int dst_x, int dst_y, + Uint32 win_gran_bytes, + Uint32 win_size_bytes, + Uint32 win_base, + int *current_bank, + Uint32 win_func_ptr) +{ + const Uint16 dst_pitch = mdata->pitch; + const int bytes_per_pixel = SDL_BYTESPERPIXEL(src->format); + const int row_bytes = src_rect->w * bytes_per_pixel; + + // Fast path: if the source row width matches src pitch AND the destination + // row width matches dst pitch, the data is contiguous in both source and + // destination — we can copy it as one flat block, minimizing dosmemput calls. + if (row_bytes == src->pitch && row_bytes == dst_pitch) { + const Uint8 *src_data = (const Uint8 *)src->pixels + src_rect->y * src->pitch + src_rect->x * bytes_per_pixel; + Uint32 dst_offset = (Uint32)(dst_y + src_rect->y) * dst_pitch + (Uint32)(dst_x + src_rect->x) * bytes_per_pixel; + BankedDosmemput(src_data, (Uint32)(row_bytes * src_rect->h), dst_offset, + win_gran_bytes, win_size_bytes, win_base, win_func_ptr, current_bank); + return; + } + + for (int y = 0; y < src_rect->h; y++) { + const Uint8 *src_row = (const Uint8 *)src->pixels + (src_rect->y + y) * src->pitch + src_rect->x * bytes_per_pixel; + Uint32 dst_offset = (Uint32)(dst_y + src_rect->y + y) * dst_pitch + (Uint32)(dst_x + src_rect->x) * bytes_per_pixel; + BankedDosmemput(src_row, (Uint32)row_bytes, dst_offset, + win_gran_bytes, win_size_bytes, win_base, win_func_ptr, current_bank); + } +} + +static void WaitForVBlank(void) +{ + while (inportb(VGA_STATUS_PORT) & VGA_STATUS_VBLANK) { + SDL_CPUPauseInstruction(); + } + while (!(inportb(VGA_STATUS_PORT) & VGA_STATUS_VBLANK)) { + SDL_CPUPauseInstruction(); + } +} + +static void ProgramVGADAC(SDL_Palette *palette) +{ + outportb(VGA_DAC_WRITE_INDEX, 0); + for (int i = 0; i < palette->ncolors && i < 256; i++) { + outportb(VGA_DAC_DATA, palette->colors[i].r >> 2); + outportb(VGA_DAC_DATA, palette->colors[i].g >> 2); + outportb(VGA_DAC_DATA, palette->colors[i].b >> 2); + } +} + +bool DOSVESA_UpdateWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + SDL_VideoData *vdata = device->internal; + + // =================================================================== + // Direct-FB fast path: copy system-RAM to VRAM, program palette, + // optionally page-flip. No cursor compositing, no SDL_BlitSurface. + // + // This path prefers banked dosmemput (through the VGA window at + // 0xA0000) over nearptr writes to the DPMI-mapped LFB. Real + // hardware testing on multiple NVIDIA cards showed dosmemput is + // significantly faster, even with bank-switching overhead at + // higher resolutions. The nearptr LFB path is only used as a + // fallback if no usable banked window is available. + // =================================================================== + if (fb_state.direct_fb && (fb_state.vram_ptr || fb_state.vram_phys)) { + + // Palette update. + if (window->surface) { + SDL_Palette *pal = window->surface->palette; + if (pal && pal->version != vdata->palette_version) { + vdata->palette_version = pal->version; + ProgramVGADAC(pal); + } + } + + if (fb_state.use_dosmemput) { + // dosmemput path (banked window, possibly multi-bank) + const int src_pitch = fb_state.src_pitch; + const int dst_pitch = fb_state.vram_pitch; + const Uint8 *pixels = fb_state.pixels; + + if (!fb_state.banked_multibank) { + // Single-bank: entire FB fits in one window (e.g. mode 13h). + // Full-surface fast path when pitches match. + if (fb_state.pitches_match) { + dosmemput(pixels, fb_state.fb_size, fb_state.vram_phys); + } else { + for (int i = 0; i < numrects; i++) { + int rx = rects[i].x, ry = rects[i].y; + int rw = rects[i].w, rh = rects[i].h; + if (rx < 0) { + rw += rx; + rx = 0; + } + if (ry < 0) { + rh += ry; + ry = 0; + } + if (rx + rw > fb_state.vram_w) { + rw = fb_state.vram_w - rx; + } + if (ry + rh > fb_state.vram_h) { + rh = fb_state.vram_h - ry; + } + if (rw <= 0 || rh <= 0) { + continue; + } + const int bx = rx * fb_state.bpp; + const int bw = rw * fb_state.bpp; + const Uint8 *sp = pixels + ry * src_pitch + bx; + Uint32 dst_off = fb_state.vram_phys + ry * dst_pitch + bx; + for (int row = 0; row < rh; row++) { + dosmemput(sp, bw, dst_off); + sp += src_pitch; + dst_off += dst_pitch; + } + } + } + } else { + // Multi-bank: bank-switch as needed. + const Uint32 gran = fb_state.win_gran_bytes; + const Uint32 wsize = fb_state.win_size_bytes; + const Uint32 wbase = fb_state.win_base; + const Uint32 wfunc = fb_state.win_func_ptr; + int current_bank = -1; + + if (fb_state.pitches_match) { + // Contiguous: stream the entire framebuffer through banks. + BankedDosmemput(pixels, fb_state.fb_size, 0, + gran, wsize, wbase, wfunc, ¤t_bank); + } else { + // Per-rect with bank switching. + for (int i = 0; i < numrects; i++) { + int rx = rects[i].x, ry = rects[i].y; + int rw = rects[i].w, rh = rects[i].h; + if (rx < 0) { + rw += rx; + rx = 0; + } + if (ry < 0) { + rh += ry; + ry = 0; + } + if (rx + rw > fb_state.vram_w) { + rw = fb_state.vram_w - rx; + } + if (ry + rh > fb_state.vram_h) { + rh = fb_state.vram_h - ry; + } + if (rw <= 0 || rh <= 0) { + continue; + } + const int bx = rx * fb_state.bpp; + const int bw = rw * fb_state.bpp; + + for (int row = 0; row < rh; row++) { + const Uint8 *sp = pixels + (ry + row) * src_pitch + bx; + Uint32 dst_offset = (Uint32)(ry + row) * dst_pitch + bx; + BankedDosmemput(sp, (Uint32)bw, dst_offset, + gran, wsize, wbase, wfunc, ¤t_bank); + } + } + } + } + } else { + // nearptr path (LFB fallback) + if (fb_state.pitches_match) { + SDL_memcpy(fb_state.vram_ptr, fb_state.pixels, fb_state.fb_size); + } else { + const int bpp = fb_state.bpp; + const int src_pitch = fb_state.src_pitch; + const int dst_pitch = fb_state.vram_pitch; + const Uint8 *pixels = fb_state.pixels; + + for (int i = 0; i < numrects; i++) { + int rx = rects[i].x, ry = rects[i].y; + int rw = rects[i].w, rh = rects[i].h; + if (rx < 0) { + rw += rx; + rx = 0; + } + if (ry < 0) { + rh += ry; + ry = 0; + } + if (rx + rw > fb_state.vram_w) { + rw = fb_state.vram_w - rx; + } + if (ry + rh > fb_state.vram_h) { + rh = fb_state.vram_h - ry; + } + if (rw <= 0 || rh <= 0) { + continue; + } + const int bw = rw * bpp; + const Uint8 *sp = pixels + ry * src_pitch + rx * bpp; + Uint8 *dp = fb_state.vram_ptr + ry * dst_pitch + rx * bpp; + for (int row = 0; row < rh; row++) { + SDL_memcpy(dp, sp, bw); + sp += src_pitch; + dp += dst_pitch; + } + } + } + } + + // Page flipping is only used with the nearptr LFB path. The banked + // dosmemput path always writes to page 0 (the visible page) and + // accepts tearing, avoiding a BIOS call. + if (!fb_state.use_dosmemput && vdata->page_flip_available) { + const SDL_DisplayModeData *mdata = vdata->current_mode.internal; + int back_page = 1 - vdata->current_page; + Uint16 first_scanline = (Uint16)(vdata->page_offset[back_page] / mdata->pitch); + + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x4F07; + regs.x.bx = 0x0080; + regs.x.cx = 0; + regs.x.dx = first_scanline; + __dpmi_int(0x10, ®s); + + vdata->current_page = back_page; + + int new_back = 1 - vdata->current_page; + fb_state.vram_ptr = (Uint8 *)DOS_PhysicalToLinear(vdata->mapping.address) + vdata->page_offset[new_back]; + } + + return true; + } + + // =================================================================== + // Normal path: system-RAM to LFB surface (or banked copy) + // with cursor compositing, palette sync, vsync, and page-flipping. + // =================================================================== + + SDL_Surface *src = fb_state.surface; + if (!src) { + src = (SDL_Surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), DOS_SURFACE, NULL); + } + if (!src) { + return SDL_SetError("Couldn't find DOS surface for window"); + } + + const SDL_DisplayModeData *mdata = vdata->current_mode.internal; + SDL_WindowData *windata = window->internal; + + // For 8-bit indexed modes, sync palette data between surfaces so the + // blit uses the correct color mapping. The actual VGA DAC programming + // is deferred until vertical blanking to avoid visible palette flicker. + SDL_Palette *dac_palette = NULL; + bool dac_needs_update = false; + + if (src->format == SDL_PIXELFORMAT_INDEX8) { + SDL_Palette *win_palette = window->surface ? SDL_GetSurfacePalette(window->surface) : NULL; + SDL_Palette *src_palette = SDL_GetSurfacePalette(src); + + // Sync: if the app set colors on the window surface palette, + // copy them to the internal surface so the blit works correctly. + if (win_palette && src_palette && win_palette != src_palette && + win_palette->version != src_palette->version) { + SDL_SetPaletteColors(src_palette, win_palette->colors, 0, + SDL_min(win_palette->ncolors, src_palette->ncolors)); + + if (!vdata->banked_mode && fb_state.lfb_surface) { + // Also update the LFB surface palette for correct blitting + SDL_Palette *dst_palette = SDL_GetSurfacePalette(fb_state.lfb_surface); + if (dst_palette && dst_palette != src_palette) { + SDL_SetPaletteColors(dst_palette, win_palette->colors, 0, + SDL_min(win_palette->ncolors, dst_palette->ncolors)); + } + } + } + + // Determine whether the VGA DAC needs reprogramming. + dac_palette = win_palette ? win_palette : src_palette; + if (dac_palette && dac_palette->version != vdata->palette_version) { + dac_needs_update = true; + } + } + + if (vdata->banked_mode) { + // --- Banked framebuffer path (dirty-rect aware) --- + // We composite the cursor onto the source surface (in system RAM), + // then bank-copy only the dirty rectangles to the VGA window. We + // need to undo the cursor composite afterwards so the app's surface + // isn't permanently modified. + + const int dst_x = ((int)mdata->w - src->w) / 2; + const int dst_y = ((int)mdata->h - src->h) / 2; + + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Surface *cursor = NULL; + SDL_Rect cursorrect; + SDL_Rect cursor_clipped; // cursorrect clipped to src bounds + SDL_Surface *cursor_save = NULL; + bool have_cursor_rect = false; + + SDL_Cursor *cur = mouse ? mouse->cur_cursor : NULL; + if (cur && cur->animation) { + cur = cur->animation->frames[cur->animation->current_frame]; + } + if (mouse && mouse->internal && !mouse->relative_mode && mouse->cursor_visible && cur && cur->internal) { + cursor = cur->internal->surface; + if (cursor) { + cursorrect.x = SDL_clamp((int)mouse->x, 0, window->w) - cur->internal->hot_x; + cursorrect.y = SDL_clamp((int)mouse->y, 0, window->h) - cur->internal->hot_y; + cursorrect.w = cursor->w; + cursorrect.h = cursor->h; + + // Clip cursor rect to src bounds for save/restore. + cursor_clipped = cursorrect; + if (cursor_clipped.x < 0) { + cursor_clipped.w += cursor_clipped.x; + cursor_clipped.x = 0; + } + if (cursor_clipped.y < 0) { + cursor_clipped.h += cursor_clipped.y; + cursor_clipped.y = 0; + } + if (cursor_clipped.x + cursor_clipped.w > src->w) { + cursor_clipped.w = src->w - cursor_clipped.x; + } + if (cursor_clipped.y + cursor_clipped.h > src->h) { + cursor_clipped.h = src->h - cursor_clipped.y; + } + + if (cursor_clipped.w > 0 && cursor_clipped.h > 0) { + have_cursor_rect = true; + + // Save the pixels under the cursor so we can restore them after the copy. + cursor_save = SDL_CreateSurface(cursor_clipped.w, cursor_clipped.h, src->format); + if (cursor_save) { + if (src->format == SDL_PIXELFORMAT_INDEX8) { + SDL_Palette *sp = SDL_GetSurfacePalette(src); + if (sp) { + SDL_SetSurfacePalette(cursor_save, sp); + } + } + SDL_BlitSurface(src, &cursor_clipped, cursor_save, NULL); + } + } + + // Composite cursor onto the source surface. + { + SDL_Surface *blit_cursor = GetConvertedCursorSurface(cur->internal, src); + SDL_BlitSurface(blit_cursor ? blit_cursor : cursor, NULL, src, &cursorrect); + } + } + } + + // Wait for vsync before the copy to reduce tearing. + const int vsync_interval = windata->framebuffer_vsync; + if (vsync_interval > 0 || dac_needs_update) { + WaitForVBlank(); + } + + if (dac_needs_update) { + vdata->palette_version = dac_palette->version; + ProgramVGADAC(dac_palette); + } + + // Bank-switched copy of only the dirty rectangles. + // Pre-compute constants shared across all rect copies. + const Uint32 win_gran_bytes = (Uint32)mdata->win_granularity * 1024; + const Uint32 win_size_bytes = (Uint32)mdata->win_size * 1024; + const Uint32 win_base = (Uint32)mdata->win_a_segment << 4; + int current_bank = -1; + + // Track whether the cursor region was already covered by a dirty rect + // so we don't copy it twice. + bool cursor_covered = false; + + for (int r = 0; r < numrects; r++) { + // Clip the dirty rect to the source surface bounds. + SDL_Rect rect = rects[r]; + if (rect.x < 0) { + rect.w += rect.x; + rect.x = 0; + } + if (rect.y < 0) { + rect.h += rect.y; + rect.y = 0; + } + if (rect.x + rect.w > src->w) { + rect.w = src->w - rect.x; + } + if (rect.y + rect.h > src->h) { + rect.h = src->h - rect.y; + } + if (rect.w <= 0 || rect.h <= 0) { + continue; + } + + // If the cursor is visible, check whether this rect fully covers it. + if (have_cursor_rect && !cursor_covered) { + if (rect.x <= cursor_clipped.x && + rect.y <= cursor_clipped.y && + rect.x + rect.w >= cursor_clipped.x + cursor_clipped.w && + rect.y + rect.h >= cursor_clipped.y + cursor_clipped.h) { + cursor_covered = true; + } + } + + BankedFramebufferCopyRect(mdata, src, &rect, dst_x, dst_y, + win_gran_bytes, win_size_bytes, win_base, + ¤t_bank, mdata->win_func_ptr); + } + + // If no dirty rect covered the cursor, copy the cursor region separately. + if (have_cursor_rect && !cursor_covered) { + BankedFramebufferCopyRect(mdata, src, &cursor_clipped, dst_x, dst_y, + win_gran_bytes, win_size_bytes, win_base, + ¤t_bank, mdata->win_func_ptr); + } + + // Restore the source surface pixels under the cursor. + if (cursor_save) { + SDL_Rect restore_rect = cursor_clipped; + SDL_BlitSurface(cursor_save, NULL, src, &restore_rect); + SDL_DestroySurface(cursor_save); + } + + } else { + // --- LFB path --- + SDL_Surface *dst = fb_state.lfb_surface; + if (!dst) { + return SDL_SetError("Couldn't find VESA linear framebuffer surface for window"); + } + + const SDL_Rect dstrect = { (dst->w - src->w) / 2, (dst->h - src->h) / 2, src->w, src->h }; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Surface *cursor = NULL; + SDL_Rect cursorrect; + + SDL_Cursor *cur = mouse ? mouse->cur_cursor : NULL; + if (cur && cur->animation) { + cur = cur->animation->frames[cur->animation->current_frame]; + } + if (mouse && mouse->internal && !mouse->relative_mode && mouse->cursor_visible && cur && cur->internal) { + cursor = cur->internal->surface; + if (cursor) { + cursorrect.x = dstrect.x + SDL_clamp((int)mouse->x, 0, window->w) - cur->internal->hot_x; + cursorrect.y = dstrect.y + SDL_clamp((int)mouse->y, 0, window->h) - cur->internal->hot_y; + } + } + + // If both surfaces are INDEX8 and same size, skip the SDL blit + // machinery (which does per-pixel palette remapping even for + // identical palettes), copy directly to the LFB surface using + // SDL_memcpy. + if (src->format == SDL_PIXELFORMAT_INDEX8 && + dst->format == SDL_PIXELFORMAT_INDEX8 && + src->w == dstrect.w && src->h == dstrect.h) { + const Uint8 *sp = (const Uint8 *)src->pixels; + Uint8 *dp = (Uint8 *)dst->pixels + dstrect.y * dst->pitch + dstrect.x; + if (src->pitch == dstrect.w && dst->pitch == dstrect.w) { + SDL_memcpy(dp, sp, (size_t)dstrect.w * dstrect.h); + } else { + for (int row = 0; row < dstrect.h; row++) { + SDL_memcpy(dp, sp, dstrect.w); + sp += src->pitch; + dp += dst->pitch; + } + } + } else { + // Blit to the back page (or the only page, if no page-flipping) + if (!SDL_BlitSurface(src, NULL, dst, &dstrect)) { + return false; + } + } + + if (cursor) { + SDL_Surface *blit_cursor = GetConvertedCursorSurface(cur->internal, dst); + if (!SDL_BlitSurface(blit_cursor ? blit_cursor : cursor, NULL, dst, &cursorrect)) { + return false; + } + } + + if (vdata->page_flip_available) { + // Page-flip with optional vsync. + const int vsync_interval = windata->framebuffer_vsync; + int back_page = 1 - vdata->current_page; + Uint16 first_scanline = (Uint16)(vdata->page_offset[back_page] / mdata->pitch); + + if (vsync_interval > 0 || dac_needs_update) { + // Wait for vblank so the flip and DAC update appear together. + WaitForVBlank(); + } + + if (dac_needs_update) { + vdata->palette_version = dac_palette->version; + ProgramVGADAC(dac_palette); + } + + // Flip: make the back page (which we just drew to) the visible page. + // Always use subfunction 0x0080 (set display start, don't wait) — + // vsync is controlled by our manual vblank wait above. + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x4F07; + regs.x.bx = 0x0080; + regs.x.cx = 0; // first pixel in scan line + regs.x.dx = first_scanline; + __dpmi_int(0x10, ®s); + + vdata->current_page = back_page; + + // Update LFB surface to point at the new back page (the old front page) + int new_back = 1 - vdata->current_page; + dst->pixels = (Uint8 *)DOS_PhysicalToLinear(vdata->mapping.address) + vdata->page_offset[new_back]; + } else { + // No page-flipping: wait for vsync, then update DAC atomically + const int vsync_interval = windata->framebuffer_vsync; + if (vsync_interval > 0 || dac_needs_update) { + WaitForVBlank(); + } + + if (dac_needs_update) { + vdata->palette_version = dac_palette->version; + ProgramVGADAC(dac_palette); + } + } + } + + return true; +} + +void DOSVESA_DestroyWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window) +{ + // Note: we intentionally do NOT call SDL_ClearSurface on the LFB surface + // here. SetDisplayMode already blanks the framebuffer (both pages) when + // setting a new mode, and the LFB surface's pixels pointer may be stale + // if the DPMI mapping was freed before this function is called. + (void)device; + SDL_zero(fb_state); + SDL_ClearProperty(SDL_GetWindowProperties(window), DOS_SURFACE); +} + +#endif // SDL_VIDEO_DRIVER_DOSVESA diff --git a/src/video/dos/SDL_dosframebuffer_c.h b/src/video/dos/SDL_dosframebuffer_c.h new file mode 100644 index 0000000000..9fdbcb2a76 --- /dev/null +++ b/src/video/dos/SDL_dosframebuffer_c.h @@ -0,0 +1,34 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dosframebuffer_c_h_ +#define SDL_dosframebuffer_c_h_ + +#include "SDL_internal.h" + +extern bool DOSVESA_CreateWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch); +extern bool DOSVESA_UpdateWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void DOSVESA_DestroyWindowFramebuffer(SDL_VideoDevice *device, SDL_Window *window); +extern bool DOSVESA_SetWindowFramebufferVSync(SDL_VideoDevice *device, SDL_Window *window, int vsync); +extern bool DOSVESA_GetWindowFramebufferVSync(SDL_VideoDevice *device, SDL_Window *window, int *vsync); +extern void DOSVESA_InvalidateCachedFramebuffer(void); + +#endif // SDL_dosframebuffer_c_h_ diff --git a/src/video/dos/SDL_dosmodes.c b/src/video/dos/SDL_dosmodes.c new file mode 100644 index 0000000000..2976caf8c9 --- /dev/null +++ b/src/video/dos/SDL_dosmodes.c @@ -0,0 +1,688 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_DOSVESA + +// SDL internals +#include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_dosframebuffer_c.h" + +// DOS declarations +#include "SDL_dosmodes.h" +#include "SDL_dosvideo.h" +#include // for dosmemput (banked framebuffer access) + +// Some VESA usage information: +// https://delorie.com/djgpp/doc/ug/graphics/vesa.html.en +// https://delorie.com/djgpp/doc/ug/graphics/vbe20.html +// https://wiki.osdev.org/User:Omarrx024/VESA_Tutorial +// https://wiki.osdev.org/VESA_Video_Modes +// https://www.phatcode.net/res/221/files/vbe20.pdf + +// VBE mode attribute bits (ModeAttributes field) +#define VBE_MODEATTR_SUPPORTED 0x01 // bit 0: mode supported in hardware +#define VBE_MODEATTR_COLOR 0x08 // bit 3: color mode (vs. monochrome) +#define VBE_MODEATTR_GRAPHICS 0x10 // bit 4: graphics mode (vs. text) +#define VBE_MODEATTR_LFB 0x80 // bit 7: linear framebuffer available + +// Minimum required mode attributes for usable graphics modes +#define VBE_MODEATTR_REQUIRED (VBE_MODEATTR_SUPPORTED | VBE_MODEATTR_COLOR | VBE_MODEATTR_GRAPHICS) + +// VBE memory model types (MemoryModel field) +#define VBE_MEMMODEL_PACKED_PIXEL 4 // packed pixel (includes 8-bit indexed) +#define VBE_MEMMODEL_DIRECT_COLOR 6 // direct color (RGB with masks) + +// VBE set-mode flag +#define VBE_SETMODE_LFB 0x4000 // request linear framebuffer when setting mode + +// VBE mode list sentinel +#define VBE_MODELIST_END 0xFFFF + +// VGA mode 13h (320x200x256) is universally supported, but most VESA +// BIOSes do not include it in their VESA mode list. This sentinel +// value is used to identify the legacy fallback. +#define VGA_MODE_13H_SENTINEL 0xFFEE +#define VGA_MODE_13H_SEGMENT 0xA000 + +#pragma pack(push, 1) +// this is the struct from the hardware; we save only a few parts from this, later, in SDL_VESAInfo. +typedef struct SDL_VESAHardwareInfo +{ + Uint8 VESASignature[4]; + Uint16 VESAVersion; + Uint32 OEMStringPtr; // segment:offset + Uint8 Capabilities[4]; + Uint32 VideoModePtr; // segment:offset + Uint16 TotalMemory; + Uint16 OEMSoftwareRev; + Uint32 OEMVendorNamePtr; // segment:offset + Uint32 OEMProductNamePtr; // segment:offset + Uint32 OEMProductRevPtr; // segment:offset + Uint8 Reserved[222]; + Uint8 OemData[256]; +} SDL_VESAHardwareInfo; + +typedef struct SDL_VESAModeHardwareInfo +{ + Uint16 ModeAttributes; + Uint8 WinAAttributes; + Uint8 WinBAttributes; + Uint16 WinGranularity; + Uint16 WinSize; + Uint16 WinASegment; + Uint16 WinBSegment; + Uint32 WinFuncPtr; + Uint16 BytesPerScanLine; + Uint16 XResolution; + Uint16 YResolution; + Uint8 XCharSize; + Uint8 YCharSize; + Uint8 NumberOfPlanes; + Uint8 BitsPerPixel; + Uint8 NumberOfBanks; + Uint8 MemoryModel; + Uint8 BankSize; + Uint8 NumberOfImagePages; + Uint8 Reserved_page; + Uint8 RedMaskSize; + Uint8 RedMaskPos; + Uint8 GreenMaskSize; + Uint8 GreenMaskPos; + Uint8 BlueMaskSize; + Uint8 BlueMaskPos; + Uint8 ReservedMaskSize; + Uint8 ReservedMaskPos; + Uint8 DirectColorModeInfo; + Uint32 PhysBasePtr; + Uint32 OffScreenMemOffset; + Uint16 OffScreenMemSize; + Uint8 Reserved[206]; +} SDL_VESAModeHardwareInfo; +#pragma pack(pop) + +typedef struct SDL_VESAInfo +{ + Uint16 version; // 0x200 == 2.0, etc. + Uint32 total_memory; // in bytes (SDL_VESAHardwareInfo::TotalMemory does it in 64k pages). + Uint32 video_addr_segoffset; // real mode segment:offset (only valid while VBE info block is allocated!) + Uint16 *mode_list; // copied out of conventional memory before freeing + int num_modes; + Uint16 oem_software_revision; + char *oem_string; + char *oem_vendor; + char *oem_product; + char *oem_revision; +} SDL_VESAInfo; + +static SDL_VESAInfo *vesa_info = NULL; + +void DOSVESA_FreeVESAInfo(void) +{ + if (vesa_info) { + SDL_free(vesa_info->mode_list); + SDL_free(vesa_info->oem_string); + SDL_free(vesa_info->oem_vendor); + SDL_free(vesa_info->oem_product); + SDL_free(vesa_info->oem_revision); + SDL_free(vesa_info); + vesa_info = NULL; + } +} + +static const SDL_VESAInfo *GetVESAInfo(void) +{ + if (vesa_info) { + return vesa_info; + } + + _go32_dpmi_seginfo hwinfo_seginfo; + SDL_VESAHardwareInfo *hwinfo = (SDL_VESAHardwareInfo *)DOS_AllocateConventionalMemory(sizeof(*hwinfo), &hwinfo_seginfo); + if (!hwinfo) { + return NULL; + } + + SDL_zerop(hwinfo); + SDL_memcpy(hwinfo->VESASignature, "VBE2", 4); + + __dpmi_regs regs; + regs.x.ax = 0x4F00; + regs.x.es = DOS_LinearToPhysical(hwinfo) / 16; + regs.x.di = DOS_LinearToPhysical(hwinfo) & 0xF; + __dpmi_int(0x10, ®s); + + // al is 0x4F if VESA is supported, ah is 0x00 if this specific call succeeded. + // If the interrupt call didn't replace VESASignature with "VESA" then something went wrong, too. + if ((regs.x.ax != 0x004F) || (SDL_memcmp(hwinfo->VESASignature, "VESA", 4) != 0)) { + SDL_SetError("VESA video not supported on this system"); + } else { + vesa_info = (SDL_VESAInfo *)SDL_calloc(1, sizeof(*vesa_info)); + if (vesa_info) { + vesa_info->version = hwinfo->VESAVersion; + vesa_info->total_memory = ((Uint32)hwinfo->TotalMemory) * (64 * 1024); // TotalMemory is 64k chunks, convert to bytes. + vesa_info->video_addr_segoffset = hwinfo->VideoModePtr; + vesa_info->oem_software_revision = hwinfo->OEMSoftwareRev; + // these strings are often empty (or maybe NULL), but it's fine. We don't _actually_ need them. + vesa_info->oem_string = DOS_GetFarPtrCString(hwinfo->OEMStringPtr); + vesa_info->oem_vendor = DOS_GetFarPtrCString(hwinfo->OEMVendorNamePtr); + vesa_info->oem_product = DOS_GetFarPtrCString(hwinfo->OEMProductNamePtr); + vesa_info->oem_revision = DOS_GetFarPtrCString(hwinfo->OEMProductRevPtr); + + // Copy the mode list out of conventional memory BEFORE freeing + // the VBE info block. Some VESA BIOSes store the mode list + // inside the 512-byte info block itself. If we free the block + // first, the mode list pointer becomes dangling and we read + // garbage, silently losing modes. + { + Uint32 segoffset = vesa_info->video_addr_segoffset; + int count = 0; + while (DOS_PeekUint16(segoffset + count * sizeof(Uint16)) != VBE_MODELIST_END) { + count++; + if (count > 64) + break; // sanity limit + } + vesa_info->num_modes = count; + vesa_info->mode_list = (Uint16 *)SDL_malloc(count * sizeof(Uint16)); + if (vesa_info->mode_list) { + for (int i = 0; i < count; i++) { + vesa_info->mode_list[i] = DOS_PeekUint16(segoffset + i * sizeof(Uint16)); + } + } else { + vesa_info->num_modes = 0; + } + } + } + } + + DOS_FreeConventionalMemory(&hwinfo_seginfo); + + return vesa_info; +} + +// Test by writing and reading back the DAC Pixel Mask register +// On VGA this is a read/write register, on EGA/CGA the port either +// doesn't exist (reads 0xFF) or isn't writable. +static bool DetectVGA(void) +{ + const Uint8 original = inportb(VGA_DAC_PIXEL_MASK); + outportb(VGA_DAC_PIXEL_MASK, 0xA5); + (void)inportb(0x80); // small I/O delay + const Uint8 readback = inportb(VGA_DAC_PIXEL_MASK); + outportb(VGA_DAC_PIXEL_MASK, original); + + return (readback == 0xA5); +} + +bool DOSVESA_SupportsVESA(void) +{ + // We need at least VGA hardware (for mode 13h). EGA and CGA cards + // do not support 256 colors or programmable palettes. + if (!DetectVGA()) { + return SDL_SetError("No VGA card detected"); + } + + // Cache VESA info if available (NULL mean we only have VGA). + (void)GetVESAInfo(); + + return true; +} + +const char *DOSVESA_GetGPUName(void) +{ + const SDL_VESAInfo *vinfo = GetVESAInfo(); + if (!vinfo) { + return "VGA"; + } + + if (vinfo->oem_product && *vinfo->oem_product) { + return vinfo->oem_product; + } + if (vinfo->oem_vendor && *vinfo->oem_vendor) { + return vinfo->oem_vendor; + } + if (vinfo->oem_string && *vinfo->oem_string) { + return vinfo->oem_string; + } + + return "VESA"; +} + +Uint32 DOSVESA_GetVESATotalMemory(void) +{ + const SDL_VESAInfo *info = GetVESAInfo(); + return info ? info->total_memory : 0; +} + +static bool GetVESAModeInfo(Uint16 mode_id, SDL_DisplayModeData *info) +{ + _go32_dpmi_seginfo hwinfo_seginfo; + SDL_VESAModeHardwareInfo *hwinfo = (SDL_VESAModeHardwareInfo *)DOS_AllocateConventionalMemory(sizeof(*hwinfo), &hwinfo_seginfo); + if (!hwinfo) { + return false; + } + + SDL_zerop(hwinfo); + + __dpmi_regs regs; + regs.x.ax = 0x4F01; + regs.x.es = DOS_LinearToPhysical(hwinfo) / 16; + regs.x.di = DOS_LinearToPhysical(hwinfo) & 0xF; + regs.x.cx = mode_id; + __dpmi_int(0x10, ®s); + + const bool retval = (regs.x.ax == 0x004F); + if (retval) { + SDL_zerop(info); + info->mode_id = mode_id; + info->attributes = hwinfo->ModeAttributes; + info->pitch = hwinfo->BytesPerScanLine; + info->w = hwinfo->XResolution; + info->h = hwinfo->YResolution; + info->num_planes = hwinfo->NumberOfPlanes; + info->bpp = hwinfo->BitsPerPixel; + info->memory_model = hwinfo->MemoryModel; + info->num_image_pages = hwinfo->NumberOfImagePages; + info->red_mask_size = hwinfo->RedMaskSize; + info->red_mask_pos = hwinfo->RedMaskPos; + info->green_mask_size = hwinfo->GreenMaskSize; + info->green_mask_pos = hwinfo->GreenMaskPos; + info->blue_mask_size = hwinfo->BlueMaskSize; + info->blue_mask_pos = hwinfo->BlueMaskPos; + info->physical_base_addr = hwinfo->PhysBasePtr; + + // VBE 1.2 banked framebuffer fields + info->has_lfb = (hwinfo->ModeAttributes & VBE_MODEATTR_LFB) != 0; + info->win_granularity = hwinfo->WinGranularity; + info->win_size = hwinfo->WinSize; + info->win_a_segment = hwinfo->WinASegment; + info->win_func_ptr = hwinfo->WinFuncPtr; + info->win_a_attributes = hwinfo->WinAAttributes; + } + + DOS_FreeConventionalMemory(&hwinfo_seginfo); + + return retval; +} + +bool DOSVESA_GetDisplayModes(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_display) +{ + const SDL_VESAInfo *vinfo = GetVESAInfo(); + + // Enumerate VESA modes if we have a VBE 1.2+ BIOS. Older VBE versions + // (1.0, 1.1) or no VESA at all just skip this loop and fall through to + // the VGA mode 13h fallback below. + int num_vesa_modes = (vinfo && vinfo->version >= 0x102) ? vinfo->num_modes : 0; + + for (int mi = 0; mi < num_vesa_modes; mi++) { + const Uint16 modeid = vinfo->mode_list[mi]; + + SDL_DisplayModeData info; + if (!GetVESAModeInfo(modeid, &info)) { + continue; + } + + // Skip 320x200x8 from VESA. We always want VGA mode 13h for this + // resolution (no page flip, no LFB overhead, universal compatibility). + if (info.bpp == 8 && info.w == 320 && info.h == 200) { + continue; + } + + if ((info.attributes & VBE_MODEATTR_REQUIRED) != VBE_MODEATTR_REQUIRED) { + continue; + } + + if (!(info.attributes & VBE_MODEATTR_LFB) && (info.win_a_attributes & VBE_WINATTR_USABLE) != VBE_WINATTR_USABLE) { + continue; + } + + if (info.num_planes != 1) { + continue; // skip planar pixel layouts. + } else if (info.bpp < 8) { + continue; // skip anything below 8-bit. + } else if (!info.w || !info.h) { + continue; // zero-area display mode?! + } else if (!info.has_lfb && !info.win_granularity) { + continue; // banked mode with zero granularity would cause division by zero. + } else if ((info.memory_model != VBE_MEMMODEL_PACKED_PIXEL) && (info.memory_model != VBE_MEMMODEL_DIRECT_COLOR)) { + continue; // must be either packed pixel or Direct Color. + // Note: 8-bit indexed modes are packed pixel. + } + + SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN; + if (info.memory_model == VBE_MEMMODEL_PACKED_PIXEL) { + switch (info.bpp) { + case 8: + format = SDL_PIXELFORMAT_INDEX8; + break; + case 15: + format = SDL_PIXELFORMAT_XRGB1555; + break; + case 16: + format = SDL_PIXELFORMAT_RGB565; + break; + case 24: + format = SDL_PIXELFORMAT_RGB24; + break; + case 32: + format = SDL_PIXELFORMAT_XRGB8888; + break; + default: + break; + } + } else { + SDL_assert(info.memory_model == VBE_MEMMODEL_DIRECT_COLOR); + const Uint32 rmask = ((((Uint32)1) << info.red_mask_size) - 1) << info.red_mask_pos; + const Uint32 gmask = ((((Uint32)1) << info.green_mask_size) - 1) << info.green_mask_pos; + const Uint32 bmask = ((((Uint32)1) << info.blue_mask_size) - 1) << info.blue_mask_pos; + format = SDL_GetPixelFormatForMasks(info.bpp, rmask, gmask, bmask, 0x00000000); + } + + if (format == SDL_PIXELFORMAT_UNKNOWN) { + continue; // don't know what to do with this one. + } + + SDL_DisplayModeData *internal = (SDL_DisplayModeData *)SDL_malloc(sizeof(*internal)); + if (!internal) { + continue; // oof. + } + + SDL_copyp(internal, &info); + + SDL_DisplayMode mode; + SDL_zero(mode); + mode.format = format; + mode.w = (int)info.w; + mode.h = (int)info.h; + mode.pixel_density = 1.0f; // no HighDPI scaling here. + + // !!! FIXME: we need to parse EDID data (VESA function 0x4F15, subfunction 0x01) to get refresh rates. Leaving as 0 for now. + // float refresh_rate; /**< refresh rate (or 0.0f for unspecified) */ + // int refresh_rate_numerator; /**< precise refresh rate numerator (or 0 for unspecified) */ + // int refresh_rate_denominator; /**< precise refresh rate denominator */ + + mode.internal = internal; + + if (!SDL_AddFullscreenDisplayMode(sdl_display, &mode)) { + SDL_free(internal); // oh well, carry on without it. + } + } + + // Always add VGA mode 13h for 320x200x8. We skipped any VESA 320x200x8 + // modes above so this is the only entry at that resolution. + { + SDL_DisplayModeData *internal = (SDL_DisplayModeData *)SDL_malloc(sizeof(*internal)); + if (internal) { + SDL_zerop(internal); + internal->mode_id = VGA_MODE_13H_SENTINEL; + internal->attributes = VBE_MODEATTR_REQUIRED; + internal->pitch = 320; + internal->w = 320; + internal->h = 200; + internal->num_planes = 1; + internal->bpp = 8; + internal->memory_model = VBE_MEMMODEL_PACKED_PIXEL; + internal->num_image_pages = 0; // no page flipping in mode 13h + internal->physical_base_addr = 0; + internal->has_lfb = false; + internal->win_granularity = 64; + internal->win_size = 64; + internal->win_a_segment = VGA_MODE_13H_SEGMENT; + internal->win_func_ptr = 0; + internal->win_a_attributes = VBE_WINATTR_USABLE; + + SDL_DisplayMode mode; + SDL_zero(mode); + mode.format = SDL_PIXELFORMAT_INDEX8; + mode.w = 320; + mode.h = 200; + mode.pixel_density = 1.0f; + mode.internal = internal; + + if (!SDL_AddFullscreenDisplayMode(sdl_display, &mode)) { + SDL_free(internal); + } + } + } + + // Sort modes descending: largest to smallest (by width first, then height, then bpp). + for (int i = 0; i < sdl_display->num_fullscreen_modes - 1; i++) { + for (int j = i + 1; j < sdl_display->num_fullscreen_modes; j++) { + const SDL_DisplayMode *a = &sdl_display->fullscreen_modes[i]; + const SDL_DisplayMode *b = &sdl_display->fullscreen_modes[j]; + bool swap = false; + if (b->w > a->w) { + swap = true; + } else if (b->w == a->w) { + if (b->h > a->h) { + swap = true; + } else if (b->h == a->h) { + if (SDL_BITSPERPIXEL(b->format) > SDL_BITSPERPIXEL(a->format)) { + swap = true; + } + } + } + if (swap) { + SDL_DisplayMode tmp = sdl_display->fullscreen_modes[i]; + sdl_display->fullscreen_modes[i] = sdl_display->fullscreen_modes[j]; + sdl_display->fullscreen_modes[j] = tmp; + } + } + } + + return true; +} + +bool DOSVESA_SetDisplayMode(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_display, SDL_DisplayMode *mode) +{ + SDL_VideoData *data = device->internal; + const SDL_DisplayModeData *modedata = mode->internal; + + if (data->current_mode.internal && (data->current_mode.internal->mode_id == modedata->mode_id)) { + return true; + } + + DOSVESA_InvalidateCachedFramebuffer(); + + if (data->mapping.size) { + __dpmi_free_physical_address_mapping(&data->mapping); // dump existing video mapping. + SDL_zero(data->mapping); + } + + __dpmi_regs regs; + + if (modedata->mode_id == VGA_MODE_13H_SENTINEL) { + // Set VGA mode 13h (320x200x256) via legacy BIOS call. + SDL_zero(regs); + regs.x.ax = 0x0013; + __dpmi_int(0x10, ®s); + // Mode 13h always succeeds on VGA hardware; no status to check. + + data->banked_mode = true; // uses A000:0000 segment, no LFB + + SDL_copyp(&data->current_mode, mode); + + data->page_flip_available = false; + data->current_page = 0; + data->page_offset[0] = 0; + data->page_offset[1] = 0; + + // Clear the framebuffer + { + Uint8 zero_buf[320]; + SDL_memset(zero_buf, 0, sizeof(zero_buf)); + Uint32 vga_base = (Uint32)VGA_MODE_13H_SEGMENT << 4; + for (int row = 0; row < 200; row++) { + dosmemput(zero_buf, 320, vga_base + row * 320); + } + } + + if (SDL_GetMouse()->internal != NULL) { + regs.x.ax = 0x7; + regs.x.cx = 0; + regs.x.dx = (Uint16)(mode->w - 1); + __dpmi_int(0x33, ®s); + + regs.x.ax = 0x8; + regs.x.cx = 0; + regs.x.dx = (Uint16)(mode->h - 1); + __dpmi_int(0x33, ®s); + } + + return true; + } + + // When the direct-FB hint is active, prefer banked mode. This needs + // to be set explicitly for some cards (Intel 740). + const bool is_banked_usable = modedata->win_a_segment && + modedata->win_size > 0 && + (modedata->win_a_attributes & VBE_WINATTR_USABLE) == VBE_WINATTR_USABLE; + const bool use_lfb = modedata->has_lfb && + (!is_banked_usable || !SDL_GetHintBoolean(SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER, false)); + + regs.x.ax = 0x4F02; + regs.x.bx = modedata->mode_id | (use_lfb ? VBE_SETMODE_LFB : 0); + __dpmi_int(0x10, ®s); + + if (regs.x.ax != 0x004F) { + return SDL_SetError("Failed to set VESA video mode"); + } + + data->banked_mode = !use_lfb; + + if (use_lfb) { + data->mapping.address = modedata->physical_base_addr; + data->mapping.size = DOSVESA_GetVESATotalMemory(); + if (__dpmi_physical_address_mapping(&data->mapping) != 0) { + SDL_zero(data->mapping); + regs.x.ax = 0x03; // try to dump us back into text mode. Not sure if this is a good idea, though. + __dpmi_int(0x10, ®s); + SDL_zero(data->current_mode); + return SDL_SetError("Failed to map VESA video memory"); + } + + // make sure framebuffer is blanked out. + SDL_memset(DOS_PhysicalToLinear(data->mapping.address), '\0', (Uint32)modedata->h * (Uint32)modedata->pitch); + } else { + // Banked mode: no physical address mapping needed. + // Blank the visible framebuffer through the banked window. + Uint32 total_bytes = (Uint32)modedata->h * (Uint32)modedata->pitch; + Uint32 win_gran_bytes = (Uint32)modedata->win_granularity * 1024; + Uint32 win_size_bytes = (Uint32)modedata->win_size * 1024; + Uint32 win_base = (Uint32)modedata->win_a_segment << 4; + Uint8 zero_buf[1024]; + SDL_memset(zero_buf, 0, sizeof(zero_buf)); + + Uint32 offset = 0; + int current_bank = -1; + while (offset < total_bytes) { + int bank = (int)(offset / win_gran_bytes); + Uint32 off_in_win = offset % win_gran_bytes; + Uint32 n = win_size_bytes - off_in_win; + if (n > total_bytes - offset) { + n = total_bytes - offset; + } + + if (bank != current_bank) { + __dpmi_regs bregs; + SDL_zero(bregs); + bregs.x.bx = 0; // Window A + bregs.x.dx = (Uint16)bank; + if (modedata->win_func_ptr) { + // Call WinFuncPtr directly — faster than INT 10h. + bregs.x.cs = (Uint16)(modedata->win_func_ptr >> 16); + bregs.x.ip = (Uint16)(modedata->win_func_ptr & 0xFFFF); + __dpmi_simulate_real_mode_procedure_retf(&bregs); + } else { + bregs.x.ax = 0x4F05; + __dpmi_int(0x10, &bregs); + } + current_bank = bank; + } + + // Zero in 1KB chunks via dosmemput + Uint32 written = 0; + while (written < n) { + Uint32 chunk = n - written; + if (chunk > sizeof(zero_buf)) { + chunk = sizeof(zero_buf); + } + dosmemput(zero_buf, chunk, win_base + off_in_win + written); + written += chunk; + } + offset += n; + } + } + + SDL_copyp(&data->current_mode, mode); + + // Set up page-flipping if the mode has at least 1 image page (meaning 2 total) + // Note: page-flipping is only supported with LFB modes. With banked modes, + // we would still need to bank-switch through the same 64KB window to write + // to the back page, so the performance benefit is minimal (just tear-free). + // For simplicity, disable page-flipping in banked mode for now. + if (!data->banked_mode && modedata->num_image_pages >= 1) { + data->page_flip_available = true; + data->current_page = 0; + data->page_offset[0] = 0; + data->page_offset[1] = (Uint32)modedata->pitch * (Uint32)modedata->h; + + // Check that both pages fit within the mapped region. + Uint32 page1_end = data->page_offset[1] + (Uint32)modedata->pitch * (Uint32)modedata->h; + if (page1_end > data->mapping.size) { + data->page_flip_available = false; + data->page_offset[1] = 0; + } else { + // Also blank the second page + SDL_memset((Uint8 *)DOS_PhysicalToLinear(data->mapping.address) + data->page_offset[1], + '\0', (Uint32)modedata->pitch * (Uint32)modedata->h); + + // Start display at page 0 + regs.x.ax = 0x4F07; + regs.x.bx = 0x0000; // set display start, wait for retrace + regs.x.cx = 0; // first pixel in scan line + regs.x.dx = 0; // first scan line + __dpmi_int(0x10, ®s); + } + } else { + data->page_flip_available = false; + data->current_page = 0; + data->page_offset[0] = 0; + data->page_offset[1] = 0; + } + + if (SDL_GetMouse()->internal != NULL) { // internal != NULL) == int 33h services available. + regs.x.ax = 0x7; // set mouse min/max horizontal position. + regs.x.cx = 0; + regs.x.dx = (Uint16)(mode->w - 1); + __dpmi_int(0x33, ®s); + + regs.x.ax = 0x8; // set mouse min/max vertical position. + regs.x.cx = 0; + regs.x.dx = (Uint16)(mode->h - 1); + __dpmi_int(0x33, ®s); + } + + return true; +} + +#endif // SDL_VIDEO_DRIVER_DOSVESA diff --git a/src/video/dos/SDL_dosmodes.h b/src/video/dos/SDL_dosmodes.h new file mode 100644 index 0000000000..27ffa426b5 --- /dev/null +++ b/src/video/dos/SDL_dosmodes.h @@ -0,0 +1,50 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dosmodes_h_ +#define SDL_dosmodes_h_ + +#include "SDL_internal.h" + +extern bool DOSVESA_GetDisplayModes(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_display); +extern bool DOSVESA_SetDisplayMode(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_display, SDL_DisplayMode *mode); +extern bool DOSVESA_SupportsVESA(void); +extern void DOSVESA_FreeVESAInfo(void); +extern Uint32 DOSVESA_GetVESATotalMemory(void); +extern const char *DOSVESA_GetGPUName(void); + +// VGA DAC (Digital-to-Analog Converter) ports for palette programming +#define VGA_DAC_PIXEL_MASK 0x3C6 // pixel mask register (read/write, VGA-only) +#define VGA_DAC_WRITE_INDEX 0x3C8 // write index register (set starting color index) +#define VGA_DAC_DATA 0x3C9 // data register (write R, G, B in sequence) + +// VGA Input Status Register 1 (for vblank detection) +#define VGA_STATUS_PORT 0x3DA +#define VGA_STATUS_VBLANK 0x08 // bit 3: vertical retrace active + +// VBE window attribute bits (WinAAttributes / WinBAttributes field) +#define VBE_WINATTR_SUPPORTED 0x01 // bit 0: window is supported +#define VBE_WINATTR_WRITABLE 0x04 // bit 2: window is writable + +// Combination: a usable banked window must be both supported and writable +#define VBE_WINATTR_USABLE (VBE_WINATTR_SUPPORTED | VBE_WINATTR_WRITABLE) + +#endif // SDL_dosmodes_h_ \ No newline at end of file diff --git a/src/video/dos/SDL_dosmouse.c b/src/video/dos/SDL_dosmouse.c new file mode 100644 index 0000000000..a77ea1ef48 --- /dev/null +++ b/src/video/dos/SDL_dosmouse.c @@ -0,0 +1,170 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_DOSVESA + +// https://stanislavs.org/helppc/int_33.html + +#include "SDL_dosmouse.h" +#include "SDL_dosvideo.h" + +#include "../../events/SDL_mouse_c.h" +#include "../../events/default_cursor.h" +#include "../SDL_sysvideo.h" + +// Create a cursor from a surface +static SDL_Cursor *DOSVESA_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + SDL_CursorData *curdata; + SDL_Cursor *cursor; + + SDL_assert(surface->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + + cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + return NULL; + } + curdata = (SDL_CursorData *)SDL_calloc(1, sizeof(*curdata)); + if (!curdata) { + SDL_free(cursor); + return NULL; + } + + curdata->surface = SDL_DuplicateSurface(surface); + if (!curdata->surface) { + SDL_free(curdata); + SDL_free(cursor); + return NULL; + } + + SDL_SetSurfaceBlendMode(curdata->surface, SDL_BLENDMODE_BLEND); + + curdata->hot_x = hot_x; + curdata->hot_y = hot_y; + curdata->w = surface->w; + curdata->h = surface->h; + + cursor->internal = curdata; + + return cursor; +} + +static SDL_Cursor *DOSVESA_CreateDefaultCursor(void) +{ + return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); +} + +// Show the specified cursor, or hide if cursor is NULL +static bool DOSVESA_ShowCursor(SDL_Cursor *cursor) +{ + return true; // we handle this elsewhere. +} + +// Free a window manager cursor +static void DOSVESA_FreeCursor(SDL_Cursor *cursor) +{ + SDL_CursorData *curdata; + + if (cursor) { + curdata = cursor->internal; + + if (curdata) { + SDL_DestroySurface(curdata->surface); + SDL_DestroySurface(curdata->converted_surface); + SDL_free(cursor->internal); + } + SDL_free(cursor); + } +} + +static bool DOSVESA_WarpMouseGlobal(float x, float y) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (!mouse || !mouse->cur_cursor || !mouse->cur_cursor->internal) { + return true; + } + + // warp mouse in the driver, so we get correct screen coordinates from it. + __dpmi_regs regs; + regs.x.ax = 0x4; + regs.x.cx = (Uint16)x; + regs.x.dx = (Uint16)y; + __dpmi_int(0x33, ®s); + + // Update internal mouse position. + SDL_SendMouseMotion(0, mouse->focus, SDL_GLOBAL_MOUSE_ID, false, x, y); + + return true; +} + +static bool DOSVESA_WarpMouse(SDL_Window *window, float x, float y) +{ + return DOSVESA_WarpMouseGlobal(x, y); +} + +// This is called when a mouse motion event occurs +static bool DOSVESA_MoveCursor(SDL_Cursor *cursor) +{ + return true; // we handle this elsewhere. +} + +void DOSVESA_InitMouse(SDL_VideoDevice *_this) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + mouse->internal = NULL; + + __dpmi_regs regs; + regs.x.ax = 0; + __dpmi_int(0x33, ®s); + if (regs.x.ax == 0) { + return; // no mouse found, don't hook up cursor support, etc. + } + + mouse->internal = SDL_calloc(1, 1); // just something non-NULL (and safely freeable) to say "there's a mouse available." + + // Query mouse sensitivity (mickeys per pixel) via INT 33h function 0x1B + SDL_VideoData *data = _this->internal; + regs.x.ax = 0x1B; // Get Mouse Sensitivity + __dpmi_int(0x33, ®s); + data->mickeys_per_hpixel = (regs.x.bx > 0) ? (float)regs.x.bx : 8.0f; + data->mickeys_per_vpixel = (regs.x.cx > 0) ? (float)regs.x.cx : 16.0f; + + mouse->CreateCursor = DOSVESA_CreateCursor; + mouse->ShowCursor = DOSVESA_ShowCursor; + mouse->MoveCursor = DOSVESA_MoveCursor; + mouse->FreeCursor = DOSVESA_FreeCursor; + mouse->WarpMouse = DOSVESA_WarpMouse; + mouse->WarpMouseGlobal = DOSVESA_WarpMouseGlobal; + + SDL_SetDefaultCursor(DOSVESA_CreateDefaultCursor()); +} + +void DOSVESA_QuitMouse(SDL_VideoDevice *_this) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_free(mouse->internal); + mouse->internal = NULL; +} + +#endif // SDL_VIDEO_DRIVER_DOSVESA diff --git a/src/video/dos/SDL_dosmouse.h b/src/video/dos/SDL_dosmouse.h new file mode 100644 index 0000000000..86bc0843e2 --- /dev/null +++ b/src/video/dos/SDL_dosmouse.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dosmouse_h_ +#define SDL_dosmouse_h_ + +#include "../SDL_sysvideo.h" + +struct SDL_CursorData +{ + SDL_Surface *surface; + SDL_Surface *converted_surface; + Uint32 converted_palette_version; + int hot_x, hot_y; + int w, h; +}; + +extern void DOSVESA_InitMouse(SDL_VideoDevice *_this); +extern void DOSVESA_QuitMouse(SDL_VideoDevice *_this); + +#endif // SDL_dosmouse_h_ diff --git a/src/video/dos/SDL_dosvideo.c b/src/video/dos/SDL_dosvideo.c new file mode 100644 index 0000000000..59043bb76e --- /dev/null +++ b/src/video/dos/SDL_dosvideo.c @@ -0,0 +1,356 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_DOSVESA + +// SDL internals +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" + +// DOS declarations +#include "SDL_dosevents_c.h" +#include "SDL_dosframebuffer_c.h" +#include "SDL_dosmodes.h" +#include "SDL_dosmouse.h" +#include "SDL_dosvideo.h" + +// Apply a display mode for a window: set the hardware mode, store it as +// the window's requested fullscreen mode, and update window dimensions. +static void DOSVESA_ApplyModeForWindow(SDL_VideoDisplay *display, SDL_Window *window, SDL_DisplayMode *mode) +{ + SDL_SetDisplayModeForDisplay(display, mode); + + if (mode) { + SDL_copyp(&window->requested_fullscreen_mode, mode); + window->floating.w = window->windowed.w = window->w = mode->w; + window->floating.h = window->windowed.h = window->h = mode->h; + } +} + +static bool DOSVESA_CreateWindow(SDL_VideoDevice *device, SDL_Window *window, SDL_PropertiesID create_props) +{ + // Allocate window internal data + SDL_WindowData *wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!wdata) { + return false; + } + + // Setup driver data for this window + window->internal = wdata; + + // One window, it always has focus + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + + { + SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); + if (!display) { + return true; + } + + SDL_DisplayMode *mode = NULL; + if (window->requested_fullscreen_mode.internal) { + // App explicitly set a fullscreen mode. + mode = &window->requested_fullscreen_mode; + } else if (window->floating.w > 0 && window->floating.h > 0) { + SDL_DisplayMode closest; + if (SDL_GetClosestFullscreenDisplayMode(display->id, window->floating.w, window->floating.h, 0.0f, false, &closest)) { + mode = &closest; + } + } + if (!mode) { + return true; + } + + DOSVESA_ApplyModeForWindow(display, window, mode); + } + + return true; +} + +static void DOSVESA_SetWindowSize(SDL_VideoDevice *device, SDL_Window *window) +{ + SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); + if (!display) { + return; + } + + SDL_DisplayMode closest; + SDL_DisplayMode *mode = NULL; + if (SDL_GetClosestFullscreenDisplayMode(display->id, window->floating.w, window->floating.h, 0.0f, false, &closest)) { + mode = &closest; + } + + DOSVESA_ApplyModeForWindow(display, window, mode); + + // Invalidate the framebuffer so it gets recreated at the new size. + window->surface_valid = false; +} + +// Critical for performance: this function must be implemented and as simple +// as possible to avoid slowdowns during calls to SDL_UpdateWindowSurface(). +// A few pointer dereferences here can cost 10% of performance easily. +static void DOSVESA_GetWindowSizeInPixels(SDL_VideoDevice *device, SDL_Window *window, int *w, int *h) +{ + *w = window->w; + *h = window->h; +} + +static void DOSVESA_DestroyWindow(SDL_VideoDevice *device, SDL_Window *window) +{ + SDL_free(window->internal); + window->internal = NULL; +} + +static bool DOSVESA_VideoInit(SDL_VideoDevice *device) +{ + SDL_VideoData *data = device->internal; + + // Verify that the "fat DS" nearptr trick is active. Without it, + // DOS_PhysicalToLinear() produces garbage pointers and we crash. + // SDL_RunApp() enables this automatically; if the app defined + // SDL_MAIN_HANDLED it must call __djgpp_nearptr_enable() itself. + if (__djgpp_conventional_base == 0) { + return SDL_SetError("DOSVESA: __djgpp_nearptr_enable() was not called. " + "Did you define SDL_MAIN_HANDLED without enabling the fat DS trick?"); + } + + // We are probably in text mode at startup, so we don't have a real "desktop mode" atm. + // Pick something _super_ conservative for now. + // We'll change to a real video mode after enumerating available modes below. + SDL_DisplayMode mode; + SDL_zero(mode); + mode.format = SDL_PIXELFORMAT_RGB565; + mode.w = 320; + mode.h = 200; + + SDL_VideoDisplay vdisplay; + SDL_zero(vdisplay); + SDL_memcpy(&vdisplay.desktop_mode, &mode, sizeof(mode)); + vdisplay.name = (char *)DOSVESA_GetGPUName(); + SDL_DisplayID display_id = SDL_AddVideoDisplay(&vdisplay, false); + if (!display_id) { + return false; + } + + SDL_zero(data->current_mode); + + SDL_VideoDisplay *display = SDL_GetVideoDisplay(display_id); + if (!display || !DOSVESA_GetDisplayModes(device, display)) { + return false; + } + + // Pick a sensible default desktop mode. This determines the window + // size for FULLSCREEN_ONLY. Target 640x480 as a safe default; apps + // that want something else should call SDL_SetWindowFullscreenMode. + { + SDL_DisplayMode closest; + if (SDL_GetClosestFullscreenDisplayMode(display_id, 640, 480, 0.0f, false, &closest)) { + // Deep-copy the mode into desktop_mode. We need our own + // internal allocation because SDL frees desktop_mode.internal + // and fullscreen_modes[].internal independently. + SDL_DisplayModeData *desktop_internal = (SDL_DisplayModeData *)SDL_malloc(sizeof(*desktop_internal)); + if (desktop_internal) { + SDL_copyp(desktop_internal, (const SDL_DisplayModeData *)closest.internal); + SDL_copyp(&display->desktop_mode, &closest); + display->desktop_mode.internal = desktop_internal; + } + } + } + + // Save the current video mode so we can restore it on quit. + // The VBE calls (0x4F03, 0x4F04) return 0x004F on success; on cards + // without VBE support (or VBE < 1.2) they simply fail and we fall + // back to restoring standard text mode 0x03. + { + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x4F03; // VBE Get Current Mode + __dpmi_int(0x10, ®s); + if (regs.x.ax == 0x004F) { + data->original_vbe_mode = regs.x.bx; + } else { + data->original_vbe_mode = 0x03; // assume text mode + } + + // Save VBE state via VBE function 0x4F04 so we can do a full restore later. + // Step 1: query the required buffer size (subfunction 0x00). + SDL_zero(regs); + regs.x.ax = 0x4F04; + regs.x.dx = 0x00; // subfunction 0: get state buffer size + regs.x.cx = 0x0F; // save all state: hardware + BIOS data + DAC + SVGA + __dpmi_int(0x10, ®s); + if (regs.x.ax == 0x004F) { + // regs.x.bx contains size in 64-byte blocks. + Uint32 state_size = (Uint32)regs.x.bx * 64; + _go32_dpmi_seginfo state_seginfo; + void *state_buf = DOS_AllocateConventionalMemory(state_size, &state_seginfo); + if (state_buf) { + // Step 2: save state (subfunction 0x01) into conventional memory buffer. + SDL_zero(regs); + regs.x.ax = 0x4F04; + regs.x.dx = 0x01; // subfunction 1: save state + regs.x.cx = 0x0F; // all state + regs.x.es = DOS_LinearToPhysical(state_buf) / 16; + regs.x.bx = DOS_LinearToPhysical(state_buf) & 0xF; + __dpmi_int(0x10, ®s); + if (regs.x.ax == 0x004F) { + // Copy state from conventional memory to our heap so we + // can free the low-memory buffer now. + data->vbe_state_buffer = SDL_malloc(state_size); + if (data->vbe_state_buffer) { + SDL_memcpy(data->vbe_state_buffer, state_buf, state_size); + data->vbe_state_buffer_size = state_size; + } + } + DOS_FreeConventionalMemory(&state_seginfo); + } + } + } + + DOSVESA_InitMouse(device); + DOSVESA_InitKeyboard(device); + + return true; +} + +static void DOSVESA_VideoQuit(SDL_VideoDevice *device) +{ + SDL_VideoData *data = device->internal; + + if (data->mapping.size) { + __dpmi_free_physical_address_mapping(&data->mapping); // dump existing video mapping. + SDL_zero(data->mapping); + } + + // Restore saved VBE state if available. + if (data->vbe_state_buffer && data->vbe_state_buffer_size > 0) { + _go32_dpmi_seginfo restore_seginfo; + void *restore_buf = DOS_AllocateConventionalMemory(data->vbe_state_buffer_size, &restore_seginfo); + if (restore_buf) { + SDL_memcpy(restore_buf, data->vbe_state_buffer, data->vbe_state_buffer_size); + __dpmi_regs regs; + SDL_zero(regs); + regs.x.ax = 0x4F04; + regs.x.dx = 0x02; // subfunction 2: restore state + regs.x.cx = 0x0F; // all state + regs.x.es = DOS_LinearToPhysical(restore_buf) / 16; + regs.x.bx = DOS_LinearToPhysical(restore_buf) & 0xF; + __dpmi_int(0x10, ®s); + DOS_FreeConventionalMemory(&restore_seginfo); + } + SDL_free(data->vbe_state_buffer); + data->vbe_state_buffer = NULL; + data->vbe_state_buffer_size = 0; + } + + // Restore the original video mode. + { + __dpmi_regs regs; + bool restored = false; + + // Try VBE mode restore first (only works on VBE 1.2+). + if (data->original_vbe_mode != 0x03) { + SDL_zero(regs); + regs.x.ax = 0x4F02; + regs.x.bx = data->original_vbe_mode; + __dpmi_int(0x10, ®s); + restored = (regs.x.ax == 0x004F); + } + + // Fall back to standard BIOS text mode (works on any VGA). + if (!restored) { + SDL_zero(regs); + regs.x.ax = 0x0003; + __dpmi_int(0x10, ®s); + } + } + + SDL_zero(data->current_mode); + + DOSVESA_QuitMouse(device); + DOSVESA_QuitKeyboard(device); +} + +static void DOSVESA_Destroy(SDL_VideoDevice *device) +{ + SDL_VideoData *data = device->internal; + SDL_free(data->vbe_state_buffer); + SDL_free(device->internal); + SDL_free(device); + DOSVESA_FreeVESAInfo(); +} + +static SDL_VideoDevice *DOSVESA_CreateDevice(void) +{ + if (!DOSVESA_SupportsVESA()) { + return NULL; + } + + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + // Initialize SDL_VideoDevice structure + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + return NULL; + } + + // Initialize internal data + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { + SDL_free(device); + return NULL; + } + + device->internal = phdata; + device->free = DOSVESA_Destroy; + device->VideoInit = DOSVESA_VideoInit; + device->VideoQuit = DOSVESA_VideoQuit; + device->GetDisplayModes = DOSVESA_GetDisplayModes; + device->SetDisplayMode = DOSVESA_SetDisplayMode; + device->CreateSDLWindow = DOSVESA_CreateWindow; + device->SetWindowSize = DOSVESA_SetWindowSize; + device->DestroyWindow = DOSVESA_DestroyWindow; + device->CreateWindowFramebuffer = DOSVESA_CreateWindowFramebuffer; + device->SetWindowFramebufferVSync = DOSVESA_SetWindowFramebufferVSync; + device->GetWindowFramebufferVSync = DOSVESA_GetWindowFramebufferVSync; + device->UpdateWindowFramebuffer = DOSVESA_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = DOSVESA_DestroyWindowFramebuffer; + device->GetWindowSizeInPixels = DOSVESA_GetWindowSizeInPixels; + device->PumpEvents = DOSVESA_PumpEvents; + device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY; + + return device; +} + +VideoBootStrap DOSVESA_bootstrap = { + "vesa", + "DOS VESA Video Driver", + DOSVESA_CreateDevice, + NULL, // no ShowMessageBox implementation + false +}; + +#endif // SDL_VIDEO_DRIVER_DOSVESA diff --git a/src/video/dos/SDL_dosvideo.h b/src/video/dos/SDL_dosvideo.h new file mode 100644 index 0000000000..c5646e9d85 --- /dev/null +++ b/src/video/dos/SDL_dosvideo.h @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dosvideo_h +#define SDL_dosvideo_h + +#include "../../core/dos/SDL_dos.h" +#include "../SDL_sysvideo.h" +#include "SDL_internal.h" + +struct SDL_DisplayModeData +{ + // we can add more fields to this, if we want them, later. + Uint16 mode_id; + Uint16 attributes; + Uint16 pitch; + Uint16 w; + Uint16 h; + Uint8 num_planes; + Uint8 bpp; + Uint8 memory_model; + Uint8 num_image_pages; + Uint8 red_mask_size; + Uint8 red_mask_pos; + Uint8 green_mask_size; + Uint8 green_mask_pos; + Uint8 blue_mask_size; + Uint8 blue_mask_pos; + Uint32 physical_base_addr; + + // VBE 1.2 banked framebuffer fields (used when LFB is not available) + bool has_lfb; // true if linear framebuffer is available (VBE 2.0+) + Uint16 win_granularity; // bank positioning granularity in KB + Uint16 win_size; // window size in KB (typically 64) + Uint16 win_a_segment; // real-mode segment of window A (typically 0xA000) + Uint32 win_func_ptr; // real-mode far pointer to bank-switch function + Uint8 win_a_attributes; // window A capabilities +}; + +struct SDL_VideoData +{ + __dpmi_meminfo mapping; // video memory mapping. + SDL_DisplayMode current_mode; + DOS_InterruptHook keyboard_interrupt_hook; + Uint32 palette_version; // tracks SDL_Palette::version to detect changes + Uint16 original_vbe_mode; // VBE mode number at startup + void *vbe_state_buffer; // saved VBE state (from VBE 0x4F04) + Uint32 vbe_state_buffer_size; // size of the state buffer + + // Mouse sensitivity (mickeys per pixel), queried from INT 33h function 0x1B + float mickeys_per_hpixel; // horizontal mickeys per pixel (default: 8) + float mickeys_per_vpixel; // vertical mickeys per pixel (default: 16) + + // Page-flipping (double-buffering) state + int current_page; // 0 or 1: which page is currently displayed + Uint32 page_offset[2]; // byte offset of each page within video memory + bool page_flip_available; // true if mode supports double-buffering + bool banked_mode; // true if current mode uses banked (not LFB) access +}; + +struct SDL_DisplayData +{ + int unused; // for now +}; + +struct SDL_WindowData +{ + int framebuffer_vsync; +}; + +#endif // SDL_dosvideo_h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 81caee0d74..b6e7b724bf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -88,12 +88,24 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.20) set(test_bin_dir "${test_bin_dir}$<$:/$>") endif() +if(DOS) + set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") + set(DOS83_SHORT "UNIFONT.HEX;UNIFONTL.TXT;PHYSADEV.PNG;LOGADEV.PNG;AUDIOFIL.PNG;SNDBRD.PNG;SNDLVL.PNG;TRASHCAN.PNG;MSDFFONT.PNG;MSDFFONT.CSV;GP_FRONT.PNG;GP_BACK.PNG;GP_FABXY.PNG;GP_FAXBY.PNG;GP_FBAYX.PNG;GP_FSONY.PNG;GP_BATT.PNG;GP_BATTX.PNG;GP_BATTW.PNG;GP_TOUCH.PNG;GP_BTN.PNG;GP_BTNSM.PNG;GP_BTNBG.PNG;GP_AXIS.PNG;GP_AXARW.PNG;GP_WIRED.PNG;GP_WLESS.PNG;SDLROUND.PNG") +endif() + set(RESOURCE_FILE_NAMES) set(RESOURCE_FILES_BINDIR) foreach(resource_file IN LISTS RESOURCE_FILES) get_filename_component(res_file_name ${resource_file} NAME) - list(APPEND RESOURCE_FILE_NAMES "${res_file_name}") - set(resource_file_bindir "${test_bin_dir}/${res_file_name}") + set(output_name "${res_file_name}") + if(DOS) + list(FIND DOS83_LONG "${res_file_name}" _dos83_idx) + if(NOT _dos83_idx EQUAL -1) + list(GET DOS83_SHORT ${_dos83_idx} output_name) + endif() + endif() + list(APPEND RESOURCE_FILE_NAMES "${output_name}") + set(resource_file_bindir "${test_bin_dir}/${output_name}") set(depends_resource_file "${resource_file}") if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) set(depends_resource_file "${CMAKE_CURRENT_LIST_FILE}") @@ -128,7 +140,7 @@ if(HAVE_WAYLAND) endif() function(add_sdl_test_executable TARGET) - cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;THREADS;MAIN_CALLBACKS;NOTRACKMEM" "" "DEPENDS;DISABLE_THREADS_ARGS;NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;INSTALLED_ARGS;SOURCES" ${ARGN}) + cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;THREADS;MAIN_CALLBACKS;NOTRACKMEM" "NAME83" "DEPENDS;DISABLE_THREADS_ARGS;NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;INSTALLED_ARGS;SOURCES" ${ARGN}) if(AST_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}") endif() @@ -227,6 +239,10 @@ function(add_sdl_test_executable TARGET) set_property(TARGET ${TARGET} PROPERTY "EXCLUDE_FROM_ALL" "1") set_propertY(TARGET ${TARGET} PROPERTY SDL_INSTALL "0") endif() + elseif(DOS) + if(AST_NAME83) + set_property(TARGET ${TARGET} PROPERTY OUTPUT_NAME "${AST_NAME83}") + endif() endif() if(OPENGL_FOUND) @@ -321,34 +337,34 @@ else() message(STATUS "Can't find ffmpeg 5.1.3 or newer, skipping testffmpeg") endif() -add_sdl_test_executable(checkkeys SOURCES checkkeys.c) +add_sdl_test_executable(checkkeys SOURCES checkkeys.c NAME83 chkkeys) add_sdl_test_executable(loopwave NEEDS_RESOURCES TESTUTILS MAIN_CALLBACKS SOURCES loopwave.c) -add_sdl_test_executable(testsurround SOURCES testsurround.c) -add_sdl_test_executable(testresample NEEDS_RESOURCES SOURCES testresample.c) -add_sdl_test_executable(testaudioinfo SOURCES testaudioinfo.c) -add_sdl_test_executable(testaudiostreamdynamicresample NEEDS_RESOURCES TESTUTILS SOURCES testaudiostreamdynamicresample.c) +add_sdl_test_executable(testsurround SOURCES testsurround.c NAME83 surround) +add_sdl_test_executable(testresample NEEDS_RESOURCES SOURCES testresample.c NAME83 resample) +add_sdl_test_executable(testaudioinfo SOURCES testaudioinfo.c NAME83 audioinf) +add_sdl_test_executable(testaudiostreamdynamicresample NEEDS_RESOURCES TESTUTILS SOURCES testaudiostreamdynamicresample.c NAME83 audynres) file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c) -add_sdl_test_executable(testautomation NONINTERACTIVE NONINTERACTIVE_TIMEOUT 120 NEEDS_RESOURCES BUILD_DEPENDENT SOURCES ${TESTAUTOMATION_SOURCE_FILES}) +add_sdl_test_executable(testautomation NONINTERACTIVE NONINTERACTIVE_TIMEOUT 120 NEEDS_RESOURCES BUILD_DEPENDENT SOURCES ${TESTAUTOMATION_SOURCE_FILES} NAME83 automat) if(EMSCRIPTEN) target_link_options(testautomation PRIVATE -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb) endif() -add_sdl_test_executable(testmultiaudio NEEDS_RESOURCES TESTUTILS SOURCES testmultiaudio.c) -add_sdl_test_executable(testaudiohotplug NEEDS_RESOURCES TESTUTILS SOURCES testaudiohotplug.c) -add_sdl_test_executable(testaudiorecording MAIN_CALLBACKS SOURCES testaudiorecording.c) -add_sdl_test_executable(testatomic NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" SOURCES testatomic.c) -add_sdl_test_executable(testintersections SOURCES testintersections.c) -add_sdl_test_executable(testrelative SOURCES testrelative.c) -add_sdl_test_executable(testhittesting SOURCES testhittesting.c) -add_sdl_test_executable(testdraw SOURCES testdraw.c) -add_sdl_test_executable(testdrawchessboard SOURCES testdrawchessboard.c) -add_sdl_test_executable(testdropfile MAIN_CALLBACKS SOURCES testdropfile.c) -add_sdl_test_executable(testerror NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" SOURCES testerror.c) -add_sdl_test_executable(testsymbols NONINTERACTIVE NOTRACKMEM NONINTERACTIVE_ARGS 0 10 20 40 80 160 320 640 SOURCES testsymbols.c) +add_sdl_test_executable(testmultiaudio NEEDS_RESOURCES TESTUTILS SOURCES testmultiaudio.c NAME83 multaudi) +add_sdl_test_executable(testaudiohotplug NEEDS_RESOURCES TESTUTILS SOURCES testaudiohotplug.c NAME83 audhotpl) +add_sdl_test_executable(testaudiorecording MAIN_CALLBACKS SOURCES testaudiorecording.c NAME83 aurecord) +add_sdl_test_executable(testatomic NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" SOURCES testatomic.c NAME83 atomic) +add_sdl_test_executable(testintersections SOURCES testintersections.c NAME83 intersec) +add_sdl_test_executable(testrelative SOURCES testrelative.c NAME83 relative) +add_sdl_test_executable(testhittesting SOURCES testhittesting.c NAME83 hittest) +add_sdl_test_executable(testdraw SOURCES testdraw.c NAME83 draw) +add_sdl_test_executable(testdrawchessboard SOURCES testdrawchessboard.c NAME83 drawches) +add_sdl_test_executable(testdropfile MAIN_CALLBACKS SOURCES testdropfile.c NAME83 dropfile) +add_sdl_test_executable(testerror NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" SOURCES testerror.c NAME83 error) +add_sdl_test_executable(testsymbols NONINTERACTIVE NOTRACKMEM NONINTERACTIVE_ARGS 0 10 20 40 80 160 320 640 SOURCES testsymbols.c NAME83 symbols) set(build_options_dependent_tests ) -add_sdl_test_executable(testevdev BUILD_DEPENDENT NONINTERACTIVE SOURCES testevdev.c) +add_sdl_test_executable(testevdev BUILD_DEPENDENT NONINTERACTIVE SOURCES testevdev.c NAME83 evdev) if(MACOS) add_sdl_test_executable(testnative BUILD_DEPENDENT NEEDS_RESOURCES TESTUTILS @@ -375,20 +391,20 @@ elseif(HAVE_X11 OR HAVE_WAYLAND) endif () endif() -add_sdl_test_executable(testasyncio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testasyncio.c) -add_sdl_test_executable(testaudio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testaudio.c) -add_sdl_test_executable(testcolorspace SOURCES testcolorspace.c) +add_sdl_test_executable(testasyncio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testasyncio.c NAME83 asyncio) +add_sdl_test_executable(testaudio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testaudio.c NAME83 audio) +add_sdl_test_executable(testcolorspace SOURCES testcolorspace.c NAME83 colorspc) add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c) -add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers} DEPENDS generate-gamepad_image_headers) -add_sdl_test_executable(testdlopennote TESTUTILS SOURCES testdlopennote.c) -add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c) -add_sdl_test_executable(testgl SOURCES testgl.c) -add_sdl_test_executable(testgles SOURCES testgles.c) -add_sdl_test_executable(testgpu_simple_clear SOURCES testgpu_simple_clear.c) -add_sdl_test_executable(testgpu_spinning_cube SOURCES testgpu_spinning_cube.c ${icon_png_header} DEPENDS generate-icon_png_header) -add_sdl_test_executable(testgpurender_effects MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testgpurender_effects.c) -add_sdl_test_executable(testgpurender_msdf MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testgpurender_msdf.c) -add_sdl_test_executable(testgpu_spinning_cube_xr SOURCES testgpu_spinning_cube_xr.c) +add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers} DEPENDS generate-gamepad_image_headers NAME83 control) +add_sdl_test_executable(testdlopennote TESTUTILS SOURCES testdlopennote.c NAME83 dlnote) +add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c NAME83 geometry) +add_sdl_test_executable(testgl SOURCES testgl.c NAME83 gl) +add_sdl_test_executable(testgles SOURCES testgles.c NAME83 tstgles NAME83 gles) +add_sdl_test_executable(testgpu_simple_clear SOURCES testgpu_simple_clear.c NAME83 gpuclear) +add_sdl_test_executable(testgpu_spinning_cube SOURCES testgpu_spinning_cube.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 gpucube) +add_sdl_test_executable(testgpurender_effects MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testgpurender_effects.c NAME83 gpufx) +add_sdl_test_executable(testgpurender_msdf MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testgpurender_msdf.c NAME83 gpumsdf) +add_sdl_test_executable(testgpu_spinning_cube_xr SOURCES testgpu_spinning_cube_xr.c NAME83 gpucubxr) if(ANDROID) target_link_libraries(testgles PRIVATE GLESv1_CM) @@ -396,70 +412,70 @@ elseif(IOS OR TVOS) find_library(GLES_LIB OpenGLES REQUIRED) target_link_libraries(testgles PRIVATE "${GLES_LIB}") endif() -add_sdl_test_executable(testgles2 SOURCES testgles2.c) -add_sdl_test_executable(testhaptic SOURCES testhaptic.c) -add_sdl_test_executable(testhotplug SOURCES testhotplug.c) -add_sdl_test_executable(testpen SOURCES testpen.c) -add_sdl_test_executable(testrumble SOURCES testrumble.c) -add_sdl_test_executable(testthread NONINTERACTIVE THREADS NONINTERACTIVE_TIMEOUT 40 SOURCES testthread.c) -add_sdl_test_executable(testiconv NEEDS_RESOURCES TESTUTILS SOURCES testiconv.c) -add_sdl_test_executable(testime NEEDS_RESOURCES TESTUTILS SOURCES testime.c) -add_sdl_test_executable(testkeys SOURCES testkeys.c) -add_sdl_test_executable(testloadso SOURCES testloadso.c) -add_sdl_test_executable(testlocale NONINTERACTIVE SOURCES testlocale.c) -add_sdl_test_executable(testlock SOURCES testlock.c) -add_sdl_test_executable(testrwlock SOURCES testrwlock.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 20) -add_sdl_test_executable(testmouse SOURCES testmouse.c) +add_sdl_test_executable(testgles2 SOURCES testgles2.c NAME83 gles2) +add_sdl_test_executable(testhaptic SOURCES testhaptic.c NAME83 haptic) +add_sdl_test_executable(testhotplug SOURCES testhotplug.c NAME83 hotplug) +add_sdl_test_executable(testpen SOURCES testpen.c NAME83 pen) +add_sdl_test_executable(testrumble SOURCES testrumble.c NAME83 rumble) +add_sdl_test_executable(testthread NONINTERACTIVE THREADS NONINTERACTIVE_TIMEOUT 40 SOURCES testthread.c NAME83 thread) +add_sdl_test_executable(testiconv NEEDS_RESOURCES TESTUTILS SOURCES testiconv.c NAME83 iconv) +add_sdl_test_executable(testime NEEDS_RESOURCES TESTUTILS SOURCES testime.c NAME83 ime) +add_sdl_test_executable(testkeys SOURCES testkeys.c NAME83 keys) +add_sdl_test_executable(testloadso SOURCES testloadso.c NAME83 loadso) +add_sdl_test_executable(testlocale NONINTERACTIVE SOURCES testlocale.c NAME83 locale) +add_sdl_test_executable(testlock SOURCES testlock.c NAME83 lock) +add_sdl_test_executable(testrwlock SOURCES testrwlock.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 20 NAME83 rwlock) +add_sdl_test_executable(testmouse SOURCES testmouse.c NAME83 mouse) -add_sdl_test_executable(testoverlay NEEDS_RESOURCES TESTUTILS SOURCES testoverlay.c) -add_sdl_test_executable(testplatform NONINTERACTIVE SOURCES testplatform.c) -add_sdl_test_executable(testpower NONINTERACTIVE SOURCES testpower.c) -add_sdl_test_executable(testfilesystem NONINTERACTIVE SOURCES testfilesystem.c) +add_sdl_test_executable(testoverlay NEEDS_RESOURCES TESTUTILS SOURCES testoverlay.c NAME83 overlay) +add_sdl_test_executable(testplatform NONINTERACTIVE SOURCES testplatform.c NAME83 platform) +add_sdl_test_executable(testpower NONINTERACTIVE SOURCES testpower.c NAME83 power) +add_sdl_test_executable(testfilesystem NONINTERACTIVE SOURCES testfilesystem.c NAME83 filesyst) if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4) add_sdl_test_executable(pretest SOURCES pretest.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 60) endif() -add_sdl_test_executable(testrendertarget NEEDS_RESOURCES TESTUTILS SOURCES testrendertarget.c) -add_sdl_test_executable(testrotate SOURCES testrotate.c) -add_sdl_test_executable(testscale NEEDS_RESOURCES TESTUTILS SOURCES testscale.c) -add_sdl_test_executable(testsem NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" NONINTERACTIVE_ARGS 10 NONINTERACTIVE_TIMEOUT 30 SOURCES testsem.c) -add_sdl_test_executable(testsensor SOURCES testsensor.c) -add_sdl_test_executable(testshader NEEDS_RESOURCES TESTUTILS SOURCES testshader.c) +add_sdl_test_executable(testrendertarget NEEDS_RESOURCES TESTUTILS SOURCES testrendertarget.c NAME83 rendrtgt) +add_sdl_test_executable(testrotate SOURCES testrotate.c NAME83 rotate) +add_sdl_test_executable(testscale NEEDS_RESOURCES TESTUTILS SOURCES testscale.c NAME83 scale) +add_sdl_test_executable(testsem NONINTERACTIVE DISABLE_THREADS_ARGS "--no-threads" NONINTERACTIVE_ARGS 10 NONINTERACTIVE_TIMEOUT 30 SOURCES testsem.c NAME83 sem) +add_sdl_test_executable(testsensor SOURCES testsensor.c NAME83 sensor) +add_sdl_test_executable(testshader NEEDS_RESOURCES TESTUTILS SOURCES testshader.c NAME83 shader) if(EMSCRIPTEN) target_link_options(testshader PRIVATE "-sLEGACY_GL_EMULATION") endif() -add_sdl_test_executable(testshape NEEDS_RESOURCES SOURCES testshape.c ${glass_png_header} DEPENDS generate-glass_png_header) -add_sdl_test_executable(testsoftwaretransparent SOURCES testsoftwaretransparent.c) -add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c) -add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_png_header} DEPENDS generate-icon_png_header) -add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_png_header} DEPENDS generate-icon_png_header) -add_sdl_test_executable(testpalette SOURCES testpalette.c) -add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c) -add_sdl_test_executable(testurl SOURCES testurl.c) -add_sdl_test_executable(testver NONINTERACTIVE NOTRACKMEM SOURCES testver.c) +add_sdl_test_executable(testshape NEEDS_RESOURCES SOURCES testshape.c ${glass_png_header} DEPENDS generate-glass_png_header NAME83 shape) +add_sdl_test_executable(testsoftwaretransparent SOURCES testsoftwaretransparent.c NAME83 swtransp) +add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c NAME83 sprite) +add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 spritmin) +add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 spritsrf) +add_sdl_test_executable(testpalette SOURCES testpalette.c NAME83 palette) +add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c NAME83 timer) +add_sdl_test_executable(testurl SOURCES testurl.c NAME83 url) +add_sdl_test_executable(testver NONINTERACTIVE NOTRACKMEM SOURCES testver.c NAME83 versdl) set_property(TARGET testver PROPERTY C_STANDARD 90) -add_sdl_test_executable(testcamera MAIN_CALLBACKS SOURCES testcamera.c) -add_sdl_test_executable(testclipboard MAIN_CALLBACKS SOURCES testclipboard.c ${icon_png_header} DEPENDS generate-icon_png_header) -add_sdl_test_executable(testviewport NEEDS_RESOURCES TESTUTILS SOURCES testviewport.c) -add_sdl_test_executable(testwm SOURCES testwm.c) -add_sdl_test_executable(testyuv NONINTERACTIVE NONINTERACTIVE_ARGS "--automated" NEEDS_RESOURCES TESTUTILS SOURCES testyuv.c testyuv_cvt.c) -add_sdl_test_executable(torturethread NONINTERACTIVE THREADS NONINTERACTIVE_TIMEOUT 30 SOURCES torturethread.c) -add_sdl_test_executable(testrendercopyex NEEDS_RESOURCES TESTUTILS SOURCES testrendercopyex.c) -add_sdl_test_executable(testmessage SOURCES testmessage.c) -add_sdl_test_executable(testdisplayinfo SOURCES testdisplayinfo.c) -add_sdl_test_executable(testqsort NONINTERACTIVE SOURCES testqsort.c) +add_sdl_test_executable(testcamera MAIN_CALLBACKS SOURCES testcamera.c NAME83 camera) +add_sdl_test_executable(testclipboard MAIN_CALLBACKS SOURCES testclipboard.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 clipbrd) +add_sdl_test_executable(testviewport NEEDS_RESOURCES TESTUTILS SOURCES testviewport.c NAME83 viewport) +add_sdl_test_executable(testwm SOURCES testwm.c NAME83 wm) +add_sdl_test_executable(testyuv NONINTERACTIVE NONINTERACTIVE_ARGS "--automated" NEEDS_RESOURCES TESTUTILS SOURCES testyuv.c testyuv_cvt.c NAME83 yuv) +add_sdl_test_executable(torturethread NONINTERACTIVE THREADS NONINTERACTIVE_TIMEOUT 30 SOURCES torturethread.c NAME83 tortthrd) +add_sdl_test_executable(testrendercopyex NEEDS_RESOURCES TESTUTILS SOURCES testrendercopyex.c NAME83 rndcopex) +add_sdl_test_executable(testmessage SOURCES testmessage.c NAME83 message) +add_sdl_test_executable(testdisplayinfo SOURCES testdisplayinfo.c NAME83 dispinfo) +add_sdl_test_executable(testqsort NONINTERACTIVE SOURCES testqsort.c NAME83 qsort) if(EMSCRIPTEN) target_link_options(testqsort PRIVATE -sALLOW_MEMORY_GROWTH) endif() -add_sdl_test_executable(testbounds NONINTERACTIVE SOURCES testbounds.c) -add_sdl_test_executable(testcustomcursor SOURCES testcustomcursor.c) -add_sdl_test_executable(testvulkan SOURCES testvulkan.c) -add_sdl_test_executable(testoffscreen SOURCES testoffscreen.c) -add_sdl_test_executable(testpopup SOURCES testpopup.c) -add_sdl_test_executable(testdialog SOURCES testdialog.c) -add_sdl_test_executable(testtime SOURCES testtime.c) -add_sdl_test_executable(testmanymouse SOURCES testmanymouse.c) -add_sdl_test_executable(testmodal SOURCES testmodal.c) -add_sdl_test_executable(testtray NEEDS_RESOURCES TESTUTILS SOURCES testtray.c) +add_sdl_test_executable(testbounds NONINTERACTIVE SOURCES testbounds.c NAME83 bounds) +add_sdl_test_executable(testcustomcursor SOURCES testcustomcursor.c NAME83 custcurs) +add_sdl_test_executable(testvulkan SOURCES testvulkan.c NAME83 vulkan) +add_sdl_test_executable(testoffscreen SOURCES testoffscreen.c NAME83 offscrn) +add_sdl_test_executable(testpopup SOURCES testpopup.c NAME83 popup) +add_sdl_test_executable(testdialog SOURCES testdialog.c NAME83 dialog) +add_sdl_test_executable(testtime SOURCES testtime.c NAME83 timesdl) +add_sdl_test_executable(testmanymouse SOURCES testmanymouse.c NAME83 manymous) +add_sdl_test_executable(testmodal SOURCES testmodal.c NAME83 modal) +add_sdl_test_executable(testtray NEEDS_RESOURCES TESTUTILS SOURCES testtray.c NAME83 tray) add_sdl_test_executable(testprocess @@ -467,8 +483,9 @@ add_sdl_test_executable(testprocess NONINTERACTIVE_ARGS $ INSTALLED_ARGS "${CMAKE_INSTALL_FULL_LIBEXECDIR}/installed-tests/SDL3/childprocess${CMAKE_EXECUTABLE_SUFFIX}" SOURCES testprocess.c + NAME83 process ) -add_sdl_test_executable(childprocess SOURCES childprocess.c) +add_sdl_test_executable(childprocess SOURCES childprocess.c NAME83 chldproc) add_dependencies(testprocess childprocess) get_property(SDL_TEST_EXECUTABLES DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY SDL_TEST_EXECUTABLES) diff --git a/test/testfile.c b/test/testfile.c index e49ce82446..d5b9f0a79d 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -166,7 +166,11 @@ int main(int argc, char *argv[]) RWOP_ERR_QUIT(iostrm); } if (0 != SDL_ReadIO(iostrm, test_buf, 1)) { +#ifdef __DJGPP__ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DJGPP allowed read on write-only file"); +#else RWOP_ERR_QUIT(iostrm); /* we are in write only mode */ +#endif } SDL_CloseIO(iostrm); @@ -203,7 +207,11 @@ int main(int argc, char *argv[]) RWOP_ERR_QUIT(iostrm); } if (0 != SDL_WriteIO(iostrm, test_buf, 1)) { +#ifdef __DJGPP__ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DJGPP allowed write on read-only file"); +#else RWOP_ERR_QUIT(iostrm); /* readonly mode */ +#endif } SDL_CloseIO(iostrm); diff --git a/test/testime.c b/test/testime.c index e2945a2cf3..e9d30aa53b 100644 --- a/test/testime.c +++ b/test/testime.c @@ -25,7 +25,11 @@ #include #include "testutils.h" +#ifdef SDL_PLATFORM_DOS +#define DEFAULT_FONT "UNIFONT.HEX" +#else #define DEFAULT_FONT "unifont-15.1.05.hex" +#endif #define MAX_TEXT_LENGTH 256 #define WINDOW_WIDTH 640 diff --git a/test/testsem.c b/test/testsem.c index 70092c98e1..e08131ad0e 100644 --- a/test/testsem.c +++ b/test/testsem.c @@ -321,9 +321,13 @@ int main(int argc, char **argv) TestOverheadUncontended(); if (enable_threads) { +#ifdef SDL_PLATFORM_DOS + SDL_Log("Skipping contended overhead tests (too slow for cooperative threading)"); +#else TestOverheadContended(false); TestOverheadContended(true); +#endif } SDL_Quit(); diff --git a/test/testutils.c b/test/testutils.c index d80ebbbf6d..d828bb49a5 100644 --- a/test/testutils.c +++ b/test/testutils.c @@ -13,6 +13,55 @@ #include "testutils.h" +#ifdef SDL_PLATFORM_DOS +static const struct +{ + const char *longname; + const char *shortname; +} names83_map[] = { + { "unifont-15.1.05.hex", "UNIFONT.HEX" }, + { "unifont-15.1.05-license.txt", "UNIFONTL.TXT" }, + { "physaudiodev.png", "PHYSADEV.PNG" }, + { "logaudiodev.png", "LOGADEV.PNG" }, + { "audiofile.png", "AUDIOFIL.PNG" }, + { "soundboard.png", "SNDBRD.PNG" }, + { "soundboard_levels.png", "SNDLVL.PNG" }, + { "trashcan.png", "TRASHCAN.PNG" }, + { "msdf_font.png", "MSDFFONT.PNG" }, + { "msdf_font.csv", "MSDFFONT.CSV" }, + { "gamepad_front.png", "GP_FRONT.PNG" }, + { "gamepad_back.png", "GP_BACK.PNG" }, + { "gamepad_face_abxy.png", "GP_FABXY.PNG" }, + { "gamepad_face_axby.png", "GP_FAXBY.PNG" }, + { "gamepad_face_bayx.png", "GP_FBAYX.PNG" }, + { "gamepad_face_sony.png", "GP_FSONY.PNG" }, + { "gamepad_battery.png", "GP_BATT.PNG" }, + { "gamepad_battery_unknown.png", "GP_BATTX.PNG" }, + { "gamepad_battery_wired.png", "GP_BATTW.PNG" }, + { "gamepad_touchpad.png", "GP_TOUCH.PNG" }, + { "gamepad_button.png", "GP_BTN.PNG" }, + { "gamepad_button_small.png", "GP_BTNSM.PNG" }, + { "gamepad_button_background.png", "GP_BTNBG.PNG" }, + { "gamepad_axis.png", "GP_AXIS.PNG" }, + { "gamepad_axis_arrow.png", "GP_AXARW.PNG" }, + { "gamepad_wired.png", "GP_WIRED.PNG" }, + { "gamepad_wireless.png", "GP_WLESS.PNG" }, + { "sdl-test_round.png", "SDLROUND.PNG" }, + { NULL, NULL } +}; + +static const char *Map83Filename(const char *file) +{ + int i; + for (i = 0; names83_map[i].longname; i++) { + if (SDL_strcasecmp(file, names83_map[i].longname) == 0) { + return names83_map[i].shortname; + } + } + return file; +} +#endif + /** * Return the absolute path to def in the SDL_GetBasePath() if possible, or * the relative path to def on platforms that don't have a working @@ -23,6 +72,9 @@ char *GetNearbyFilename(const char *file) { const char *base = SDL_GetBasePath(); +#ifdef SDL_PLATFORM_DOS + file = Map83Filename(file); +#endif char *path; if (base) { @@ -59,6 +111,9 @@ char *GetResourceFilename(const char *user_specified, const char *def) if (user_specified) { return SDL_strdup(user_specified); } +#ifdef SDL_PLATFORM_DOS + def = Map83Filename(def); +#endif return GetNearbyFilename(def); } diff --git a/test/testwm.c b/test/testwm.c index f770f35885..393f82c3f7 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -106,6 +106,9 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport) for (j = 0; modes[j]; ++j) { SDL_FRect cell_rect; const SDL_DisplayMode *mode = modes[j]; + if (mode->format == SDL_PIXELFORMAT_INDEX8) { + continue; + } (void)SDL_snprintf(text, sizeof(text), "%s mode %d: %dx%d@%gx %gHz", SDL_GetDisplayName(display), diff --git a/test/torturethread.c b/test/torturethread.c index 1607e0db90..ba0d339cd4 100644 --- a/test/torturethread.c +++ b/test/torturethread.c @@ -19,7 +19,11 @@ #include #include +#ifdef SDL_PLATFORM_DOS +#define NUMTHREADS 3 /* DOS cooperative scheduler has limited thread slots */ +#else #define NUMTHREADS 10 +#endif static SDL_AtomicInt time_for_threads_to_die[NUMTHREADS]; @@ -63,7 +67,9 @@ ThreadFunc(void *data) SDL_Log("Thread '%d' waiting for signal", tid); while (SDL_GetAtomicInt(&time_for_threads_to_die[tid]) != 1) { - ; /* do nothing */ +#ifdef SDL_PLATFORM_DOS + SDL_Delay(0); /* Yield for cooperative threading */ +#endif } SDL_Log("Thread '%d' sending signals to subthreads", tid); From ec4cef27119f4f3f9d2c81e766f922fef2a0a4b3 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 24 Apr 2026 02:21:57 +0200 Subject: [PATCH 154/407] cmake: disable vulkan by default for Solaris --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86b0214b85..936d979fe9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,8 +283,11 @@ if(COMMAND SDL_Preseed_CMakeCache) set(SDL_PRESEED_AVAILABLE ON) endif() +set(SDL_VULKAN_DEFAULT ON) + set(SDL_X11_XRANDR_DEFAULT ON) if(SOLARIS) + set(SDL_VULKAN_DEFAULT OFF) set(SDL_X11_XRANDR_DEFAULT OFF) endif() @@ -373,7 +376,7 @@ dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SD dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF) dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF) dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF) -dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS" OFF) +dep_option(SDL_VULKAN "Enable Vulkan support" "${SDL_VULKAN_DEFAULT}" "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS" OFF) dep_option(SDL_RENDER_VULKAN "Enable the Vulkan render driver" ON "SDL_RENDER;SDL_VULKAN" OFF) dep_option(SDL_METAL "Enable Metal support" ON "APPLE" OFF) set_option(SDL_OPENVR "Use OpenVR video driver" OFF) From f2206974b098d2fbd61fdaf1a01513b6831b60d9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 23 Apr 2026 20:57:35 -0500 Subject: [PATCH 155/407] atomic: Use DMB ISHLD for aarch64 acquire barrier This is a little more efficient than a DMB ISH and matches what GCC, Clang, and MSVC generate for a C++11 acquire fence. --- include/SDL3/SDL_atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index bbd5828df3..91de812828 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -283,7 +283,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") #elif defined(__GNUC__) && defined(__aarch64__) #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ishld" : : : "memory") #elif defined(__GNUC__) && defined(__arm__) #if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */ /* Information from: From 1db6d5381a0ff9bd6fc5d8ab2d4d5a4fea3c8f14 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Fri, 10 Apr 2026 16:54:08 +0200 Subject: [PATCH 156/407] SDL_EnumerateDirectory(""): Don't append path separator if path is empty --- src/filesystem/posix/SDL_sysfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index 1ab9f80301..fd42876215 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -74,7 +74,7 @@ bool SDL_SYS_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback #endif char *pathwithsep = NULL; - int pathwithseplen = SDL_asprintf(&pathwithsep, "%s/", apath ? apath : path); + int pathwithseplen = SDL_asprintf(&pathwithsep, "%s%s", apath ? apath : path, (apath ? *apath : *path) ? "/" : ""); const size_t extralen = apath ? (SDL_strlen(apath) - SDL_strlen(path)) : 0; SDL_free(apath); if ((pathwithseplen == -1) || (!pathwithsep)) { From f3d7df54e2c06ba1921621d069984c599b572372 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 24 Apr 2026 07:30:12 -0700 Subject: [PATCH 157/407] Fixed crash in SDL_startswith() when passed NULL strings Fixes https://github.com/libsdl-org/SDL/issues/15451 --- src/SDL_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL_utils.c b/src/SDL_utils.c index 2667390ac6..a4a0d77614 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -111,7 +111,8 @@ void SDL_CalculateFraction(float x, int *numerator, int *denominator) bool SDL_startswith(const char *string, const char *prefix) { - if (SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0) { + if (string && prefix && + SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0) { return true; } return false; From c124da43674faebe80b7ed6880b520dec0cb9cb6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 24 Apr 2026 07:33:37 -0700 Subject: [PATCH 158/407] Don't do name blacklisting if there's no name --- src/joystick/SDL_gamepad.c | 39 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 3d2171e73e..72d43a5552 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -3233,28 +3233,29 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id) */ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) { - int i; - for (i = 0; i < SDL_arraysize(SDL_gamepad_blacklist_words); i++) { - const struct SDL_GamepadBlacklistWords *blacklist_word = &SDL_gamepad_blacklist_words[i]; + if (name) { + for (int i = 0; i < SDL_arraysize(SDL_gamepad_blacklist_words); i++) { + const struct SDL_GamepadBlacklistWords *blacklist_word = &SDL_gamepad_blacklist_words[i]; - switch (blacklist_word->pos) { - case GAMEPAD_BLACKLIST_BEGIN: - if (SDL_startswith(name, blacklist_word->str)) { - return true; - } - break; + switch (blacklist_word->pos) { + case GAMEPAD_BLACKLIST_BEGIN: + if (SDL_startswith(name, blacklist_word->str)) { + return true; + } + break; - case GAMEPAD_BLACKLIST_END: - if (SDL_endswith(name, blacklist_word->str)) { - return true; - } - break; + case GAMEPAD_BLACKLIST_END: + if (SDL_endswith(name, blacklist_word->str)) { + return true; + } + break; - case GAMEPAD_BLACKLIST_ANYWHERE: - if (SDL_strstr(name, blacklist_word->str) != NULL) { - return true; - } - break; + case GAMEPAD_BLACKLIST_ANYWHERE: + if (SDL_strstr(name, blacklist_word->str) != NULL) { + return true; + } + break; + } } } From 01a7588f8e593b93c75ca7adbc6ec595e84e9bce Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 24 Apr 2026 13:14:30 -0400 Subject: [PATCH 159/407] wayland: Avoid excessive exposure events during interactive resizes Only send the unblocking exposure event once per frame, so that clients using an event watcher won't redraw excessively. Also ensure that the unblocking exposure is always sent on the libdecor path. --- src/video/wayland/SDL_waylandwindow.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 43ccce42e7..cc44d58ef4 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -870,10 +870,10 @@ static void handle_xdg_surface_configure(void *data, struct xdg_surface *xdg, ui wind->pending_config_ack = false; ConfigureWindowGeometry(window); xdg_surface_ack_configure(xdg, serial); - } else { + } else if (!wind->pending_config_ack) { wind->pending_config_ack = true; - // Send an exposure event so that clients doing deferred updates will trigger a frame callback and make guaranteed forward progress when resizing. + // Always send an exposure event during a new frame to ensure forward progress if the frame callback already occurred. SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); } @@ -1643,6 +1643,11 @@ static void decoration_frame_configure(struct libdecor_frame *frame, struct libdecor_state *state = libdecor_state_new(wind->current.logical_width, wind->current.logical_height); libdecor_frame_commit(frame, state, configuration); libdecor_state_free(state); + + // Always send an exposure event during a new frame to ensure forward progress if the frame callback already occurred. + if (started_resize) { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); + } } if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { From 1146ea484a5972947528d5ae9b20ee874e71408d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 24 Apr 2026 11:35:01 -0700 Subject: [PATCH 160/407] Fixed the menu controller button state on recent Apple platforms The OS reports the button state as of macOS 11.0, iOS 14.0, and tvOS 14.0, so use that instead of the deprecated pause handler. --- src/joystick/apple/SDL_mfijoystick.m | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m index 2e93e684ae..d512521a4b 100644 --- a/src/joystick/apple/SDL_mfijoystick.m +++ b/src/joystick/apple/SDL_mfijoystick.m @@ -1060,13 +1060,7 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) int button = 0; for (id key in device->buttons) { - bool down; - if (button == device->pause_button_index) { - down = (device->pause_button_pressed > 0); - } else { - down = buttons[key].isPressed; - } - SDL_SendJoystickButton(timestamp, joystick, button++, down); + SDL_SendJoystickButton(timestamp, joystick, button++, buttons[key].isPressed); } } else if (controller.extendedGamepad) { bool isstack; From 74a746281f2208e07a7680560fcb7ec57565228e Mon Sep 17 00:00:00 2001 From: Kuratius <47481645+Kuratius@users.noreply.github.com> Date: Sat, 25 Apr 2026 01:18:57 +0200 Subject: [PATCH 161/407] Expose Steam Controller touchpads in Gamepad API (#15378) --- src/joystick/hidapi/SDL_hidapi_steam.c | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index ca5fe5b76f..624e8b5dd5 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1011,6 +1011,13 @@ typedef struct Uint64 sensor_timestamp; Uint64 pairing_time; + bool left_touch_down; + float left_touch_x; + float left_touch_y; + bool right_touch_down; + float right_touch_x; + float right_touch_y; + SteamControllerPacketAssembler m_assembler; SteamControllerStateInternal_t m_state; SteamControllerStateInternal_t m_last_state; @@ -1269,6 +1276,9 @@ static bool HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joyst SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); + SDL_PrivateJoystickAddTouchpad(joystick, 1); + SDL_PrivateJoystickAddTouchpad(joystick, 1); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM_HOME_LED, SDL_HomeLEDHintChanged, ctx); @@ -1348,6 +1358,21 @@ static bool ControllerConnected(SDL_HIDAPI_Device *device, SDL_Joystick **joysti return true; } +static float FilterTouch(float newValue, float oldValue) +{ + const float jitter = 256.0f / (1 << 16); + if (newValue > (oldValue - jitter * 0.5f) && newValue < (oldValue + jitter * 0.5f)) { + return oldValue; + } + if (newValue > (oldValue - jitter) && newValue < (oldValue + jitter)) { + return oldValue * 0.75f + newValue * 0.25f; + } + if (newValue > (oldValue - jitter * 2.0f) && newValue < (oldValue + jitter * 2.0f)) { + return (oldValue + newValue) * 0.5f; + } + return newValue; +} + static void ControllerDisconnected(SDL_HIDAPI_Device *device, SDL_Joystick **joystick) { SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context; @@ -1469,6 +1494,46 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, ctx->m_state.sRightPadX); SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, ~ctx->m_state.sRightPadY); + // Note that the left pad is normally mapped to D-Pad, so you should ignore that input if you use the touchpad instead. + { + const bool down = (ctx->m_state.ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) ? true : false; + if (down || ctx->left_touch_down) { + const bool clicked = (ctx->m_state.ulButtons & STEAM_BUTTON_LEFTPAD_CLICKED_MASK) ? true : false; + const float leftX = (float)ctx->m_state.sLeftPadX / (1 << 16) + 0.5f; + const float leftY = -(float)ctx->m_state.sLeftPadY / (1 << 16) + 0.5f; + float pressure = down ? 0.5f : 0.0f; + if (clicked) { + pressure += 0.5f; + } + if (down) { + ctx->left_touch_x = FilterTouch(leftX, ctx->left_touch_x); + ctx->left_touch_y = FilterTouch(leftY, ctx->left_touch_y); + } + SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, down, ctx->left_touch_x, ctx->left_touch_y, pressure); + ctx->left_touch_down = down; + } + } + + // Note that the right pad is normally mapped to right thumbstick, so you should ignore that input if you use the touchpad instead. + { + const bool down = (ctx->m_state.ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK) ? true : false; + if (down || ctx->right_touch_down) { + const bool clicked = (ctx->m_state.ulButtons & STEAM_BUTTON_RIGHTPAD_CLICKED_MASK) ? true : false; + const float rightX = (float)ctx->m_state.sRightPadX / (1 << 16) + 0.5f; + const float rightY = -(float)ctx->m_state.sRightPadY / (1 << 16) + 0.5f; + float pressure = down ? 0.5f : 0.0f; + if (clicked) { + pressure += 0.5f; + } + if (down) { + ctx->right_touch_x = FilterTouch(rightX, ctx->right_touch_x); + ctx->right_touch_y = FilterTouch(rightY, ctx->right_touch_y); + } + SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, down, ctx->right_touch_x, ctx->right_touch_y, pressure); + ctx->right_touch_down = down; + } + } + if (ctx->report_sensors) { float values[3]; From 0220a41a2eba0eddddf0b449272c03c3439838c3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 24 Apr 2026 18:26:10 -0500 Subject: [PATCH 162/407] atomic: Use acquire/release InterlockedExchange intrinsics on ARM64EC --- src/atomic/SDL_spinlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index 591e6bb8b7..32913b4f72 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -50,7 +50,7 @@ bool SDL_TryLockSpinlock(SDL_SpinLock *lock) #if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET) return __sync_lock_test_and_set(lock, 1) == 0; -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)) SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); return _InterlockedExchange_acq((long *)lock, 1) == 0; @@ -167,7 +167,7 @@ void SDL_UnlockSpinlock(SDL_SpinLock *lock) #if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET) __sync_lock_release(lock); -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)) SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); _InterlockedExchange_rel((long *)lock, 0); From 2c4c8172d77c774dff17af2ece5f4032b579636d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 23 Apr 2026 21:27:49 -0500 Subject: [PATCH 163/407] atomic: Fix memory barriers on MSVC ARM64 --- include/SDL3/SDL_atomic.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index 91de812828..e14a02a8ce 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -284,6 +284,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); #elif defined(__GNUC__) && defined(__aarch64__) #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ishld" : : : "memory") +#elif defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC)) +#include +#define SDL_MemoryBarrierRelease() __dmb(_ARM64_BARRIER_ISH) +#define SDL_MemoryBarrierAcquire() __dmb(_ARM64_BARRIER_ISHLD) #elif defined(__GNUC__) && defined(__arm__) #if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */ /* Information from: From 95ae0c194ec785d5a7ecf8b83a34f7f2ae29b07a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 24 Apr 2026 22:26:28 -0500 Subject: [PATCH 164/407] atomic: Fix and cleanup SDL_UnlockSpinlock() - Add missing SDL_MemoryBarrierRelease() in the generic codepath - Remove MSVC x86/x64 case which is now identical to the generic codepath - Fix Solaris barrier to ensure prior stores are visible before unlocking --- src/atomic/SDL_spinlock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index 32913b4f72..c048866604 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -171,16 +171,13 @@ void SDL_UnlockSpinlock(SDL_SpinLock *lock) SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); _InterlockedExchange_rel((long *)lock, 0); -#elif defined(_MSC_VER) - _ReadWriteBarrier(); - *lock = 0; - #elif defined(SDL_PLATFORM_SOLARIS) // Used for Solaris when not using gcc. - *lock = 0; membar_producer(); + *lock = 0; #else + SDL_MemoryBarrierRelease(); *lock = 0; #endif } From 3c02de2f7cd4c42eaa71f9a0ad9e7d9dfa26b000 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Apr 2026 07:24:53 -0700 Subject: [PATCH 165/407] Ignore the first hover event with a stale position on iOS Fixes https://github.com/libsdl-org/SDL/issues/15450 --- src/video/uikit/SDL_uikitpen.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/uikit/SDL_uikitpen.m b/src/video/uikit/SDL_uikitpen.m index 9e37000685..e66dbc588f 100644 --- a/src/video/uikit/SDL_uikitpen.m +++ b/src/video/uikit/SDL_uikitpen.m @@ -124,6 +124,11 @@ static void UIKit_HandlePenAxes(SDL_Window *window, NSTimeInterval nstimestamp, // rotation is in radians, and only available on a later iOS. const float rotation = rollAngle * radians_to_degrees; // !!! FIXME: this might need adjustment, I don't have a pencil that supports it. + if (force == 0.0f && (SDL_GetPenStatus(penId, NULL, 0) & SDL_PEN_INPUT_DOWN)) { + // The first hover as the pen is being released has a stale position, so ignore it + return; + } + SDL_SendPenMotion(timestamp, penId, window, point->x, point->y); SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_PRESSURE, pressure); SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_XTILT, xtilt); From 929e304b18796bf4db74f60f024a5e206f58d31b Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 24 Apr 2026 02:14:13 +0200 Subject: [PATCH 166/407] cmake: also check iconv on Windows when SDL_SYSTEM_ICONV is defined --- CMakeLists.txt | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 936d979fe9..6959d9f5c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1212,34 +1212,33 @@ if(SDL_LIBC) check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE) check_symbol_exists(posix_spawn_file_actions_addchdir "spawn.h" HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) check_symbol_exists(posix_spawn_file_actions_addchdir_np "spawn.h" HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) + endif() + if(SDL_SYSTEM_ICONV) + check_c_source_compiles(" + #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */ + #include + #include + int main(int argc, char **argv) { + return !iconv_open(NULL,NULL); + }" ICONV_IN_LIBC) - if(SDL_SYSTEM_ICONV) - check_c_source_compiles(" - #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */ - #include - #include - int main(int argc, char **argv) { - return !iconv_open(NULL,NULL); - }" ICONV_IN_LIBC) + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES iconv) + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { + return !iconv_open(NULL,NULL); + }" ICONV_IN_LIBICONV) + cmake_pop_check_state() - cmake_push_check_state() - list(APPEND CMAKE_REQUIRED_LIBRARIES iconv) - check_c_source_compiles(" - #include - #include - int main(int argc, char **argv) { - return !iconv_open(NULL,NULL); - }" ICONV_IN_LIBICONV) - cmake_pop_check_state() - - if(ICONV_IN_LIBC OR ICONV_IN_LIBICONV) - set(HAVE_ICONV 1) - set(HAVE_SYSTEM_ICONV TRUE) - if(ICONV_IN_LIBICONV AND (SDL_LIBICONV OR (NOT ICONV_IN_LIBC))) - sdl_link_dependency(iconv LIBS iconv) - set(SDL_USE_LIBICONV 1) - set(HAVE_LIBICONV TRUE) - endif() + if(ICONV_IN_LIBC OR ICONV_IN_LIBICONV) + set(HAVE_ICONV 1) + set(HAVE_SYSTEM_ICONV TRUE) + if(ICONV_IN_LIBICONV AND (SDL_LIBICONV OR (NOT ICONV_IN_LIBC))) + sdl_link_dependency(iconv LIBS iconv) + set(SDL_USE_LIBICONV 1) + set(HAVE_LIBICONV TRUE) endif() endif() From 880343d0e16a6e8d26a9edac5cce26d71bed6e53 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 25 Apr 2026 14:30:34 -0400 Subject: [PATCH 167/407] setup-djgpp-toolchain/action.yml: Fixed typo. --- .github/actions/setup-djgpp-toolchain/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-djgpp-toolchain/action.yml b/.github/actions/setup-djgpp-toolchain/action.yml index 7b10dc8afb..636c669b04 100644 --- a/.github/actions/setup-djgpp-toolchain/action.yml +++ b/.github/actions/setup-djgpp-toolchain/action.yml @@ -47,7 +47,7 @@ runs: with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} - - name: 'Extract DJGP archive' + - name: 'Extract DJGPP archive' shell: pwsh run: | $archive = "${{ steps.calc.outputs.archive }}"; From 30b0d2d8d0b2233c918dd7275c534cd7f168ac9b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 25 Apr 2026 14:30:50 -0400 Subject: [PATCH 168/407] macros.cmake: PrintEnabledBackends should catch underscores. Otherwise, "dos_soundblaster" doesn't show up in the list of backends for DOS. --- cmake/macros.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/macros.cmake b/cmake/macros.cmake index b39bd5d83f..eb445b233d 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -412,10 +412,10 @@ function(SDL_PrintSummary) PrintEnabledBackends("X11 libraries" "^SDL_VIDEO_DRIVER_X11_([A-Z0-9]*)$") endif() PrintEnabledBackends("Render drivers" "^SDL_VIDEO_RENDER_([A-Z0-9_]*)$") - PrintEnabledBackends("GPU drivers" "^SDL_GPU_([A-Z0-9]*)$") - PrintEnabledBackends("Audio drivers" "^SDL_AUDIO_DRIVER_([A-Z0-9]*)$") - PrintEnabledBackends("Joystick drivers" "^SDL_JOYSTICK_([A-Z0-9]*)$") - PrintEnabledBackends("Camera drivers" "^SDL_CAMERA_DRIVER_([A-Z0-9]*)$") + PrintEnabledBackends("GPU drivers" "^SDL_GPU_([A-Z0-9_]*)$") + PrintEnabledBackends("Audio drivers" "^SDL_AUDIO_DRIVER_([A-Z0-9_]*)$") + PrintEnabledBackends("Joystick drivers" "^SDL_JOYSTICK_([A-Z0-9_]*)$") + PrintEnabledBackends("Camera drivers" "^SDL_CAMERA_DRIVER_([A-Z0-9_]*)$") message(STATUS "") if(UNIX) From 559d226fc65a7191eca1a75e0646ee31e5a2ca9c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 25 Apr 2026 14:56:51 -0400 Subject: [PATCH 169/407] error: Alternate between two buffers in SDL_SetError. This way you can always safely use SDL_GetError() in your formatted string: ```c SDL_SetError("Couldn't open '%s': %s", filename, SDL_GetError()); ``` This problem was hidden on platforms that use the dynamic API, because it would format the new error string to a separate buffer first, to deal with the varargs entry point. Fixes #15456. --- src/SDL_error.c | 37 +++++++++++++++++++++++-------------- src/SDL_error_c.h | 8 +++++++- src/thread/SDL_thread.c | 17 +++++++++++------ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/SDL_error.c b/src/SDL_error.c index 618eb93d68..64c1bf06eb 100644 --- a/src/SDL_error.c +++ b/src/SDL_error.c @@ -43,22 +43,28 @@ bool SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) if (fmt) { int result; SDL_error *error = SDL_GetErrBuf(true); + + // use the other slot for the new error, so if this does + // SDL_SetError("%s", SDL_GetError()), we don't have a problem. + const int current = error->current ? 0 : 1; + SDL_ErrorInfo *errinfo = &error->info[current]; + error->current = current; + + errinfo->error = SDL_ErrorCodeGeneric; + va_list ap2; - - error->error = SDL_ErrorCodeGeneric; - va_copy(ap2, ap); - result = SDL_vsnprintf(error->str, error->len, fmt, ap2); + result = SDL_vsnprintf(errinfo->str, errinfo->len, fmt, ap2); va_end(ap2); - if (result >= 0 && (size_t)result >= error->len && error->realloc_func) { + if (result >= 0 && (size_t)result >= errinfo->len && error->realloc_func) { size_t len = (size_t)result + 1; - char *str = (char *)error->realloc_func(error->str, len); + char *str = (char *)error->realloc_func(errinfo->str, len); if (str) { - error->str = str; - error->len = len; + errinfo->str = str; + errinfo->len = len; va_copy(ap2, ap); - (void)SDL_vsnprintf(error->str, error->len, fmt, ap2); + (void)SDL_vsnprintf(errinfo->str, errinfo->len, fmt, ap2); va_end(ap2); } } @@ -67,7 +73,7 @@ bool SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) // Note that there are many recoverable errors that may happen internally and // can be safely ignored if the public API doesn't return an error code. #if 0 - SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", error->str); + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", errinfo->str); #endif } @@ -82,9 +88,10 @@ const char *SDL_GetError(void) return ""; } - switch (error->error) { + const SDL_ErrorInfo *errinfo = &error->info[error->current]; + switch (errinfo->error) { case SDL_ErrorCodeGeneric: - return error->str; + return errinfo->str; case SDL_ErrorCodeOutOfMemory: return "Out of memory"; default: @@ -97,7 +104,8 @@ bool SDL_ClearError(void) SDL_error *error = SDL_GetErrBuf(false); if (error) { - error->error = SDL_ErrorCodeNone; + SDL_ErrorInfo *errinfo = &error->info[error->current]; + errinfo->error = SDL_ErrorCodeNone; } return true; } @@ -107,7 +115,8 @@ bool SDL_OutOfMemory(void) SDL_error *error = SDL_GetErrBuf(true); if (error) { - error->error = SDL_ErrorCodeOutOfMemory; + SDL_ErrorInfo *errinfo = &error->info[error->current]; + errinfo->error = SDL_ErrorCodeOutOfMemory; } return false; } diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h index 6ea7703832..7d53783d88 100644 --- a/src/SDL_error_c.h +++ b/src/SDL_error_c.h @@ -34,11 +34,17 @@ typedef enum SDL_ErrorCodeOutOfMemory, } SDL_ErrorCode; -typedef struct SDL_error +typedef struct SDL_ErrorInfo { SDL_ErrorCode error; char *str; size_t len; +} SDL_ErrorInfo; + +typedef struct SDL_error +{ + SDL_ErrorInfo info[2]; // there are two, so you can do SDL_SetError("%s", SDL_GetError()) without stomping the buffer. + int current; SDL_realloc_func realloc_func; SDL_free_func free_func; } SDL_error; diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index efa1b72d4e..0d02bcd312 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -262,9 +262,12 @@ void SDL_Generic_QuitTLSData(void) static SDL_error *SDL_GetStaticErrBuf(void) { static SDL_error SDL_global_error; - static char SDL_global_error_str[128]; - SDL_global_error.str = SDL_global_error_str; - SDL_global_error.len = sizeof(SDL_global_error_str); + static char SDL_global_error_str1[128]; + static char SDL_global_error_str2[128]; + SDL_global_error.info[0].str = SDL_global_error_str1; + SDL_global_error.info[0].len = sizeof(SDL_global_error_str1); + SDL_global_error.info[1].str = SDL_global_error_str2; + SDL_global_error.info[1].len = sizeof(SDL_global_error_str2); return &SDL_global_error; } @@ -272,9 +275,11 @@ static SDL_error *SDL_GetStaticErrBuf(void) static void SDLCALL SDL_FreeErrBuf(void *data) { SDL_error *errbuf = (SDL_error *)data; - - if (errbuf->str) { - errbuf->free_func(errbuf->str); + if (errbuf->info[0].str) { + errbuf->free_func(errbuf->info[0].str); + } + if (errbuf->info[1].str) { + errbuf->free_func(errbuf->info[1].str); } errbuf->free_func(errbuf); } From 8fb1c6e367620be931ef5b1477737e144c1c10c1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 25 Apr 2026 15:26:22 -0400 Subject: [PATCH 170/407] haiku: Don't strdup SDL_GetError()'s string before using it in SDL_SetError(). This isn't necessary anymore, after recent fixes. --- src/dialog/haiku/SDL_haikudialog.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/dialog/haiku/SDL_haikudialog.cc b/src/dialog/haiku/SDL_haikudialog.cc index 33bf87cef1..78881e47be 100644 --- a/src/dialog/haiku/SDL_haikudialog.cc +++ b/src/dialog/haiku/SDL_haikudialog.cc @@ -222,9 +222,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil }; if (!SDL_InitBeApp()) { - char *err = SDL_strdup(SDL_GetError()); - SDL_SetError("Couldn't init Be app: %s", err); - SDL_free(err); + SDL_SetError("Couldn't init Be app: %s", SDL_GetError()); callback(userdata, NULL, -1); return; } From 47d14491a6e89322b2a649cdbfb854fccce12cd3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Apr 2026 17:10:54 -0700 Subject: [PATCH 171/407] Fixed keyboard being hidden while being shown on Android --- .../src/main/java/org/libsdl/app/SDLSurface.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java index 42eceb5096..dedc00b78a 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java @@ -45,6 +45,9 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, // Is SurfaceView ready for rendering protected boolean mIsSurfaceReady; + // Is on-screen keyboard visible + protected boolean mKeyboardVisible; + // Pinch events private final ScaleGestureDetector scaleGestureDetector; @@ -210,9 +213,15 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, SDLActivity.onNativeInsetsChanged(combined.left, combined.right, combined.top, combined.bottom); if (insets.isVisible(WindowInsets.Type.ime())) { - SDLActivity.onNativeScreenKeyboardShown(); + if (!mKeyboardVisible) { + mKeyboardVisible = true; + SDLActivity.onNativeScreenKeyboardShown(); + } } else { - SDLActivity.onNativeScreenKeyboardHidden(); + if (mKeyboardVisible) { + mKeyboardVisible = false; + SDLActivity.onNativeScreenKeyboardHidden(); + } } } From 543a05bf08b8f07462458826b5a0a58e3b025384 Mon Sep 17 00:00:00 2001 From: ShulkerSakura <50770360+ShulkerSakura@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:45:06 +0800 Subject: [PATCH 172/407] Add keychron Q3 blacklist (#15462) --- src/joystick/SDL_joystick.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index da778975ea..904509c191 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -451,6 +451,7 @@ static Uint32 initial_blacklist_devices[] = { MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) MAKE_VIDPID(0x31e3, 0x1310), // Wooting 60HE (ARM) MAKE_VIDPID(0x3297, 0x1969), // Moonlander MK1 Keyboard + MAKE_VIDPID(0x3434, 0x0121), // Keychron Q3 System Control MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control MAKE_VIDPID(0x3434, 0x0353), // Keychron V5 System Control MAKE_VIDPID(0x3434, 0xd030), // Keychron Link From 80a590507535da7403c3f75c958e7a45517ada4d Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sat, 25 Apr 2026 11:07:39 -0400 Subject: [PATCH 173/407] wayland: Change the non-native fullscreen mode scaling default to 'aspect' --- include/SDL3/SDL_hints.h | 3 +-- src/video/wayland/SDL_waylandwindow.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 377226f057..2f01f09881 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -4037,9 +4037,8 @@ extern "C" { * The variable can be set to the following values: * * - "aspect" - Video modes will be displayed scaled, in their proper aspect - * ratio, with black bars. + * ratio, with black bars. (default) * - "stretch" - Video modes will be scaled to fill the entire display. - * (default) * - "none" - Video modes will be displayed as 1:1 with no scaling. * * This hint should be set before creating a window. diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index cc44d58ef4..1dd4ec47dd 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -103,15 +103,15 @@ static enum WaylandModeScale GetModeScaleMethod(void) const char *scale_hint = SDL_GetHint(SDL_HINT_VIDEO_WAYLAND_MODE_SCALING); if (scale_hint) { - if (!SDL_strcasecmp(scale_hint, "aspect")) { - scale_mode = WAYLAND_MODE_SCALE_ASPECT; + if (!SDL_strcasecmp(scale_hint, "stretch")) { + scale_mode = WAYLAND_MODE_SCALE_STRETCH; } else if (!SDL_strcasecmp(scale_hint, "none")) { scale_mode = WAYLAND_MODE_SCALE_NONE; } else { - scale_mode = WAYLAND_MODE_SCALE_STRETCH; + scale_mode = WAYLAND_MODE_SCALE_ASPECT; } } else { - scale_mode = WAYLAND_MODE_SCALE_STRETCH; + scale_mode = WAYLAND_MODE_SCALE_ASPECT; } } From c65c8093377cfa286854a3ff1bed9668b9d2a255 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sat, 25 Apr 2026 11:32:19 -0400 Subject: [PATCH 174/407] wayland: Use manual masking on KDE for non-native aspect fullscreen modes KDE doesn't automatically center and mask fullscreen windows that don't match the display aspect ratio, so they are masked manually. Can be removed when https://invent.kde.org/plasma/kwin/-/merge_requests/6953 is merged. --- src/video/wayland/SDL_waylandwindow.c | 53 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 1dd4ec47dd..5f8bd98400 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -53,6 +53,41 @@ #include #endif +/* According to the Wayland spec: + * + * "If the [fullscreen] surface doesn't cover the whole output, the compositor will + * position the surface in the center of the output and compensate with border fill + * covering the rest of the output. The content of the border fill is undefined, but + * should be assumed to be in some way that attempts to blend into the surrounding area + * (e.g. solid black)." + * + * KDE (6.7 at the time of writing) doesn't do this (https://invent.kde.org/plasma/kwin/-/merge_requests/6953), + * so fullscreen modes that don't cover the output need to be manually masked. + * + * This must not be done universally, as some compositors do not correctly honor subsurface + * offsets on fullscreen windows, but those also follow the spec regarding automatic masking + * around fullscreen windows, so SDL doesn't need to apply its own mask. + * + * TODO: Remove this once KDE is spec-compliant. + */ +static bool ShouldMaskFullscreen() +{ + static int mask_required = -1; + + if (mask_required >= 0) { + return mask_required != 0; + } + + const char *desktop = SDL_getenv("XDG_CURRENT_DESKTOP"); + if (desktop && SDL_strcmp(desktop, "KDE") == 0) { + mask_required = 1; + } else { + mask_required = 0; + } + + return mask_required != 0; +} + static double GetWindowScale(SDL_Window *window) { return (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) || window->internal->scale_to_display ? window->internal->scale_factor : 1.0; @@ -73,20 +108,6 @@ static int PixelToPoint(SDL_Window *window, int pixel) return pixel ? SDL_max((int)SDL_lround((double)pixel / GetWindowScale(window)), 1) : 0; } -/* According to the Wayland spec: - * - * "If the [fullscreen] surface doesn't cover the whole output, the compositor will - * position the surface in the center of the output and compensate with border fill - * covering the rest of the output. The content of the border fill is undefined, but - * should be assumed to be in some way that attempts to blend into the surrounding area - * (e.g. solid black)." - * - * - KDE, as of 5.27, still doesn't do this - * - GNOME prior to 43 didn't do this (older versions are still found in many LTS distros) - * - * Default to 'stretch' for now, until things have moved forward enough that the default - * can be changed to 'aspect'. - */ enum WaylandModeScale { WAYLAND_MODE_SCALE_UNDEFINED, @@ -479,9 +500,9 @@ static void ConfigureWindowGeometry(SDL_Window *window) } /* Calculate the mask size and offset. - * Fullscreen windows are centered and masked automatically by the compositor. + * Fullscreen windows are centered and masked automatically by the compositor, unless it lacks the capability. */ - if (data->viewport && data->waylandData->subcompositor && !data->is_fullscreen && + if (data->viewport && data->waylandData->subcompositor && (!data->is_fullscreen || ShouldMaskFullscreen()) && (viewport_width != data->current.logical_width || viewport_height != data->current.logical_height)) { struct wl_buffer *old_buffer = NULL; From 1023f48b5a403890ecd59cd862f2c373e2255a7b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 26 Apr 2026 21:12:14 +0300 Subject: [PATCH 175/407] add missing newlines at end of dos sources. --- src/core/dos/SDL_dos_scheduler.h | 2 +- src/joystick/dos/SDL_sysjoystick.c | 2 +- src/thread/dos/SDL_sysmutex.c | 2 +- src/thread/dos/SDL_syssem.c | 2 +- src/thread/dos/SDL_systhread.c | 2 +- src/thread/dos/SDL_systhread_c.h | 2 +- src/thread/dos/SDL_systls.c | 3 ++- src/timer/dos/SDL_systimer.c | 2 +- src/video/dos/SDL_dosmodes.h | 2 +- 9 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/core/dos/SDL_dos_scheduler.h b/src/core/dos/SDL_dos_scheduler.h index 7732306aa7..bb1d085229 100644 --- a/src/core/dos/SDL_dos_scheduler.h +++ b/src/core/dos/SDL_dos_scheduler.h @@ -104,4 +104,4 @@ void DOS_DestroyThread(int thread_id); } #endif -#endif // SDL_dos_scheduler_h_ \ No newline at end of file +#endif // SDL_dos_scheduler_h_ diff --git a/src/joystick/dos/SDL_sysjoystick.c b/src/joystick/dos/SDL_sysjoystick.c index 4fde0f0f4a..63dc162616 100644 --- a/src/joystick/dos/SDL_sysjoystick.c +++ b/src/joystick/dos/SDL_sysjoystick.c @@ -339,4 +339,4 @@ SDL_JoystickDriver SDL_DOS_JoystickDriver = { DOS_JoystickGetGamepadMapping }; -#endif /* SDL_JOYSTICK_DOS */ \ No newline at end of file +#endif /* SDL_JOYSTICK_DOS */ diff --git a/src/thread/dos/SDL_sysmutex.c b/src/thread/dos/SDL_sysmutex.c index 9b138017dc..69f70c0125 100644 --- a/src/thread/dos/SDL_sysmutex.c +++ b/src/thread/dos/SDL_sysmutex.c @@ -119,4 +119,4 @@ void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS DOS_EnableInterrupts(); } -#endif /* SDL_THREAD_DOS */ \ No newline at end of file +#endif /* SDL_THREAD_DOS */ diff --git a/src/thread/dos/SDL_syssem.c b/src/thread/dos/SDL_syssem.c index 3166b2bce0..ea10d84d9d 100644 --- a/src/thread/dos/SDL_syssem.c +++ b/src/thread/dos/SDL_syssem.c @@ -112,4 +112,4 @@ void SDL_SignalSemaphore(SDL_Semaphore *sem) DOS_EnableInterrupts(); } -#endif /* SDL_THREAD_DOS */ \ No newline at end of file +#endif /* SDL_THREAD_DOS */ diff --git a/src/thread/dos/SDL_systhread.c b/src/thread/dos/SDL_systhread.c index 836bcf0632..b118d0832a 100644 --- a/src/thread/dos/SDL_systhread.c +++ b/src/thread/dos/SDL_systhread.c @@ -84,4 +84,4 @@ bool SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) return true; } -#endif /* SDL_THREAD_DOS */ \ No newline at end of file +#endif /* SDL_THREAD_DOS */ diff --git a/src/thread/dos/SDL_systhread_c.h b/src/thread/dos/SDL_systhread_c.h index ba1629e239..fd88a36c7a 100644 --- a/src/thread/dos/SDL_systhread_c.h +++ b/src/thread/dos/SDL_systhread_c.h @@ -25,4 +25,4 @@ /* DOS thread handle is an integer thread ID from the DOS scheduler */ typedef int SYS_ThreadHandle; -#endif /* SDL_systhread_c_h_ */ \ No newline at end of file +#endif /* SDL_systhread_c_h_ */ diff --git a/src/thread/dos/SDL_systls.c b/src/thread/dos/SDL_systls.c index 5c47596189..da9406f0a9 100644 --- a/src/thread/dos/SDL_systls.c +++ b/src/thread/dos/SDL_systls.c @@ -18,6 +18,7 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #include "SDL_internal.h" #ifdef SDL_THREAD_DOS @@ -60,4 +61,4 @@ void SDL_SYS_QuitTLSData(void) SDL_memset(tls_data, 0, sizeof(tls_data)); } -#endif /* SDL_THREAD_DOS */ \ No newline at end of file +#endif /* SDL_THREAD_DOS */ diff --git a/src/timer/dos/SDL_systimer.c b/src/timer/dos/SDL_systimer.c index d47bae177f..551c27d75c 100644 --- a/src/timer/dos/SDL_systimer.c +++ b/src/timer/dos/SDL_systimer.c @@ -67,4 +67,4 @@ void SDL_SYS_DelayNS(Uint64 ns) } } -#endif /* SDL_TIMER_DOS */ \ No newline at end of file +#endif /* SDL_TIMER_DOS */ diff --git a/src/video/dos/SDL_dosmodes.h b/src/video/dos/SDL_dosmodes.h index 27ffa426b5..dd811f2408 100644 --- a/src/video/dos/SDL_dosmodes.h +++ b/src/video/dos/SDL_dosmodes.h @@ -47,4 +47,4 @@ extern const char *DOSVESA_GetGPUName(void); // Combination: a usable banked window must be both supported and writable #define VBE_WINATTR_USABLE (VBE_WINATTR_SUPPORTED | VBE_WINATTR_WRITABLE) -#endif // SDL_dosmodes_h_ \ No newline at end of file +#endif // SDL_dosmodes_h_ From 3308183dfaedceb7cabb861d6ddb1bbc528d6cca Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 27 Apr 2026 05:30:14 +0300 Subject: [PATCH 176/407] video, dos: silence -Wdangling-pointer warnings --- src/video/dos/SDL_dosvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/dos/SDL_dosvideo.c b/src/video/dos/SDL_dosvideo.c index 59043bb76e..387a33360c 100644 --- a/src/video/dos/SDL_dosvideo.c +++ b/src/video/dos/SDL_dosvideo.c @@ -70,11 +70,11 @@ static bool DOSVESA_CreateWindow(SDL_VideoDevice *device, SDL_Window *window, SD } SDL_DisplayMode *mode = NULL; + SDL_DisplayMode closest; if (window->requested_fullscreen_mode.internal) { // App explicitly set a fullscreen mode. mode = &window->requested_fullscreen_mode; } else if (window->floating.w > 0 && window->floating.h > 0) { - SDL_DisplayMode closest; if (SDL_GetClosestFullscreenDisplayMode(display->id, window->floating.w, window->floating.h, 0.0f, false, &closest)) { mode = &closest; } From d5acd7f123f593a256124f313a47816c97532652 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 26 Apr 2026 21:42:23 -0500 Subject: [PATCH 177/407] atomic: Use __atomic_signal_fence() for SDL_CompilerBarrier() This is the (slightly) more standard way to accomplish it. --- include/SDL3/SDL_atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index e14a02a8ce..b6094b2550 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -156,6 +156,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockSpinlock(SDL_SpinLock *lock); */ #define SDL_CompilerBarrier() DoCompilerSpecificReadWriteBarrier() +#elif SDL_HAS_BUILTIN(__atomic_signal_fence) || (defined(__GNUC__) && (__GNUC__ >= 5)) +#define SDL_CompilerBarrier() __atomic_signal_fence(__ATOMIC_SEQ_CST) #elif defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__) void _ReadWriteBarrier(void); #pragma intrinsic(_ReadWriteBarrier) From c46dfdba543195873c205f8a30957d1a50b99565 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Mon, 27 Apr 2026 04:32:58 +0000 Subject: [PATCH 178/407] Sync SDL3 wiki -> header [ci skip] --- docs/README-platforms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README-platforms.md b/docs/README-platforms.md index e938eece6a..98e8600057 100644 --- a/docs/README-platforms.md +++ b/docs/README-platforms.md @@ -12,7 +12,7 @@ SDL3 has been known to work on the following platforms at some point: - [Linux](README-linux.md) - [macOS](README-macos.md) (10.14 and later) - [NetBSD](README-bsd.md) -- [Nintendo Switch](README-switch.md) (Separate NDA-only fork) +- [Nintendo Switch and Switch 2](README-switch.md) (Separate NDA-only fork) - [Nintendo 3DS](README-n3ds.md) (Homebrew) - [Nokia N-Gage](README-ngage.md) - [OpenBSD](README-bsd.md) From 0bf2fa89784344973bceaa6f6163f46885ebf8e6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 09:33:46 -0400 Subject: [PATCH 179/407] internal: Replace SDL_PUSH_ERROR with SDL_PushError. Reference Issue #15458. --- src/SDL_error_c.h | 12 ------------ src/SDL_internal.h | 13 +++++++++---- src/video/SDL_video.c | 4 ++-- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h index 7d53783d88..2997c10fa3 100644 --- a/src/SDL_error_c.h +++ b/src/SDL_error_c.h @@ -52,16 +52,4 @@ typedef struct SDL_error // Defined in SDL_thread.c extern SDL_error *SDL_GetErrBuf(bool create); -// Macros to save and restore error values -#define SDL_PushError() \ - char *saved_error = SDL_strdup(SDL_GetError()) - -#define SDL_PopError() \ - do { \ - if (saved_error) { \ - SDL_SetError("%s", saved_error); \ - SDL_free(saved_error); \ - } \ - } while (0) - #endif // SDL_error_c_h_ diff --git a/src/SDL_internal.h b/src/SDL_internal.h index 967dab3c67..d8c3b4320f 100644 --- a/src/SDL_internal.h +++ b/src/SDL_internal.h @@ -276,11 +276,16 @@ extern SDL_NORETURN void SDL_ExitProcess(int exitcode); } while (0) #endif -#define PUSH_SDL_ERROR() \ - { char *_error = SDL_strdup(SDL_GetError()); +// Macros to save and restore error values +#define SDL_PushError() do { \ + char *saved_error = SDL_strdup(SDL_GetError()) -#define POP_SDL_ERROR() \ - SDL_SetError("%s", _error); SDL_free(_error); } +#define SDL_PopError() \ + if (saved_error) { \ + SDL_SetError("%s", saved_error); \ + SDL_free(saved_error); \ + } \ +} while (0) #if defined(SDL_DISABLE_INVALID_PARAMS) #ifdef DEBUG diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 8308eba5d9..0a387fad2a 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -2584,9 +2584,9 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props) SDL_UpdateWindowHierarchy(window, parent); if (_this->CreateSDLWindow && !_this->CreateSDLWindow(_this, window, props)) { - PUSH_SDL_ERROR() + SDL_PushError(); SDL_DestroyWindow(window); - POP_SDL_ERROR() + SDL_PopError(); return NULL; } From a74722ed746a54f176a1fb44c8d9d1ae7db3d950 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 10:25:25 -0400 Subject: [PATCH 180/407] coreaudio: Always init/deinit session listener on iOS. Previously, if UpdateAudioSession() failed on close--which it might if something strange has happened with the system's audio configuration--the listener wouldn't be deregistered, and would risk touching a free'd pointer if the app moved to or from the background afterwards, firing an event handler that should have been deregistered. Closes #15439. --- src/audio/coreaudio/SDL_coreaudio.m | 70 +++++++++++++++-------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index dda5f573c7..471a472c7f 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -502,39 +502,6 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl [session setActive:NO error:nil]; session_active = false; } - - if (open) { - SDLInterruptionListener *listener = [SDLInterruptionListener new]; - listener.device = device; - - [center addObserver:listener - selector:@selector(audioSessionInterruption:) - name:AVAudioSessionInterruptionNotification - object:session]; - - /* An interruption end notification is not guaranteed to be sent if - we were previously interrupted... resuming if needed when the app - becomes active seems to be the way to go. */ - // Note: object: below needs to be nil, as otherwise it filters by the object, and session doesn't send foreground / active notifications. - [center addObserver:listener - selector:@selector(applicationBecameActive:) - name:UIApplicationDidBecomeActiveNotification - object:nil]; - - [center addObserver:listener - selector:@selector(applicationBecameActive:) - name:UIApplicationWillEnterForegroundNotification - object:nil]; - - device->hidden->interruption_listener = CFBridgingRetain(listener); - } else { - SDLInterruptionListener *listener = nil; - listener = (SDLInterruptionListener *)CFBridgingRelease(device->hidden->interruption_listener); - [center removeObserver:listener]; - @synchronized(listener) { - listener.device = NULL; - } - } } return true; @@ -627,6 +594,17 @@ static void COREAUDIO_CloseDevice(SDL_AudioDevice *device) return; } + #ifndef MACOSX_COREAUDIO + if (device->hidden->interruption_listener) { + SDLInterruptionListener *listener = (SDLInterruptionListener *)CFBridgingRelease(device->hidden->interruption_listener); + device->hidden->interruption_listener = nil; + [center removeObserver:listener]; + @synchronized(listener) { + listener.device = NULL; + } + } + #endif + // dispose of the audio queue before waiting on the thread, or it might stall for a long time! if (device->hidden->audioQueue) { AudioQueueFlush(device->hidden->audioQueue); @@ -998,6 +976,32 @@ static bool COREAUDIO_OpenDevice(SDL_AudioDevice *device) return SDL_SetError("%s", device->hidden->thread_error); } +#ifndef MACOSX_COREAUDIO + SDLInterruptionListener *listener = [SDLInterruptionListener new]; + listener.device = device; + + [center addObserver:listener + selector:@selector(audioSessionInterruption:) + name:AVAudioSessionInterruptionNotification + object:session]; + + /* An interruption end notification is not guaranteed to be sent if + we were previously interrupted... resuming if needed when the app + becomes active seems to be the way to go. */ + // Note: object: below needs to be nil, as otherwise it filters by the object, and session doesn't send foreground / active notifications. + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + + device->hidden->interruption_listener = CFBridgingRetain(listener); +#endif + return (device->hidden->thread != NULL); } From 62ea2968944b6eb709d0c945f21f0abb3f5bec9c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 10:39:06 -0400 Subject: [PATCH 181/407] coreaudio: Patched to compile on iOS. --- src/audio/coreaudio/SDL_coreaudio.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 471a472c7f..c7f6209245 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -598,7 +598,7 @@ static void COREAUDIO_CloseDevice(SDL_AudioDevice *device) if (device->hidden->interruption_listener) { SDLInterruptionListener *listener = (SDLInterruptionListener *)CFBridgingRelease(device->hidden->interruption_listener); device->hidden->interruption_listener = nil; - [center removeObserver:listener]; + [[NSNotificationCenter defaultCenter] removeObserver:listener]; @synchronized(listener) { listener.device = NULL; } @@ -977,6 +977,7 @@ static bool COREAUDIO_OpenDevice(SDL_AudioDevice *device) } #ifndef MACOSX_COREAUDIO + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; SDLInterruptionListener *listener = [SDLInterruptionListener new]; listener.device = device; From 1226725e9ac1321614e1ecd0d7f245285bd73131 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 27 Apr 2026 18:04:02 +0300 Subject: [PATCH 182/407] docs/README-platforms.md: Add DOS. [ci skip] --- docs/README-platforms.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README-platforms.md b/docs/README-platforms.md index 98e8600057..6b280f3ff1 100644 --- a/docs/README-platforms.md +++ b/docs/README-platforms.md @@ -5,6 +5,7 @@ SDL3 has been known to work on the following platforms at some point: - [Android](README-android.md) +- [DOS](README-dos.md) - [Emscripten](README-emscripten.md) (Web browsers) - [FreeBSD](README-bsd.md) - [Haiku OS](README-haiku.md) From fe6c1f113402cbdf708e14533c18710f371b52de Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 11:46:15 -0400 Subject: [PATCH 183/407] coreaudio: Patched to compile, again, on iOS. --- src/audio/coreaudio/SDL_coreaudio.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index c7f6209245..5342d3d28d 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -406,7 +406,6 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl { @autoreleasepool { AVAudioSession *session = [AVAudioSession sharedInstance]; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; NSString *category = AVAudioSessionCategoryPlayback; NSString *mode = AVAudioSessionModeDefault; @@ -984,7 +983,7 @@ static bool COREAUDIO_OpenDevice(SDL_AudioDevice *device) [center addObserver:listener selector:@selector(audioSessionInterruption:) name:AVAudioSessionInterruptionNotification - object:session]; + object:[AVAudioSession sharedInstance]]; /* An interruption end notification is not guaranteed to be sent if we were previously interrupted... resuming if needed when the app From 73fc274ef7f96e181ec217f54ed74e0dca91b771 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 27 Apr 2026 12:29:55 -0400 Subject: [PATCH 184/407] renderer: Check the surface validity flag when re-acquiring the surface in the software renderer If a size change occurs, the sdl2-compat event handler will flush the renderer, which will cause the software renderer to re-acquire a surface that was invalidated due to the size change. However, if the OnWindowPixelSizeChanged handler is called afterward, the invalid flag will be set on the surface, causing presentation to fail. Check both for a null surface pointer and an invalid surface flag when checking surface validity in the software renderer. --- src/render/software/SDL_render_sw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 160e2a10be..ce3a3f5165 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -34,6 +34,7 @@ #include "SDL_triangle.h" #include "../../video/SDL_pixels_c.h" #include "../../video/SDL_rotate.h" +#include "../../video/SDL_sysvideo.h" // SDL surface based renderer implementation @@ -54,12 +55,13 @@ typedef struct static SDL_Surface *SW_ActivateRenderer(SDL_Renderer *renderer) { SW_RenderData *data = (SW_RenderData *)renderer->internal; + SDL_Window *window = renderer->window; if (!data->surface) { data->surface = data->window; } - if (!data->surface) { - SDL_Surface *surface = SDL_GetWindowSurface(renderer->window); + if (window && (!data->surface || !window->surface_valid)) { + SDL_Surface *surface = SDL_GetWindowSurface(window); if (surface) { data->surface = data->window = surface; } From 6f952a8e636b8c3173075ddf1fd9458489adedf3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Apr 2026 10:06:00 -0700 Subject: [PATCH 185/407] testime: use the correct properties when enabling text input --- test/testime.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/testime.c b/test/testime.c index e9d30aa53b..9005f17f50 100644 --- a/test/testime.c +++ b/test/testime.c @@ -478,7 +478,7 @@ static void InitInput(WindowState *ctx) { /* Prepare a rect for text input */ ctx->textRect.x = 100.0f; - ctx->textRect.y = 250.0f; + ctx->textRect.y = 250.0f; ctx->textRect.w = DEFAULT_WINDOW_WIDTH - 2 * ctx->textRect.x; ctx->textRect.h = 50.0f; ctx->markedRect = ctx->textRect; @@ -1066,7 +1066,7 @@ int main(int argc, char *argv[]) SDL_StopTextInput(ctx->window); } else { SDL_Log("Enabling text input\n"); - SDL_StartTextInput(ctx->window); + SDL_StartTextInputWithProperties(ctx->window, ctx->text_settings); } } break; @@ -1113,12 +1113,14 @@ int main(int argc, char *argv[]) int index = (event.key.key - SDLK_KP_1); if (index < state->num_windows) { SDL_Window *window = state->windows[index]; + ctx = &windowstate[index]; if (SDL_TextInputActive(window)) { SDL_Log("Disabling text input for window %d\n", 1 + index); SDL_StopTextInput(window); } else { SDL_Log("Enabling text input for window %d\n", 1 + index); SDL_StartTextInput(window); + SDL_StartTextInputWithProperties(window, ctx->text_settings); } } } From dcf05165d389af01d5680b66e2656c2cdc5a24ca Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Apr 2026 09:57:31 -0700 Subject: [PATCH 186/407] Use SDL_SendScreenKeyboardShown() and SDL_SendScreenKeyboardHidden() on iOS We now have events for on-screen keyboard visibility, so we should use these instead of starting and stopping text input. Fixes https://github.com/libsdl-org/SDL/issues/15437 Confirmed not to regress the fix in https://github.com/libsdl-org/SDL/pull/11845 --- src/video/uikit/SDL_uikitviewcontroller.h | 2 + src/video/uikit/SDL_uikitviewcontroller.m | 46 ++++++----------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index f42f586d89..a758de7ff5 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -75,7 +75,9 @@ - (void)deinitKeyboard; - (void)keyboardWillShow:(NSNotification *)notification; +- (void)keyboardDidShow:(NSNotification *)notification; - (void)keyboardWillHide:(NSNotification *)notification; +- (void)keyboardDidHide:(NSNotification *)notification; - (void)updateKeyboard; diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index ffb822d919..bbb49f835a 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -75,7 +75,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #ifdef SDL_IPHONE_KEYBOARD SDLUITextField *textField; - BOOL hidingKeyboard; BOOL rotatingOrientation; NSString *committedText; NSString *obligateForBackspace; @@ -92,7 +91,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #ifdef SDL_IPHONE_KEYBOARD [self initKeyboard]; - hidingKeyboard = NO; rotatingOrientation = NO; #endif @@ -289,6 +287,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [center addObserver:self + selector:@selector(keyboardDidShow:) + name:UIKeyboardDidShowNotification + object:nil]; [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification @@ -373,6 +375,9 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [center removeObserver:self + name:UIKeyboardDidShowNotification + object:nil]; [center removeObserver:self name:UIKeyboardWillHideNotification object:nil]; @@ -543,49 +548,25 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [self setKeyboardHeight:(int)kbrect.size.height]; #endif +} - /* A keyboard hide transition has been interrupted with a show (keyboardWillHide has been called but keyboardDidHide didn't). - * since text input was stopped by the hide, we have to start it again. */ - if (hidingKeyboard) { - SDL_StartTextInput(window); - hidingKeyboard = NO; - } +- (void)keyboardDidShow:(NSNotification *)notification +{ + SDL_SendScreenKeyboardShown(); } - (void)keyboardWillHide:(NSNotification *)notification { - hidingKeyboard = YES; [self setKeyboardHeight:0]; - - /* When the user dismisses the software keyboard by the "hide" button in the bottom right corner, - * we want to reflect that on SDL_TextInputActive by calling SDL_StopTextInput...on certain conditions */ - if (SDL_TextInputActive(window) - /* keyboardWillHide gets called when a hardware keyboard is attached, - * keep text input state active if hiding while there is a hardware keyboard. - * if the hardware keyboard gets detached, the software keyboard will appear anyway. */ - && !SDL_HasKeyboard() - /* When the device changes orientation, a sequence of hide and show transitions are triggered. - * keep text input state active in this case. */ - && !rotatingOrientation) { - SDL_StopTextInput(window); - } } - (void)keyboardDidHide:(NSNotification *)notification { - hidingKeyboard = NO; + SDL_SendScreenKeyboardHidden(); } - (void)textFieldTextDidChange:(NSNotification *)notification { - // When opening a password manager overlay to select a password and have it auto-filled, - // text input becomes stopped as a result of the keyboard being hidden or the text field losing focus. - // As a workaround, ensure text input is activated on any changes to the text field. - bool startTextInputMomentarily = !SDL_TextInputActive(window); - - if (startTextInputMomentarily) - SDL_StartTextInput(window); - if (textField.markedTextRange == nil) { if (isOTPMode && labs((NSInteger)textField.text.length - (NSInteger)committedText.length) != 1) { return; @@ -624,9 +605,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char } committedText = textField.text; } - - if (startTextInputMomentarily) - SDL_StopTextInput(window); } - (void)updateKeyboard From b7726026f8fd9d5bf3c39a8566162db23f755e7d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Apr 2026 10:18:25 -0700 Subject: [PATCH 187/407] Fixed double-backspace with hardware keyboard on iOS --- src/video/uikit/SDL_uikitviewcontroller.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index bbb49f835a..e9b48c2e01 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -581,7 +581,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char break; } } - if (matchLength < committedText.length) { + if (matchLength < committedText.length && !SDL_HasKeyboard()) { size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]); while (deleteLength > 0) { // Send distinct down and up events for each backspace action From 66e98b5598d840b3e4d767ace145b197bc0a9962 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 24 Apr 2026 22:52:17 -0500 Subject: [PATCH 188/407] atomic: Fix infinite recursion in SDL_CompilerBarrier() fallback On some platforms, SDL_MemoryBarrierRelease() is defined to SDL_CompilerBarrier(). If SDL_CompilerBarrier() is also defined to the fallback spinlock acquire/release, then we will infinitely recurse in SDL_UnlockSpinlock(). Avoid this by not unlocking the temporary spinlock we create. --- include/SDL3/SDL_atomic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index b6094b2550..f1a8e0638d 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -169,8 +169,9 @@ void _ReadWriteBarrier(void); extern __inline void SDL_CompilerBarrier(void); #pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; #else +/* We don't unlock here to avoid possible infinite recursion */ #define SDL_CompilerBarrier() \ -{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); } +{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); } #endif /** From 30aeb330f24223f824f26b71cfd4bf9219c286c9 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Mon, 27 Apr 2026 18:38:02 +0000 Subject: [PATCH 189/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_openxr.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/SDL3/SDL_openxr.h b/include/SDL3/SDL_openxr.h index ceb9790c57..4b682769df 100644 --- a/include/SDL3/SDL_openxr.h +++ b/include/SDL3/SDL_openxr.h @@ -24,9 +24,8 @@ * * Functions for creating OpenXR handles for SDL_gpu contexts. * - * For the most part, OpenXR operates independent of SDL, but - * the graphics initialization depends on direct support from SDL_gpu. - * + * For the most part, OpenXR operates independent of SDL, but the graphics + * initialization depends on direct support from SDL_gpu. */ #ifndef SDL_openxr_h_ From 6d9b470e84921a847bd641e02920efd81baa22bf Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 14:41:45 -0400 Subject: [PATCH 190/407] SDL_openxr.h: tweak the category docs language slightly. --- include/SDL3/SDL_openxr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_openxr.h b/include/SDL3/SDL_openxr.h index 4b682769df..3328c01d77 100644 --- a/include/SDL3/SDL_openxr.h +++ b/include/SDL3/SDL_openxr.h @@ -22,10 +22,10 @@ /** * # CategoryOpenXR * - * Functions for creating OpenXR handles for SDL_gpu contexts. + * Functions for creating OpenXR handles for [GPU API](CategoryGPU) contexts. * * For the most part, OpenXR operates independent of SDL, but the graphics - * initialization depends on direct support from SDL_gpu. + * initialization depends on direct support from the GPU API. */ #ifndef SDL_openxr_h_ From 96a061e1b1ab2318ea841cd9a391ba70c7cabc34 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 14:42:10 -0400 Subject: [PATCH 191/407] SDL_openxr.h: Wrap some non-SDL pieces in `!SDL_WIKI_DOCUMENTATION_SECTION`. --- include/SDL3/SDL_openxr.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/SDL3/SDL_openxr.h b/include/SDL3/SDL_openxr.h index 3328c01d77..bff2d73d12 100644 --- a/include/SDL3/SDL_openxr.h +++ b/include/SDL3/SDL_openxr.h @@ -40,6 +40,8 @@ extern "C" { #endif +#ifndef SDL_WIKI_DOCUMENTATION_SECTION + #if defined(OPENXR_H_) #define NO_SDL_OPENXR_TYPEDEFS 1 #endif /* OPENXR_H_ */ @@ -78,6 +80,9 @@ typedef enum XrResult { #define PFN_xrGetInstanceProcAddr SDL_FunctionPointer #endif /* NO_SDL_OPENXR_TYPEDEFS */ +#endif /* !SDL_WIKI_DOCUMENTATION_SECTION */ + + /** * Creates an OpenXR session. * From 364c8037f45b8b2110451575aca2c40f50d8a5c5 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Mon, 27 Apr 2026 18:46:49 +0000 Subject: [PATCH 192/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_openxr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_openxr.h b/include/SDL3/SDL_openxr.h index bff2d73d12..a017983952 100644 --- a/include/SDL3/SDL_openxr.h +++ b/include/SDL3/SDL_openxr.h @@ -22,10 +22,10 @@ /** * # CategoryOpenXR * - * Functions for creating OpenXR handles for [GPU API](CategoryGPU) contexts. + * Functions for creating OpenXR handles for SDL_gpu contexts. * * For the most part, OpenXR operates independent of SDL, but the graphics - * initialization depends on direct support from the GPU API. + * initialization depends on direct support from SDL_gpu. */ #ifndef SDL_openxr_h_ From 085447a56e889abfaa4317b2a9c6d0826774d26a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 27 Apr 2026 00:58:38 +0200 Subject: [PATCH 193/407] apple: add exports file --- CMakeLists.txt | 4 + Xcode/SDL/SDL.xcodeproj/project.pbxproj | 2 + src/dynapi/SDL_dynapi.exports | 1287 +++++++++++++++++++++++ src/dynapi/gendynapi.py | 13 +- 4 files changed, 1303 insertions(+), 3 deletions(-) create mode 100644 src/dynapi/SDL_dynapi.exports diff --git a/CMakeLists.txt b/CMakeLists.txt index 6959d9f5c9..e591a011c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4055,6 +4055,10 @@ if(SDL_SHARED) MACHO_COMPATIBILITY_VERSION "${SDL_DYLIB_COMPAT_VERSION}" MACHO_CURRENT_VERSION "${SDL_DYLIB_CURRENT_VERSION}" ) + set_property(TARGET SDL3-shared APPEND PROPERTY LINK_DEPENDS + "${PROJECT_SOURCE_DIR}/src/dynapi/SDL_dynapi.exports") + target_link_options(SDL3-shared PRIVATE + "SHELL:-Wl,-exported_symbols_list,${PROJECT_SOURCE_DIR}/src/dynapi/SDL_dynapi.exports") if(SDL_FRAMEWORK) set_target_properties(SDL3-shared PROPERTIES PUBLIC_HEADER "${SDL3_INCLUDE_FILES}" diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 7ce097403f..3704aa73ee 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3243,6 +3243,7 @@ GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../../src/dynapi/SDL_dynapi.exports"; OTHER_LDFLAGS = "-liconv"; SUPPORTS_MACCATALYST = YES; }; @@ -3308,6 +3309,7 @@ GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../../src/dynapi/SDL_dynapi.exports"; OTHER_LDFLAGS = "-liconv"; SUPPORTS_MACCATALYST = YES; }; diff --git a/src/dynapi/SDL_dynapi.exports b/src/dynapi/SDL_dynapi.exports new file mode 100644 index 0000000000..5953db3622 --- /dev/null +++ b/src/dynapi/SDL_dynapi.exports @@ -0,0 +1,1287 @@ +# SDL3.dylib exports +_JNI_OnLoad +_SDL_DYNAPI_entry +_SDL_AcquireCameraFrame +_SDL_AcquireGPUCommandBuffer +_SDL_AcquireGPUSwapchainTexture +_SDL_AddAtomicInt +_SDL_AddEventWatch +_SDL_AddGamepadMapping +_SDL_AddGamepadMappingsFromFile +_SDL_AddGamepadMappingsFromIO +_SDL_AddHintCallback +_SDL_AddSurfaceAlternateImage +_SDL_AddTimer +_SDL_AddTimerNS +_SDL_AddVulkanRenderSemaphores +_SDL_AttachVirtualJoystick +_SDL_AudioDevicePaused +_SDL_BeginGPUComputePass +_SDL_BeginGPUCopyPass +_SDL_BeginGPURenderPass +_SDL_BindAudioStream +_SDL_BindAudioStreams +_SDL_BindGPUComputePipeline +_SDL_BindGPUComputeSamplers +_SDL_BindGPUComputeStorageBuffers +_SDL_BindGPUComputeStorageTextures +_SDL_BindGPUFragmentSamplers +_SDL_BindGPUFragmentStorageBuffers +_SDL_BindGPUFragmentStorageTextures +_SDL_BindGPUGraphicsPipeline +_SDL_BindGPUIndexBuffer +_SDL_BindGPUVertexBuffers +_SDL_BindGPUVertexSamplers +_SDL_BindGPUVertexStorageBuffers +_SDL_BindGPUVertexStorageTextures +_SDL_BlitGPUTexture +_SDL_BlitSurface9Grid +_SDL_BlitSurface +_SDL_BlitSurfaceScaled +_SDL_BlitSurfaceTiled +_SDL_BlitSurfaceTiledWithScale +_SDL_BlitSurfaceUnchecked +_SDL_BlitSurfaceUncheckedScaled +_SDL_BroadcastCondition +_SDL_CaptureMouse +_SDL_ClaimWindowForGPUDevice +_SDL_CleanupTLS +_SDL_ClearAudioStream +_SDL_ClearClipboardData +_SDL_ClearComposition +_SDL_ClearError +_SDL_ClearProperty +_SDL_ClearSurface +_SDL_CloseAudioDevice +_SDL_CloseCamera +_SDL_CloseGamepad +_SDL_CloseHaptic +_SDL_CloseIO +_SDL_CloseJoystick +_SDL_CloseSensor +_SDL_CloseStorage +_SDL_CompareAndSwapAtomicInt +_SDL_CompareAndSwapAtomicPointer +_SDL_CompareAndSwapAtomicU32 +_SDL_ComposeCustomBlendMode +_SDL_ConvertAudioSamples +_SDL_ConvertEventToRenderCoordinates +_SDL_ConvertPixels +_SDL_ConvertPixelsAndColorspace +_SDL_ConvertSurface +_SDL_ConvertSurfaceAndColorspace +_SDL_CopyFile +_SDL_CopyGPUBufferToBuffer +_SDL_CopyGPUTextureToTexture +_SDL_CopyProperties +_SDL_CopyStorageFile +_SDL_CreateAudioStream +_SDL_CreateColorCursor +_SDL_CreateCondition +_SDL_CreateCursor +_SDL_CreateDirectory +_SDL_CreateEnvironment +_SDL_CreateGPUBuffer +_SDL_CreateGPUComputePipeline +_SDL_CreateGPUDevice +_SDL_CreateGPUDeviceWithProperties +_SDL_CreateGPUGraphicsPipeline +_SDL_CreateGPUSampler +_SDL_CreateGPUShader +_SDL_CreateGPUTexture +_SDL_CreateGPUTransferBuffer +_SDL_CreateHapticEffect +_SDL_CreateMutex +_SDL_CreatePalette +_SDL_CreatePopupWindow +_SDL_CreateProcess +_SDL_CreateProcessWithProperties +_SDL_CreateProperties +_SDL_CreateRWLock +_SDL_CreateRenderer +_SDL_CreateRendererWithProperties +_SDL_CreateSemaphore +_SDL_CreateSoftwareRenderer +_SDL_CreateStorageDirectory +_SDL_CreateSurface +_SDL_CreateSurfaceFrom +_SDL_CreateSurfacePalette +_SDL_CreateSystemCursor +_SDL_CreateTexture +_SDL_CreateTextureFromSurface +_SDL_CreateTextureWithProperties +_SDL_CreateThreadRuntime +_SDL_CreateThreadWithPropertiesRuntime +_SDL_CreateWindow +_SDL_CreateWindowAndRenderer +_SDL_CreateWindowWithProperties +_SDL_CursorVisible +_SDL_DateTimeToTime +_SDL_Delay +_SDL_DelayNS +_SDL_DestroyAudioStream +_SDL_DestroyCondition +_SDL_DestroyCursor +_SDL_DestroyEnvironment +_SDL_DestroyGPUDevice +_SDL_DestroyHapticEffect +_SDL_DestroyMutex +_SDL_DestroyPalette +_SDL_DestroyProcess +_SDL_DestroyProperties +_SDL_DestroyRWLock +_SDL_DestroyRenderer +_SDL_DestroySemaphore +_SDL_DestroySurface +_SDL_DestroyTexture +_SDL_DestroyWindow +_SDL_DestroyWindowSurface +_SDL_DetachThread +_SDL_DetachVirtualJoystick +_SDL_DisableScreenSaver +_SDL_DispatchGPUCompute +_SDL_DispatchGPUComputeIndirect +_SDL_DownloadFromGPUBuffer +_SDL_DownloadFromGPUTexture +_SDL_DrawGPUIndexedPrimitives +_SDL_DrawGPUIndexedPrimitivesIndirect +_SDL_DrawGPUPrimitives +_SDL_DrawGPUPrimitivesIndirect +_SDL_DuplicateSurface +_SDL_EGL_GetCurrentConfig +_SDL_EGL_GetCurrentDisplay +_SDL_EGL_GetProcAddress +_SDL_EGL_GetWindowSurface +_SDL_EGL_SetAttributeCallbacks +_SDL_EnableScreenSaver +_SDL_EndGPUComputePass +_SDL_EndGPUCopyPass +_SDL_EndGPURenderPass +_SDL_EnterAppMainCallbacks +_SDL_EnumerateDirectory +_SDL_EnumerateProperties +_SDL_EnumerateStorageDirectory +_SDL_EventEnabled +_SDL_FillSurfaceRect +_SDL_FillSurfaceRects +_SDL_FilterEvents +_SDL_FlashWindow +_SDL_FlipSurface +_SDL_FlushAudioStream +_SDL_FlushEvent +_SDL_FlushEvents +_SDL_FlushIO +_SDL_FlushRenderer +_SDL_GDKResumeGPU +_SDL_GDKSuspendComplete +_SDL_GDKSuspendGPU +_SDL_GL_CreateContext +_SDL_GL_DestroyContext +_SDL_GL_ExtensionSupported +_SDL_GL_GetAttribute +_SDL_GL_GetCurrentContext +_SDL_GL_GetCurrentWindow +_SDL_GL_GetProcAddress +_SDL_GL_GetSwapInterval +_SDL_GL_LoadLibrary +_SDL_GL_MakeCurrent +_SDL_GL_ResetAttributes +_SDL_GL_SetAttribute +_SDL_GL_SetSwapInterval +_SDL_GL_SwapWindow +_SDL_GL_UnloadLibrary +_SDL_GPUSupportsProperties +_SDL_GPUSupportsShaderFormats +_SDL_GPUTextureFormatTexelBlockSize +_SDL_GPUTextureSupportsFormat +_SDL_GPUTextureSupportsSampleCount +_SDL_GUIDToString +_SDL_GamepadConnected +_SDL_GamepadEventsEnabled +_SDL_GamepadHasAxis +_SDL_GamepadHasButton +_SDL_GamepadHasSensor +_SDL_GamepadSensorEnabled +_SDL_GenerateMipmapsForGPUTexture +_SDL_GetAndroidActivity +_SDL_GetAndroidCachePath +_SDL_GetAndroidExternalStoragePath +_SDL_GetAndroidExternalStorageState +_SDL_GetAndroidInternalStoragePath +_SDL_GetAndroidJNIEnv +_SDL_GetAndroidSDKVersion +_SDL_GetAppMetadataProperty +_SDL_GetAssertionHandler +_SDL_GetAssertionReport +_SDL_GetAtomicInt +_SDL_GetAtomicPointer +_SDL_GetAtomicU32 +_SDL_GetAudioDeviceChannelMap +_SDL_GetAudioDeviceFormat +_SDL_GetAudioDeviceGain +_SDL_GetAudioDeviceName +_SDL_GetAudioDriver +_SDL_GetAudioFormatName +_SDL_GetAudioPlaybackDevices +_SDL_GetAudioRecordingDevices +_SDL_GetAudioStreamAvailable +_SDL_GetAudioStreamData +_SDL_GetAudioStreamDevice +_SDL_GetAudioStreamFormat +_SDL_GetAudioStreamFrequencyRatio +_SDL_GetAudioStreamGain +_SDL_GetAudioStreamInputChannelMap +_SDL_GetAudioStreamOutputChannelMap +_SDL_GetAudioStreamProperties +_SDL_GetAudioStreamQueued +_SDL_GetBasePath +_SDL_GetBooleanProperty +_SDL_GetCPUCacheLineSize +_SDL_GetCameraDriver +_SDL_GetCameraFormat +_SDL_GetCameraID +_SDL_GetCameraName +_SDL_GetCameraPermissionState +_SDL_GetCameraPosition +_SDL_GetCameraProperties +_SDL_GetCameraSupportedFormats +_SDL_GetCameras +_SDL_GetClipboardData +_SDL_GetClipboardMimeTypes +_SDL_GetClipboardText +_SDL_GetClosestFullscreenDisplayMode +_SDL_GetCurrentAudioDriver +_SDL_GetCurrentCameraDriver +_SDL_GetCurrentDisplayMode +_SDL_GetCurrentDisplayOrientation +_SDL_GetCurrentRenderOutputSize +_SDL_GetCurrentThreadID +_SDL_GetCurrentTime +_SDL_GetCurrentVideoDriver +_SDL_GetCursor +_SDL_GetDXGIOutputInfo +_SDL_GetDateTimeLocalePreferences +_SDL_GetDayOfWeek +_SDL_GetDayOfYear +_SDL_GetDaysInMonth +_SDL_GetDefaultAssertionHandler +_SDL_GetDefaultCursor +_SDL_GetDesktopDisplayMode +_SDL_GetDirect3D9AdapterIndex +_SDL_GetDisplayBounds +_SDL_GetDisplayContentScale +_SDL_GetDisplayForPoint +_SDL_GetDisplayForRect +_SDL_GetDisplayForWindow +_SDL_GetDisplayName +_SDL_GetDisplayProperties +_SDL_GetDisplayUsableBounds +_SDL_GetDisplays +_SDL_GetEnvironment +_SDL_GetEnvironmentVariable +_SDL_GetEnvironmentVariables +_SDL_GetError +_SDL_GetEventFilter +_SDL_GetFloatProperty +_SDL_GetFullscreenDisplayModes +_SDL_GetGDKDefaultUser +_SDL_GetGDKTaskQueue +_SDL_GetGPUDeviceDriver +_SDL_GetGPUDriver +_SDL_GetGPUShaderFormats +_SDL_GetGPUSwapchainTextureFormat +_SDL_GetGamepadAppleSFSymbolsNameForAxis +_SDL_GetGamepadAppleSFSymbolsNameForButton +_SDL_GetGamepadAxis +_SDL_GetGamepadAxisFromString +_SDL_GetGamepadBindings +_SDL_GetGamepadButton +_SDL_GetGamepadButtonFromString +_SDL_GetGamepadButtonLabel +_SDL_GetGamepadButtonLabelForType +_SDL_GetGamepadConnectionState +_SDL_GetGamepadFirmwareVersion +_SDL_GetGamepadFromID +_SDL_GetGamepadFromPlayerIndex +_SDL_GetGamepadGUIDForID +_SDL_GetGamepadID +_SDL_GetGamepadJoystick +_SDL_GetGamepadMapping +_SDL_GetGamepadMappingForGUID +_SDL_GetGamepadMappingForID +_SDL_GetGamepadMappings +_SDL_GetGamepadName +_SDL_GetGamepadNameForID +_SDL_GetGamepadPath +_SDL_GetGamepadPathForID +_SDL_GetGamepadPlayerIndex +_SDL_GetGamepadPlayerIndexForID +_SDL_GetGamepadPowerInfo +_SDL_GetGamepadProduct +_SDL_GetGamepadProductForID +_SDL_GetGamepadProductVersion +_SDL_GetGamepadProductVersionForID +_SDL_GetGamepadProperties +_SDL_GetGamepadSensorData +_SDL_GetGamepadSensorDataRate +_SDL_GetGamepadSerial +_SDL_GetGamepadSteamHandle +_SDL_GetGamepadStringForAxis +_SDL_GetGamepadStringForButton +_SDL_GetGamepadStringForType +_SDL_GetGamepadTouchpadFinger +_SDL_GetGamepadType +_SDL_GetGamepadTypeForID +_SDL_GetGamepadTypeFromString +_SDL_GetGamepadVendor +_SDL_GetGamepadVendorForID +_SDL_GetGamepads +_SDL_GetGlobalMouseState +_SDL_GetGlobalProperties +_SDL_GetGrabbedWindow +_SDL_GetHapticEffectStatus +_SDL_GetHapticFeatures +_SDL_GetHapticFromID +_SDL_GetHapticID +_SDL_GetHapticName +_SDL_GetHapticNameForID +_SDL_GetHaptics +_SDL_GetHint +_SDL_GetHintBoolean +_SDL_GetIOProperties +_SDL_GetIOSize +_SDL_GetIOStatus +_SDL_GetJoystickAxis +_SDL_GetJoystickAxisInitialState +_SDL_GetJoystickBall +_SDL_GetJoystickButton +_SDL_GetJoystickConnectionState +_SDL_GetJoystickFirmwareVersion +_SDL_GetJoystickFromID +_SDL_GetJoystickFromPlayerIndex +_SDL_GetJoystickGUID +_SDL_GetJoystickGUIDForID +_SDL_GetJoystickGUIDInfo +_SDL_GetJoystickHat +_SDL_GetJoystickID +_SDL_GetJoystickName +_SDL_GetJoystickNameForID +_SDL_GetJoystickPath +_SDL_GetJoystickPathForID +_SDL_GetJoystickPlayerIndex +_SDL_GetJoystickPlayerIndexForID +_SDL_GetJoystickPowerInfo +_SDL_GetJoystickProduct +_SDL_GetJoystickProductForID +_SDL_GetJoystickProductVersion +_SDL_GetJoystickProductVersionForID +_SDL_GetJoystickProperties +_SDL_GetJoystickSerial +_SDL_GetJoystickType +_SDL_GetJoystickTypeForID +_SDL_GetJoystickVendor +_SDL_GetJoystickVendorForID +_SDL_GetJoysticks +_SDL_GetKeyFromName +_SDL_GetKeyFromScancode +_SDL_GetKeyName +_SDL_GetKeyboardFocus +_SDL_GetKeyboardNameForID +_SDL_GetKeyboardState +_SDL_GetKeyboards +_SDL_GetLogOutputFunction +_SDL_GetLogPriority +_SDL_GetMasksForPixelFormat +_SDL_GetMaxHapticEffects +_SDL_GetMaxHapticEffectsPlaying +_SDL_GetMemoryFunctions +_SDL_GetMice +_SDL_GetModState +_SDL_GetMouseFocus +_SDL_GetMouseNameForID +_SDL_GetMouseState +_SDL_GetNaturalDisplayOrientation +_SDL_GetNumAllocations +_SDL_GetNumAudioDrivers +_SDL_GetNumCameraDrivers +_SDL_GetNumGPUDrivers +_SDL_GetNumGamepadTouchpadFingers +_SDL_GetNumGamepadTouchpads +_SDL_GetNumHapticAxes +_SDL_GetNumJoystickAxes +_SDL_GetNumJoystickBalls +_SDL_GetNumJoystickButtons +_SDL_GetNumJoystickHats +_SDL_GetNumLogicalCPUCores +_SDL_GetNumRenderDrivers +_SDL_GetNumVideoDrivers +_SDL_GetNumberProperty +_SDL_GetOriginalMemoryFunctions +_SDL_GetPathInfo +_SDL_GetPerformanceCounter +_SDL_GetPerformanceFrequency +_SDL_GetPixelFormatDetails +_SDL_GetPixelFormatForMasks +_SDL_GetPixelFormatName +_SDL_GetPlatform +_SDL_GetPointerProperty +_SDL_GetPowerInfo +_SDL_GetPrefPath +_SDL_GetPreferredLocales +_SDL_GetPrimaryDisplay +_SDL_GetPrimarySelectionText +_SDL_GetProcessInput +_SDL_GetProcessOutput +_SDL_GetProcessProperties +_SDL_GetPropertyType +_SDL_GetRGB +_SDL_GetRGBA +_SDL_GetRealGamepadType +_SDL_GetRealGamepadTypeForID +_SDL_GetRectAndLineIntersection +_SDL_GetRectAndLineIntersectionFloat +_SDL_GetRectEnclosingPoints +_SDL_GetRectEnclosingPointsFloat +_SDL_GetRectIntersection +_SDL_GetRectIntersectionFloat +_SDL_GetRectUnion +_SDL_GetRectUnionFloat +_SDL_GetRelativeMouseState +_SDL_GetRenderClipRect +_SDL_GetRenderColorScale +_SDL_GetRenderDrawBlendMode +_SDL_GetRenderDrawColor +_SDL_GetRenderDrawColorFloat +_SDL_GetRenderDriver +_SDL_GetRenderLogicalPresentation +_SDL_GetRenderLogicalPresentationRect +_SDL_GetRenderMetalCommandEncoder +_SDL_GetRenderMetalLayer +_SDL_GetRenderOutputSize +_SDL_GetRenderSafeArea +_SDL_GetRenderScale +_SDL_GetRenderTarget +_SDL_GetRenderVSync +_SDL_GetRenderViewport +_SDL_GetRenderWindow +_SDL_GetRenderer +_SDL_GetRendererFromTexture +_SDL_GetRendererName +_SDL_GetRendererProperties +_SDL_GetRevision +_SDL_GetSIMDAlignment +_SDL_GetScancodeFromKey +_SDL_GetScancodeFromName +_SDL_GetScancodeName +_SDL_GetSemaphoreValue +_SDL_GetSensorData +_SDL_GetSensorFromID +_SDL_GetSensorID +_SDL_GetSensorName +_SDL_GetSensorNameForID +_SDL_GetSensorNonPortableType +_SDL_GetSensorNonPortableTypeForID +_SDL_GetSensorProperties +_SDL_GetSensorType +_SDL_GetSensorTypeForID +_SDL_GetSensors +_SDL_GetSilenceValueForFormat +_SDL_GetStorageFileSize +_SDL_GetStoragePathInfo +_SDL_GetStorageSpaceRemaining +_SDL_GetStringProperty +_SDL_GetSurfaceAlphaMod +_SDL_GetSurfaceBlendMode +_SDL_GetSurfaceClipRect +_SDL_GetSurfaceColorKey +_SDL_GetSurfaceColorMod +_SDL_GetSurfaceColorspace +_SDL_GetSurfaceImages +_SDL_GetSurfacePalette +_SDL_GetSurfaceProperties +_SDL_GetSystemRAM +_SDL_GetSystemTheme +_SDL_GetTLS +_SDL_GetTextInputArea +_SDL_GetTextureAlphaMod +_SDL_GetTextureAlphaModFloat +_SDL_GetTextureBlendMode +_SDL_GetTextureColorMod +_SDL_GetTextureColorModFloat +_SDL_GetTextureProperties +_SDL_GetTextureScaleMode +_SDL_GetTextureSize +_SDL_GetThreadID +_SDL_GetThreadName +_SDL_GetTicks +_SDL_GetTicksNS +_SDL_GetTouchDeviceName +_SDL_GetTouchDeviceType +_SDL_GetTouchDevices +_SDL_GetTouchFingers +_SDL_GetUserFolder +_SDL_GetVersion +_SDL_GetVideoDriver +_SDL_GetWindowAspectRatio +_SDL_GetWindowBordersSize +_SDL_GetWindowDisplayScale +_SDL_GetWindowFlags +_SDL_GetWindowFromEvent +_SDL_GetWindowFromID +_SDL_GetWindowFullscreenMode +_SDL_GetWindowICCProfile +_SDL_GetWindowID +_SDL_GetWindowKeyboardGrab +_SDL_GetWindowMaximumSize +_SDL_GetWindowMinimumSize +_SDL_GetWindowMouseGrab +_SDL_GetWindowMouseRect +_SDL_GetWindowOpacity +_SDL_GetWindowParent +_SDL_GetWindowPixelDensity +_SDL_GetWindowPixelFormat +_SDL_GetWindowPosition +_SDL_GetWindowProperties +_SDL_GetWindowRelativeMouseMode +_SDL_GetWindowSafeArea +_SDL_GetWindowSize +_SDL_GetWindowSizeInPixels +_SDL_GetWindowSurface +_SDL_GetWindowSurfaceVSync +_SDL_GetWindowTitle +_SDL_GetWindows +_SDL_GlobDirectory +_SDL_GlobStorageDirectory +_SDL_HapticEffectSupported +_SDL_HapticRumbleSupported +_SDL_HasARMSIMD +_SDL_HasAVX2 +_SDL_HasAVX512F +_SDL_HasAVX +_SDL_HasAltiVec +_SDL_HasClipboardData +_SDL_HasClipboardText +_SDL_HasEvent +_SDL_HasEvents +_SDL_HasGamepad +_SDL_HasJoystick +_SDL_HasKeyboard +_SDL_HasLASX +_SDL_HasLSX +_SDL_HasMMX +_SDL_HasMouse +_SDL_HasNEON +_SDL_HasPrimarySelectionText +_SDL_HasProperty +_SDL_HasRectIntersection +_SDL_HasRectIntersectionFloat +_SDL_HasSSE2 +_SDL_HasSSE3 +_SDL_HasSSE41 +_SDL_HasSSE42 +_SDL_HasSSE +_SDL_HasScreenKeyboardSupport +_SDL_HideCursor +_SDL_HideWindow +_SDL_IOFromConstMem +_SDL_IOFromDynamicMem +_SDL_IOFromFile +_SDL_IOFromMem +_SDL_IOprintf +_SDL_IOvprintf +_SDL_Init +_SDL_InitHapticRumble +_SDL_InitSubSystem +_SDL_InsertGPUDebugLabel +_SDL_IsChromebook +_SDL_IsDeXMode +_SDL_IsGamepad +_SDL_IsJoystickHaptic +_SDL_IsJoystickVirtual +_SDL_IsMouseHaptic +_SDL_IsTV +_SDL_IsTablet +_SDL_JoystickConnected +_SDL_JoystickEventsEnabled +_SDL_KillProcess +_SDL_LoadBMP +_SDL_LoadBMP_IO +_SDL_LoadFile +_SDL_LoadFile_IO +_SDL_LoadFunction +_SDL_LoadObject +_SDL_LoadWAV +_SDL_LoadWAV_IO +_SDL_LockAudioStream +_SDL_LockJoysticks +_SDL_LockMutex +_SDL_LockProperties +_SDL_LockRWLockForReading +_SDL_LockRWLockForWriting +_SDL_LockSpinlock +_SDL_LockSurface +_SDL_LockTexture +_SDL_LockTextureToSurface +_SDL_Log +_SDL_LogCritical +_SDL_LogDebug +_SDL_LogError +_SDL_LogInfo +_SDL_LogMessage +_SDL_LogMessageV +_SDL_LogTrace +_SDL_LogVerbose +_SDL_LogWarn +_SDL_MapGPUTransferBuffer +_SDL_MapRGB +_SDL_MapRGBA +_SDL_MapSurfaceRGB +_SDL_MapSurfaceRGBA +_SDL_MaximizeWindow +_SDL_MemoryBarrierAcquireFunction +_SDL_MemoryBarrierReleaseFunction +_SDL_Metal_CreateView +_SDL_Metal_DestroyView +_SDL_Metal_GetLayer +_SDL_MinimizeWindow +_SDL_MixAudio +_SDL_OnApplicationDidChangeStatusBarOrientation +_SDL_OnApplicationDidEnterBackground +_SDL_OnApplicationDidEnterForeground +_SDL_OnApplicationDidReceiveMemoryWarning +_SDL_OnApplicationWillEnterBackground +_SDL_OnApplicationWillEnterForeground +_SDL_OnApplicationWillTerminate +_SDL_OpenAudioDevice +_SDL_OpenAudioDeviceStream +_SDL_OpenCamera +_SDL_OpenFileStorage +_SDL_OpenGamepad +_SDL_OpenHaptic +_SDL_OpenHapticFromJoystick +_SDL_OpenHapticFromMouse +_SDL_OpenIO +_SDL_OpenJoystick +_SDL_OpenSensor +_SDL_OpenStorage +_SDL_OpenTitleStorage +_SDL_OpenURL +_SDL_OpenUserStorage +_SDL_OutOfMemory +_SDL_PauseAudioDevice +_SDL_PauseAudioStreamDevice +_SDL_PauseHaptic +_SDL_PeepEvents +_SDL_PlayHapticRumble +_SDL_PollEvent +_SDL_PopGPUDebugGroup +_SDL_PremultiplyAlpha +_SDL_PremultiplySurfaceAlpha +_SDL_PumpEvents +_SDL_PushEvent +_SDL_PushGPUComputeUniformData +_SDL_PushGPUDebugGroup +_SDL_PushGPUFragmentUniformData +_SDL_PushGPUVertexUniformData +_SDL_PutAudioStreamData +_SDL_QueryGPUFence +_SDL_Quit +_SDL_QuitSubSystem +_SDL_RaiseWindow +_SDL_ReadIO +_SDL_ReadProcess +_SDL_ReadS16BE +_SDL_ReadS16LE +_SDL_ReadS32BE +_SDL_ReadS32LE +_SDL_ReadS64BE +_SDL_ReadS64LE +_SDL_ReadS8 +_SDL_ReadStorageFile +_SDL_ReadSurfacePixel +_SDL_ReadSurfacePixelFloat +_SDL_ReadU16BE +_SDL_ReadU16LE +_SDL_ReadU32BE +_SDL_ReadU32LE +_SDL_ReadU64BE +_SDL_ReadU64LE +_SDL_ReadU8 +_SDL_RegisterApp +_SDL_RegisterEvents +_SDL_ReleaseCameraFrame +_SDL_ReleaseGPUBuffer +_SDL_ReleaseGPUComputePipeline +_SDL_ReleaseGPUFence +_SDL_ReleaseGPUGraphicsPipeline +_SDL_ReleaseGPUSampler +_SDL_ReleaseGPUShader +_SDL_ReleaseGPUTexture +_SDL_ReleaseGPUTransferBuffer +_SDL_ReleaseWindowFromGPUDevice +_SDL_ReloadGamepadMappings +_SDL_RemoveEventWatch +_SDL_RemoveHintCallback +_SDL_RemovePath +_SDL_RemoveStoragePath +_SDL_RemoveSurfaceAlternateImages +_SDL_RemoveTimer +_SDL_RenamePath +_SDL_RenameStoragePath +_SDL_RenderClear +_SDL_RenderClipEnabled +_SDL_RenderCoordinatesFromWindow +_SDL_RenderCoordinatesToWindow +_SDL_RenderFillRect +_SDL_RenderFillRects +_SDL_RenderGeometry +_SDL_RenderGeometryRaw +_SDL_RenderLine +_SDL_RenderLines +_SDL_RenderPoint +_SDL_RenderPoints +_SDL_RenderPresent +_SDL_RenderReadPixels +_SDL_RenderRect +_SDL_RenderRects +_SDL_RenderTexture9Grid +_SDL_RenderTexture +_SDL_RenderTextureRotated +_SDL_RenderTextureTiled +_SDL_RenderViewportSet +_SDL_ReportAssertion +_SDL_RequestAndroidPermission +_SDL_ResetAssertionReport +_SDL_ResetHint +_SDL_ResetHints +_SDL_ResetKeyboard +_SDL_ResetLogPriorities +_SDL_RestoreWindow +_SDL_ResumeAudioDevice +_SDL_ResumeAudioStreamDevice +_SDL_ResumeHaptic +_SDL_RumbleGamepad +_SDL_RumbleGamepadTriggers +_SDL_RumbleJoystick +_SDL_RumbleJoystickTriggers +_SDL_RunApp +_SDL_RunHapticEffect +_SDL_SaveBMP +_SDL_SaveBMP_IO +_SDL_ScaleSurface +_SDL_ScreenKeyboardShown +_SDL_ScreenSaverEnabled +_SDL_SeekIO +_SDL_SendAndroidBackButton +_SDL_SendAndroidMessage +_SDL_SendGamepadEffect +_SDL_SendJoystickEffect +_SDL_SendJoystickVirtualSensorData +_SDL_SetAppMetadata +_SDL_SetAppMetadataProperty +_SDL_SetAssertionHandler +_SDL_SetAtomicInt +_SDL_SetAtomicPointer +_SDL_SetAtomicU32 +_SDL_SetAudioDeviceGain +_SDL_SetAudioPostmixCallback +_SDL_SetAudioStreamFormat +_SDL_SetAudioStreamFrequencyRatio +_SDL_SetAudioStreamGain +_SDL_SetAudioStreamGetCallback +_SDL_SetAudioStreamInputChannelMap +_SDL_SetAudioStreamOutputChannelMap +_SDL_SetAudioStreamPutCallback +_SDL_SetBooleanProperty +_SDL_SetClipboardData +_SDL_SetClipboardText +_SDL_SetCurrentThreadPriority +_SDL_SetCursor +_SDL_SetEnvironmentVariable +_SDL_SetError +_SDL_SetEventEnabled +_SDL_SetEventFilter +_SDL_SetFloatProperty +_SDL_SetGPUBlendConstants +_SDL_SetGPUBufferName +_SDL_SetGPUScissor +_SDL_SetGPUStencilReference +_SDL_SetGPUSwapchainParameters +_SDL_SetGPUTextureName +_SDL_SetGPUViewport +_SDL_SetGamepadEventsEnabled +_SDL_SetGamepadLED +_SDL_SetGamepadMapping +_SDL_SetGamepadPlayerIndex +_SDL_SetGamepadSensorEnabled +_SDL_SetHapticAutocenter +_SDL_SetHapticGain +_SDL_SetHint +_SDL_SetHintWithPriority +_SDL_SetInitialized +_SDL_SetJoystickEventsEnabled +_SDL_SetJoystickLED +_SDL_SetJoystickPlayerIndex +_SDL_SetJoystickVirtualAxis +_SDL_SetJoystickVirtualBall +_SDL_SetJoystickVirtualButton +_SDL_SetJoystickVirtualHat +_SDL_SetJoystickVirtualTouchpad +_SDL_SetLinuxThreadPriority +_SDL_SetLinuxThreadPriorityAndPolicy +_SDL_SetLogOutputFunction +_SDL_SetLogPriorities +_SDL_SetLogPriority +_SDL_SetLogPriorityPrefix +_SDL_SetMainReady +_SDL_SetMemoryFunctions +_SDL_SetModState +_SDL_SetNumberProperty +_SDL_SetPaletteColors +_SDL_SetPointerProperty +_SDL_SetPointerPropertyWithCleanup +_SDL_SetPrimarySelectionText +_SDL_SetRenderClipRect +_SDL_SetRenderColorScale +_SDL_SetRenderDrawBlendMode +_SDL_SetRenderDrawColor +_SDL_SetRenderDrawColorFloat +_SDL_SetRenderLogicalPresentation +_SDL_SetRenderScale +_SDL_SetRenderTarget +_SDL_SetRenderVSync +_SDL_SetRenderViewport +_SDL_SetScancodeName +_SDL_SetStringProperty +_SDL_SetSurfaceAlphaMod +_SDL_SetSurfaceBlendMode +_SDL_SetSurfaceClipRect +_SDL_SetSurfaceColorKey +_SDL_SetSurfaceColorMod +_SDL_SetSurfaceColorspace +_SDL_SetSurfacePalette +_SDL_SetSurfaceRLE +_SDL_SetTLS +_SDL_SetTextInputArea +_SDL_SetTextureAlphaMod +_SDL_SetTextureAlphaModFloat +_SDL_SetTextureBlendMode +_SDL_SetTextureColorMod +_SDL_SetTextureColorModFloat +_SDL_SetTextureScaleMode +_SDL_SetWindowAlwaysOnTop +_SDL_SetWindowAspectRatio +_SDL_SetWindowBordered +_SDL_SetWindowFocusable +_SDL_SetWindowFullscreen +_SDL_SetWindowFullscreenMode +_SDL_SetWindowHitTest +_SDL_SetWindowIcon +_SDL_SetWindowKeyboardGrab +_SDL_SetWindowMaximumSize +_SDL_SetWindowMinimumSize +_SDL_SetWindowModal +_SDL_SetWindowMouseGrab +_SDL_SetWindowMouseRect +_SDL_SetWindowOpacity +_SDL_SetWindowParent +_SDL_SetWindowPosition +_SDL_SetWindowRelativeMouseMode +_SDL_SetWindowResizable +_SDL_SetWindowShape +_SDL_SetWindowSize +_SDL_SetWindowSurfaceVSync +_SDL_SetWindowTitle +_SDL_SetWindowsMessageHook +_SDL_SetX11EventHook +_SDL_SetiOSAnimationCallback +_SDL_SetiOSEventPump +_SDL_ShouldInit +_SDL_ShouldQuit +_SDL_ShowAndroidToast +_SDL_ShowCursor +_SDL_ShowMessageBox +_SDL_ShowOpenFileDialog +_SDL_ShowOpenFolderDialog +_SDL_ShowSaveFileDialog +_SDL_ShowSimpleMessageBox +_SDL_ShowWindow +_SDL_ShowWindowSystemMenu +_SDL_SignalCondition +_SDL_SignalSemaphore +_SDL_StartTextInput +_SDL_StartTextInputWithProperties +_SDL_StepUTF8 +_SDL_StopHapticEffect +_SDL_StopHapticEffects +_SDL_StopHapticRumble +_SDL_StopTextInput +_SDL_StorageReady +_SDL_StringToGUID +_SDL_SubmitGPUCommandBuffer +_SDL_SubmitGPUCommandBufferAndAcquireFence +_SDL_SurfaceHasAlternateImages +_SDL_SurfaceHasColorKey +_SDL_SurfaceHasRLE +_SDL_SyncWindow +_SDL_TellIO +_SDL_TextInputActive +_SDL_TimeFromWindows +_SDL_TimeToDateTime +_SDL_TimeToWindows +_SDL_TryLockMutex +_SDL_TryLockRWLockForReading +_SDL_TryLockRWLockForWriting +_SDL_TryLockSpinlock +_SDL_TryWaitSemaphore +_SDL_UCS4ToUTF8 +_SDL_UnbindAudioStream +_SDL_UnbindAudioStreams +_SDL_UnloadObject +_SDL_UnlockAudioStream +_SDL_UnlockJoysticks +_SDL_UnlockMutex +_SDL_UnlockProperties +_SDL_UnlockRWLock +_SDL_UnlockSpinlock +_SDL_UnlockSurface +_SDL_UnlockTexture +_SDL_UnmapGPUTransferBuffer +_SDL_UnregisterApp +_SDL_UnsetEnvironmentVariable +_SDL_UpdateGamepads +_SDL_UpdateHapticEffect +_SDL_UpdateJoysticks +_SDL_UpdateNVTexture +_SDL_UpdateSensors +_SDL_UpdateTexture +_SDL_UpdateWindowSurface +_SDL_UpdateWindowSurfaceRects +_SDL_UpdateYUVTexture +_SDL_UploadToGPUBuffer +_SDL_UploadToGPUTexture +_SDL_Vulkan_CreateSurface +_SDL_Vulkan_DestroySurface +_SDL_Vulkan_GetInstanceExtensions +_SDL_Vulkan_GetPresentationSupport +_SDL_Vulkan_GetVkGetInstanceProcAddr +_SDL_Vulkan_LoadLibrary +_SDL_Vulkan_UnloadLibrary +_SDL_WaitCondition +_SDL_WaitConditionTimeout +_SDL_WaitEvent +_SDL_WaitEventTimeout +_SDL_WaitForGPUFences +_SDL_WaitForGPUIdle +_SDL_WaitProcess +_SDL_WaitSemaphore +_SDL_WaitSemaphoreTimeout +_SDL_WaitThread +_SDL_WarpMouseGlobal +_SDL_WarpMouseInWindow +_SDL_WasInit +_SDL_WindowHasSurface +_SDL_WindowSupportsGPUPresentMode +_SDL_WindowSupportsGPUSwapchainComposition +_SDL_WriteIO +_SDL_WriteS16BE +_SDL_WriteS16LE +_SDL_WriteS32BE +_SDL_WriteS32LE +_SDL_WriteS64BE +_SDL_WriteS64LE +_SDL_WriteS8 +_SDL_WriteStorageFile +_SDL_WriteSurfacePixel +_SDL_WriteSurfacePixelFloat +_SDL_WriteU16BE +_SDL_WriteU16LE +_SDL_WriteU32BE +_SDL_WriteU32LE +_SDL_WriteU64BE +_SDL_WriteU64LE +_SDL_WriteU8 +_SDL_abs +_SDL_acos +_SDL_acosf +_SDL_aligned_alloc +_SDL_aligned_free +_SDL_asin +_SDL_asinf +_SDL_asprintf +_SDL_atan2 +_SDL_atan2f +_SDL_atan +_SDL_atanf +_SDL_atof +_SDL_atoi +_SDL_bsearch +_SDL_bsearch_r +_SDL_calloc +_SDL_ceil +_SDL_ceilf +_SDL_copysign +_SDL_copysignf +_SDL_cos +_SDL_cosf +_SDL_crc16 +_SDL_crc32 +_SDL_exp +_SDL_expf +_SDL_fabs +_SDL_fabsf +_SDL_floor +_SDL_floorf +_SDL_fmod +_SDL_fmodf +_SDL_free +_SDL_getenv +_SDL_getenv_unsafe +_SDL_hid_ble_scan +_SDL_hid_close +_SDL_hid_device_change_count +_SDL_hid_enumerate +_SDL_hid_exit +_SDL_hid_free_enumeration +_SDL_hid_get_device_info +_SDL_hid_get_feature_report +_SDL_hid_get_indexed_string +_SDL_hid_get_input_report +_SDL_hid_get_manufacturer_string +_SDL_hid_get_product_string +_SDL_hid_get_report_descriptor +_SDL_hid_get_serial_number_string +_SDL_hid_init +_SDL_hid_open +_SDL_hid_open_path +_SDL_hid_read +_SDL_hid_read_timeout +_SDL_hid_send_feature_report +_SDL_hid_set_nonblocking +_SDL_hid_write +_SDL_iconv +_SDL_iconv_close +_SDL_iconv_open +_SDL_iconv_string +_SDL_isalnum +_SDL_isalpha +_SDL_isblank +_SDL_iscntrl +_SDL_isdigit +_SDL_isgraph +_SDL_isinf +_SDL_isinff +_SDL_islower +_SDL_isnan +_SDL_isnanf +_SDL_isprint +_SDL_ispunct +_SDL_isspace +_SDL_isupper +_SDL_isxdigit +_SDL_itoa +_SDL_lltoa +_SDL_log10 +_SDL_log10f +_SDL_log +_SDL_logf +_SDL_lround +_SDL_lroundf +_SDL_ltoa +_SDL_malloc +_SDL_memcmp +_SDL_memcpy +_SDL_memmove +_SDL_memset4 +_SDL_memset +_SDL_modf +_SDL_modff +_SDL_murmur3_32 +_SDL_pow +_SDL_powf +_SDL_qsort +_SDL_qsort_r +_SDL_rand +_SDL_rand_bits +_SDL_rand_bits_r +_SDL_rand_r +_SDL_randf +_SDL_randf_r +_SDL_realloc +_SDL_round +_SDL_roundf +_SDL_scalbn +_SDL_scalbnf +_SDL_setenv_unsafe +_SDL_sin +_SDL_sinf +_SDL_snprintf +_SDL_sqrt +_SDL_sqrtf +_SDL_srand +_SDL_sscanf +_SDL_strcasecmp +_SDL_strcasestr +_SDL_strchr +_SDL_strcmp +_SDL_strdup +_SDL_strlcat +_SDL_strlcpy +_SDL_strlen +_SDL_strlwr +_SDL_strncasecmp +_SDL_strncmp +_SDL_strndup +_SDL_strnlen +_SDL_strnstr +_SDL_strpbrk +_SDL_strrchr +_SDL_strrev +_SDL_strstr +_SDL_strtod +_SDL_strtok_r +_SDL_strtol +_SDL_strtoll +_SDL_strtoul +_SDL_strtoull +_SDL_strupr +_SDL_swprintf +_SDL_tan +_SDL_tanf +_SDL_tolower +_SDL_toupper +_SDL_trunc +_SDL_truncf +_SDL_uitoa +_SDL_ulltoa +_SDL_ultoa +_SDL_unsetenv_unsafe +_SDL_utf8strlcpy +_SDL_utf8strlen +_SDL_utf8strnlen +_SDL_vasprintf +_SDL_vsnprintf +_SDL_vsscanf +_SDL_vswprintf +_SDL_wcscasecmp +_SDL_wcscmp +_SDL_wcsdup +_SDL_wcslcat +_SDL_wcslcpy +_SDL_wcslen +_SDL_wcsncasecmp +_SDL_wcsncmp +_SDL_wcsnlen +_SDL_wcsnstr +_SDL_wcsstr +_SDL_wcstol +_SDL_StepBackUTF8 +_SDL_DelayPrecise +_SDL_CalculateGPUTextureFormatSize +_SDL_SetErrorV +_SDL_GetDefaultLogOutputFunction +_SDL_RenderDebugText +_SDL_GetSandbox +_SDL_CancelGPUCommandBuffer +_SDL_SaveFile_IO +_SDL_SaveFile +_SDL_GetCurrentDirectory +_SDL_IsAudioDevicePhysical +_SDL_IsAudioDevicePlayback +_SDL_AsyncIOFromFile +_SDL_GetAsyncIOSize +_SDL_ReadAsyncIO +_SDL_WriteAsyncIO +_SDL_CloseAsyncIO +_SDL_CreateAsyncIOQueue +_SDL_DestroyAsyncIOQueue +_SDL_GetAsyncIOResult +_SDL_WaitAsyncIOResult +_SDL_SignalAsyncIOQueue +_SDL_LoadFileAsync +_SDL_ShowFileDialogWithProperties +_SDL_IsMainThread +_SDL_RunOnMainThread +_SDL_SetGPUAllowedFramesInFlight +_SDL_RenderTextureAffine +_SDL_WaitForGPUSwapchain +_SDL_WaitAndAcquireGPUSwapchainTexture +_SDL_RenderDebugTextFormat +_SDL_CreateTray +_SDL_SetTrayIcon +_SDL_SetTrayTooltip +_SDL_CreateTrayMenu +_SDL_CreateTraySubmenu +_SDL_GetTrayMenu +_SDL_GetTraySubmenu +_SDL_GetTrayEntries +_SDL_RemoveTrayEntry +_SDL_InsertTrayEntryAt +_SDL_SetTrayEntryLabel +_SDL_GetTrayEntryLabel +_SDL_SetTrayEntryChecked +_SDL_GetTrayEntryChecked +_SDL_SetTrayEntryEnabled +_SDL_GetTrayEntryEnabled +_SDL_SetTrayEntryCallback +_SDL_DestroyTray +_SDL_GetTrayEntryParent +_SDL_GetTrayMenuParentEntry +_SDL_GetTrayMenuParentTray +_SDL_GetThreadState +_SDL_AudioStreamDevicePaused +_SDL_ClickTrayEntry +_SDL_UpdateTrays +_SDL_StretchSurface +_SDL_SetRelativeMouseTransform +_SDL_RenderTexture9GridTiled +_SDL_SetDefaultTextureScaleMode +_SDL_GetDefaultTextureScaleMode +_SDL_CreateGPURenderState +_SDL_SetGPURenderStateFragmentUniforms +_SDL_SetGPURenderState +_SDL_DestroyGPURenderState +_SDL_SetWindowProgressState +_SDL_SetWindowProgressValue +_SDL_GetWindowProgressState +_SDL_GetWindowProgressValue +_SDL_SetRenderTextureAddressMode +_SDL_GetRenderTextureAddressMode +_SDL_GetGPUDeviceProperties +_SDL_CreateGPURenderer +_SDL_PutAudioStreamPlanarData +_SDL_GetEventDescription +_SDL_PutAudioStreamDataNoCopy +_SDL_AddAtomicU32 +_SDL_hid_get_properties +_SDL_GetPixelFormatFromGPUTextureFormat +_SDL_GetGPUTextureFormatFromPixelFormat +_SDL_SetTexturePalette +_SDL_GetTexturePalette +_SDL_GetGPURendererDevice +_SDL_LoadPNG_IO +_SDL_LoadPNG +_SDL_SavePNG_IO +_SDL_SavePNG +_SDL_GetSystemPageSize +_SDL_GetPenDeviceType +_SDL_CreateAnimatedCursor +_SDL_RotateSurface +_SDL_LoadSurface_IO +_SDL_LoadSurface +_SDL_SetWindowFillDocument +_SDL_TryLockJoysticks +_SDL_CreateGPUXRSession +_SDL_GetGPUXRSwapchainFormats +_SDL_CreateGPUXRSwapchain +_SDL_DestroyGPUXRSwapchain +_SDL_OpenXR_LoadLibrary +_SDL_OpenXR_UnloadLibrary +_SDL_OpenXR_GetXrGetInstanceProcAddr +_SDL_CreateTrayWithProperties +_SDL_SetGPURenderStateSamplerBindings +_SDL_SetGPURenderStateStorageTextures +_SDL_SetGPURenderStateStorageBuffers +_SDL_GDKSuspendRenderer +_SDL_GDKResumeRenderer +_SDL_IsPhone diff --git a/src/dynapi/gendynapi.py b/src/dynapi/gendynapi.py index 4071b752a0..7827d6e739 100755 --- a/src/dynapi/gendynapi.py +++ b/src/dynapi/gendynapi.py @@ -44,6 +44,7 @@ SDL_ROOT = Path(__file__).resolve().parents[2] SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3" SDL_DYNAPI_PROCS_H = SDL_ROOT / "src/dynapi/SDL_dynapi_procs.h" SDL_DYNAPI_OVERRIDES_H = SDL_ROOT / "src/dynapi/SDL_dynapi_overrides.h" +SDL_DYNAPI_EXPORTS = SDL_ROOT / "src/dynapi/SDL_dynapi.exports" SDL_DYNAPI_SYM = SDL_ROOT / "src/dynapi/SDL_dynapi.sym" RE_EXTERN_C = re.compile(r'.*extern[ "]*C[ "].*') @@ -493,9 +494,15 @@ def add_dyn_api(proc: SdlProcedure) -> None: # # Add at last # "#define SDL_DelayNS SDL_DelayNS_REAL - f = open(SDL_DYNAPI_OVERRIDES_H, "a", newline="") - f.write(f"#define {proc.name} {proc.name}_REAL\n") - f.close() + with open(SDL_DYNAPI_OVERRIDES_H, "a", newline="") as f: + f.write(f"#define {proc.name} {proc.name}_REAL\n") + + # File: SDL_dynapi.exports + # + # Append to end + # "_SDL_DelayNS" + with open(SDL_DYNAPI_EXPORTS, "a", newline="") as f: + f.write(f"_{proc.name}\n") # File: SDL_dynapi.sym # From 788bd816e7c3d90ba7eaa3b3703a384e1ef50483 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 27 Apr 2026 14:53:45 -0400 Subject: [PATCH 194/407] SDL_openxr.h: Another attempt to fix the wiki bridge. --- include/SDL3/SDL_openxr.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_openxr.h b/include/SDL3/SDL_openxr.h index a017983952..6405ed2f15 100644 --- a/include/SDL3/SDL_openxr.h +++ b/include/SDL3/SDL_openxr.h @@ -19,13 +19,15 @@ 3. This notice may not be removed or altered from any source distribution. */ +/* WIKI CATEGORY: OpenXR */ + /** * # CategoryOpenXR * - * Functions for creating OpenXR handles for SDL_gpu contexts. + * Functions for creating OpenXR handles for [GPU API](CategoryGPU) contexts. * * For the most part, OpenXR operates independent of SDL, but the graphics - * initialization depends on direct support from SDL_gpu. + * initialization depends on direct support from the GPU API. */ #ifndef SDL_openxr_h_ From 7212ab1c2a12db7a81b1b13cc28e860cb9cfa138 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 28 Apr 2026 08:08:15 -0400 Subject: [PATCH 195/407] checkkeys: Sleeping for 100ms every frame makes the program too unresponsive. Makes it feel like there's a bug in SDL's text input handling. 10ms is fine. --- test/checkkeys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/checkkeys.c b/test/checkkeys.c index f2223b6879..aaaff1462f 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -434,7 +434,7 @@ static void loop(void) } /* Slow down framerate */ - SDL_Delay(100); + SDL_Delay(10); #ifdef SDL_PLATFORM_EMSCRIPTEN if (done) { From b40baf1532eb98b08b65cb9f51cd0e3e76be6459 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Tue, 28 Apr 2026 19:11:35 +0000 Subject: [PATCH 196/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_gpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index 0a523b81aa..6cdd8b6a39 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -1873,6 +1873,7 @@ typedef struct SDL_GPUMultisampleState * \since This struct is available since SDL 3.2.0. * * \sa SDL_GPUGraphicsPipelineCreateInfo + * \sa SDL_GPUStencilOpState */ typedef struct SDL_GPUDepthStencilState { From d5fca9628affff85fc7dd8dc8fb2e70a6e1957dd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Apr 2026 14:10:04 -0700 Subject: [PATCH 197/407] Don't use the fake HID endpoint for Xbox controllers on Windows --- src/joystick/hidapi/SDL_hidapi_xboxone.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 896423f848..13a2bdc7b6 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -34,7 +34,7 @@ // #define DEBUG_JOYSTICK // Define this if you want to log all packets from the controller -#if 0 +#if 1 #define DEBUG_XBOX_PROTOCOL #endif @@ -374,6 +374,12 @@ static bool HIDAPI_DriverXboxOne_IsSupportedDevice(SDL_HIDAPI_Device *device, co // we'll just use the GCController support instead. return false; } +#endif +#ifdef SDL_PLATFORM_WIN32 + if (SDL_strncmp(device->path, "\\\\?\\HID#", 8) == 0) { + // Windows provides a fake HID endpoint for XGIP controllers, don't use this + return false; + } #endif if (interface_class && (interface_class != LIBUSB_CLASS_VENDOR_SPEC || From 71d0d069edf49eaed63762ea0d593e7296cff357 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Apr 2026 15:31:10 -0700 Subject: [PATCH 198/407] GameInput: don't say the device is present if we won't handle it --- src/joystick/gdk/SDL_gameinputjoystick.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index bb511dda2b..c1c57a43b3 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -487,7 +487,9 @@ static bool GAMEINPUT_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_i if (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) { // The Xbox One controller shows up as a hardcoded raw input VID/PID, which we definitely handle - return true; + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) { + return true; + } } for (int i = 0; i < g_GameInputList.count; ++i) { From bb4332bdc2ff32aa41bdb7354731ac1ef38f7d9e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 20 Apr 2026 20:18:45 -0400 Subject: [PATCH 199/407] android: Parse the APK directory tree, replace AAssetManager enum/getpathinfo. The AAssetManager won't supply this information to us, but it's just a zip file, so we can read its central directory ourselves. We can still use AAssetManager for file i/o to the APK's assets, so we don't have to deal with compression and other zipfile features. Fixes #15220. Reference Issue #15347. --- src/core/android/SDL_android.c | 461 ++++++++++++++++++++++++++++++--- 1 file changed, 429 insertions(+), 32 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 07f71600e3..18ec7a8a1c 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -44,6 +44,7 @@ #include #include #include +#include #define SDL_JAVA_PREFIX org_libsdl_app #define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function) @@ -1838,6 +1839,398 @@ static bool Android_JNI_ExceptionOccurred(bool silent) return false; } + +// APK file tree discovery... + +// APK files are just .zip files, so try to find parse out the file tree from it. We'll still +// use Android's system APIs to actually access data, but those APIs aren't reliable for +// enumerating the tree for various reasons. + +// we only care about the directories; Android's AAssetManager can enumerate all files in any +// known directory, but it won't enumerate subdirectories, so we track that by ourselves. +typedef struct APKNode +{ + char *name; + SDL_PathInfo info; + struct APKNode *children; + struct APKNode *next_sibling; +} APKNode; + +static APKNode *APKRootNode = NULL; + +static void FreeAPKNode(APKNode *node) +{ + if (node) { + FreeAPKNode(node->next_sibling); + FreeAPKNode(node->children); + SDL_free(node->name); + SDL_free(node); + } +} + +static APKNode *FindAPKChildNode(APKNode *parent, const char *child) +{ + for (APKNode *node = parent->children; node != NULL; node = node->next_sibling) { + if (SDL_strcmp(child, node->name) == 0) { + return node; + } + } + return NULL; +} + +static const APKNode *FindAPKNode(const char *constpath) +{ + APKNode *parent = APKRootNode; + if (!parent) { + return NULL; + } + + const size_t pathlen = SDL_strlen(constpath); + bool isstack = false; + char *alloc_path = SDL_small_alloc(char, pathlen + 1, &isstack); + if (!alloc_path) { + return NULL; + } + char *path = alloc_path; + SDL_strlcpy(path, constpath, pathlen + 1); + + while (parent) { + while (*path == '/') { + path++; // just in case there are absolute paths or double-slashes, drop them. + } + + if (*path == '\0') { // ended with a '/'? We're done. + break; + } + + char *ptr = SDL_strchr(path, '/'); + if (ptr) { + *ptr = '\0'; // terminate on the end of this subdir's name. + } + + APKNode *node = FindAPKChildNode(parent, path); + if (!node) { + SDL_SetError("No such file or directory"); + parent = NULL; + } else if ((node->info.type == SDL_PATHTYPE_FILE) && ptr) { // file where we want a directory? + SDL_SetError("%s is not a directory", alloc_path); + parent = NULL; + } else { + parent = node; + if (!ptr) { + break; + } + *ptr = '/'; + path = ptr + 1; + } + } + + SDL_small_free(alloc_path, isstack); + return parent; +} + +static APKNode *AddAPKChildNode(APKNode *parent, const char *child) +{ + APKNode *node = FindAPKChildNode(parent, child); + if (!node) { // don't have this one yet, make a new node. + node = (APKNode *) SDL_calloc(1, sizeof (*node)); + if (!node) { + return NULL; // uhoh. + } + + node->name = SDL_strdup(child); + if (!node->name) { + SDL_free(node); + return NULL; // uhoh. + } + + SDL_copyp(&node->info, &parent->info); // you probably need to update this afterwards. + + node->next_sibling = parent->children; + parent->children = node; + } + return node; +} + +static APKNode *AddAPKDirs(char *path, APKNode *parent) +{ + // zip files specify explicit directories by just having a path that ends with a dir separator, + // which works nicely for our needs here; if the last segment of the path doesn't end with a + // '/', it's a file and we can drop it, or we filled in the final subdirectory and the '/' at + // the end will put us at an empty string to be dropped. + // + // directories do not need to be explicitly specified if something uses some deeper path, they + // may need to be inferred from those references, so we build out the tree by looking at all + // files and filling in nodes they mention. + + SDL_assert(parent->info.type == SDL_PATHTYPE_DIRECTORY); + SDL_assert(parent->info.size == 0); + + while (true) { // while still subdirectories to handle... + while (*path == '/') { + path++; // just in case there are absolute paths or double-slashes, drop them. + } + + char *ptr = SDL_strchr(path, '/'); + if (!ptr) { + break; // last thing is either an empty string (we ended with a '/'), or an actual file's name, so drop it. + } + + *ptr = '\0'; // terminate on the end of this subdir's name. + APKNode *node = AddAPKChildNode(parent, path); + *ptr = '/'; + + if (!node) { + return NULL; // uhoh. + } + + parent = node; + path = ptr + 1; // point to start of next section. + } + + return parent; +} + + +static SDL_Time ZipDosTimeToSDLTime(Uint32 dostime) +{ + Uint32 dosdate; + struct tm unixtime; + SDL_zero(unixtime); + + dosdate = (Uint32) ((dostime >> 16) & 0xFFFF); + dostime &= 0xFFFF; + + /* dissect date */ + unixtime.tm_year = ((dosdate >> 9) & 0x7F) + 80; + unixtime.tm_mon = ((dosdate >> 5) & 0x0F) - 1; + unixtime.tm_mday = ((dosdate ) & 0x1F); + + /* dissect time */ + unixtime.tm_hour = ((dostime >> 11) & 0x1F); + unixtime.tm_min = ((dostime >> 5) & 0x3F); + unixtime.tm_sec = ((dostime << 1) & 0x3E); + + /* let mktime calculate daylight savings time. */ + unixtime.tm_isdst = -1; + + return ((SDL_Time) mktime(&unixtime)); +} + + + +#define ZIP_CENTRAL_DIR_SIG 0x02014b50 +#define ZIP_END_OF_CENTRAL_DIR_SIG 0x06054b50 +#define ZIP64_END_OF_CENTRAL_DIR_SIG 0x06064b50 +#define ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG 0x07064b50 + +static bool ProcessZip(SDL_IOStream *io, APKNode *root) +{ + // There is a record at the end of a .zip file we can use to find the central directory; + // unfortunately it's before the variable-length comment field, so we might need to read + // from the end of the file until we see a magic signature. For now, we assume APKs don't + // have a comment, so we don't have to search backwards for the signature and it's always + // 22 bytes from EOF. + const Sint64 eocd = SDL_GetIOSize(io) - 22; + if (eocd < 0) { + SDL_Log("ANDROID: Couldn't find End Of Central Directory in APK (%s). Filesystem enumeration will fail.", SDL_GetError()); + return false; + } + + //bool zip64 = false; + Sint64 centraldir = -1; + Uint64 num_entries = 0; + Uint16 val16 = 0; + Uint32 val32 = 0; + Uint64 val64 = 0; + + // First, check if this is actually zip64 format instead. The zip64 magic is 20 bytes back. + if (eocd < 20) { // presumably we always _are_ > 20, but let's be defensive here. + goto corrupterr; + } else if (SDL_SeekIO(io, eocd - 20, SDL_IO_SEEK_SET) < 0) { + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { + goto ioerr; + } else if (val32 == ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG) { // this is a zip64 archive? + if (!SDL_ReadU32LE(io, &val32)) { // disk number with start of central directory. + goto ioerr; + } else if (val32 != 0) { + goto corrupterr; + } else if (!SDL_ReadU64LE(io, &val64)) { // file offset of zip64 end-of-central-dir record + goto ioerr; + + // note that this gets significantly more complex if there is data prepended to the .zip file + // (like a self-extracting .exe, etc), but until that happens, we're keeping this as simple + // as possible and assuming the file offset in val64 is correct. + + } else if (SDL_SeekIO(io, (Sint64) val64, SDL_IO_SEEK_SET) < 0) { + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // zip64 end-of-central-dir signature. + goto ioerr; + } else if (val32 != ZIP64_END_OF_CENTRAL_DIR_SIG) { + goto corrupterr; + } else if (SDL_SeekIO(io, 28, SDL_IO_SEEK_CUR) < 0) { // we don't care about several of the fields, skip over them. + goto ioerr; + } else if (!SDL_ReadU64LE(io, &num_entries)) { // total entries in the central dir. + goto ioerr; + } else if (!SDL_ReadU64LE(io, &val64)) { // size of the central dir. + goto ioerr; + } else if (!SDL_ReadU64LE(io, &val64)) { // offset of the central dir. + goto ioerr; + } + + //zip64 = true; + centraldir = (Sint64) val64; + } else if (SDL_SeekIO(io, eocd + 4 + 6, SDL_IO_SEEK_SET) < 0) { // skip back to where we were, plus skip some fields we don't care about. + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // size of the central dir. + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // offset of the central dir. + goto ioerr; + } else { + num_entries = (Uint64) val16; + centraldir = (Sint64) val32; + } + + // okay, we know where the central dir is now, go there and start reading entries. + SDL_assert(centraldir > 0); // negative means we failed, zero is impossible since there should be something else there. + + for (Uint64 i = 0; i < num_entries; i++) { + Uint16 fnamelen = 0; + Uint16 extralen = 0; + Uint16 commentlen = 0; + Uint32 dosmodtime = 0; + Uint32 uncompressed = 0; + + // we don't care about most of this information, just parse through it to get what we need. + if (SDL_SeekIO(io, centraldir, SDL_IO_SEEK_SET) < 0) { + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // central dir item signature. + goto ioerr; + } else if (val32 != ZIP_CENTRAL_DIR_SIG) { + goto corrupterr; + } else if (!SDL_ReadU16LE(io, &val16)) { // version made by + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { // version needed + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { // general bits + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { // compression method + goto ioerr; + } else if (!SDL_ReadU32LE(io, &dosmodtime)) { // last mod date/time + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // CRC-32 + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // compressed size + goto ioerr; + } else if (!SDL_ReadU32LE(io, &uncompressed)) { // uncompressed size + goto ioerr; + } else if (!SDL_ReadU16LE(io, &fnamelen)) { // filename length + goto ioerr; + } else if (!SDL_ReadU16LE(io, &extralen)) { // extra length + goto ioerr; + } else if (!SDL_ReadU16LE(io, &commentlen)) { // comment length + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { // disk number start + goto ioerr; + } else if (!SDL_ReadU16LE(io, &val16)) { // internal file attributes + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // external file attributes + goto ioerr; + } else if (!SDL_ReadU32LE(io, &val32)) { // relative offset of local header + goto ioerr; + } + + char fnamebuf[0xFFFF+1]; // just eat 64k of stack like a boss until someone complains. + if (SDL_ReadIO(io, fnamebuf, (size_t) fnamelen) != ((size_t) fnamelen)) { + goto ioerr; + } + + // !!! FIXME: parse out the extralen section for zip64 file sizes; needed if a file is > 4 gigabytes. + + // technically zip files might have '\\' dir separators, but these were mostly old DOS files and not Android APKs, I think. Revisit if necessary. + + fnamebuf[fnamelen] = '\0'; // make sure the string is null-terminated. + + //SDL_Log("ANDROID: Saw ZIP entry '%s'", fnamebuf); + + char *ptr = fnamebuf; + while (*ptr == '/') { // drop absolute paths. + ptr++; + } + + if (SDL_strncmp(ptr, "assets/", 7) == 0) { // we only care about things under 'assets' for now. Drop everything else. + ptr += 6; // keep the '/' so strrchr never returns NULL. + APKNode *node = AddAPKDirs(ptr, root); // this builds out any missing subdirs, returns parent dir's node. + if (!node) { + goto ioerr; // (probably out of memory.) + } + + const SDL_Time modtime = ZipDosTimeToSDLTime(dosmodtime); + ptr = SDL_strrchr(ptr, '/'); + SDL_assert(ptr != NULL); + if (*(++ptr) == '\0') { // explicit directory entry paths end with '/' ...`node` is the new node. + node->info.type = SDL_PATHTYPE_DIRECTORY; + node->info.size = 0; + } else { + node = AddAPKChildNode(node, ptr); + if (!node) { + goto ioerr; // (probably out of memory.) + } + node->info.type = SDL_PATHTYPE_FILE; + node->info.size = (Uint64) uncompressed; + } + node->info.create_time = node->info.modify_time = node->info.access_time = modtime; + } + + centraldir += (Sint64) (46 + fnamelen + extralen + commentlen); // will seek to next file entry. + } + + return true; + +corrupterr: + SDL_Log("ANDROID: Unexpected or corrupt data in APK. Filesystem enumeration will fail."); + return false; + +ioerr: + SDL_Log("ANDROID: i/o error in APK (%s). Filesystem enumeration will fail.", SDL_GetError()); + return false; +} + +static bool CreateAPKNodes(const char *path) +{ + SDL_Log("ANDROID: Parsing APK file '%s' ...", path); + + SDL_PathInfo apkinfo; + SDL_assert(path[0] == '/'); // So SDL_GetPathInfo goes through the `stat` path and doesn't try to dig into the APK. + if (!SDL_GetPathInfo(path, &apkinfo)) { + SDL_zero(apkinfo); // we just want the file times here, so oh well. + } + + if (!APKRootNode) { + APKRootNode = (APKNode *) SDL_calloc(1, sizeof (*APKRootNode)); + if (!APKRootNode) { + SDL_Log("ANDROID: Can't open APK (out of memory). Filesystem enumeration will fail."); + return false; + } + APKRootNode->info.type = SDL_PATHTYPE_DIRECTORY; + APKRootNode->info.create_time = apkinfo.create_time; + APKRootNode->info.modify_time = apkinfo.modify_time; + APKRootNode->info.access_time = apkinfo.access_time; + } + + SDL_IOStream *io = SDL_IOFromFile(path, "rb"); + if (!io) { + SDL_Log("ANDROID: Can't open APK '%s' for reading (%s). Filesystem enumeration will fail.", path, SDL_GetError()); + } else { + ProcessZip(io, APKRootNode); + SDL_CloseIO(io); + } + return true; // even on failure, leave an empty root node so we have zero files and don't try to load the .zip again. +} + static void Internal_Android_Create_AssetManager(void) { @@ -1874,6 +2267,21 @@ static void Internal_Android_Create_AssetManager(void) Android_JNI_ExceptionOccurred(true); } + // the assetmanager isn't useful for enumerating directories, so parse the APK directly for that info upfront. + jthrowable jexception = 0; + jstring jstr = 0; + + mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), "getPackageResourcePath", "()Ljava/lang/String;"); + jstr = (jstring)(*env)->CallObjectMethod(env, context, mid); + jexception = (*env)->ExceptionOccurred(env); + if (jexception != NULL) { + (*env)->ExceptionClear(env); // oh well + } else { + const char *apkpath = (*env)->GetStringUTFChars(env, jstr, NULL); + CreateAPKNodes(apkpath); + (*env)->ReleaseStringUTFChars(env, jstr, apkpath); + } + LocalReferenceHolder_Cleanup(&refs); } @@ -1885,6 +2293,11 @@ static void Internal_Android_Destroy_AssetManager(void) (*env)->DeleteGlobalRef(env, javaAssetManagerRef); asset_manager = NULL; } + + if (APKRootNode) { + FreeAPKNode(APKRootNode); + APKRootNode = NULL; + } } static const char *GetAssetPath(const char *path) @@ -1970,21 +2383,21 @@ bool Android_JNI_EnumerateAssetDirectory(const char *path, SDL_EnumerateDirector } } + SDL_EnumerationResult result = SDL_ENUM_CONTINUE; const char *asset_path = GetAssetPath(path); - AAssetDir *adir = AAssetManager_openDir(asset_manager, asset_path); - if (!adir) { - return SDL_SetError("AAssetManager_openDir failed"); + // check our tree we built from the APK first. + const APKNode *apknode = FindAPKNode(asset_path); + if (!apknode) { + return SDL_SetError("No such directory"); + } else if (apknode->info.type != SDL_PATHTYPE_DIRECTORY) { + return SDL_SetError("Not a directory"); + } else { + for (const APKNode *node = apknode->children; node && (result == SDL_ENUM_CONTINUE); node = node->next_sibling) { + result = cb(userdata, path, node->name); + } } - SDL_EnumerationResult result = SDL_ENUM_CONTINUE; - const char *ent; - while ((result == SDL_ENUM_CONTINUE) && ((ent = AAssetDir_getNextFileName(adir)) != NULL)) { - result = cb(userdata, path, ent); - } - - AAssetDir_close(adir); - return (result != SDL_ENUM_FAILURE); } @@ -1998,28 +2411,12 @@ bool Android_JNI_GetAssetPathInfo(const char *path, SDL_PathInfo *info) } path = GetAssetPath(path); - - // this is sort of messy, but there isn't a stat()-like interface to the Assets. - AAsset *aasset = AAssetManager_open(asset_manager, path, AASSET_MODE_UNKNOWN); - if (aasset) { // it's a file! - info->type = SDL_PATHTYPE_FILE; - info->size = (Uint64) AAsset_getLength64(aasset); - AAsset_close(aasset); - return true; + const APKNode *apknode = FindAPKNode(path); + if (!apknode) { + return SDL_SetError("No such file or directory"); } - - AAssetDir *adir = AAssetManager_openDir(asset_manager, path); - if (adir) { // This does _not_ return NULL for a missing directory! Treat empty directories as missing. Better than nothing. :/ - const bool contains_something = (AAssetDir_getNextFileName(adir) != NULL); // if not NULL, there are files in this directory, so it's _definitely_ a directory. - AAssetDir_close(adir); - if (contains_something) { - info->type = SDL_PATHTYPE_DIRECTORY; - info->size = 0; - return true; - } - } - - return SDL_SetError("Couldn't open asset '%s'", path); + SDL_copyp(info, &apknode->info); + return true; } bool Android_JNI_SetClipboardText(const char *text) From 40e60452ade1c82c3ce728ce4631f8824182f609 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 23 Apr 2026 23:15:13 -0400 Subject: [PATCH 200/407] android: Use enough zip64 format info to see APKs with files that are > 4gb. --- src/core/android/SDL_android.c | 47 +++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 18ec7a8a1c..8919b87b58 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2023,6 +2023,7 @@ static SDL_Time ZipDosTimeToSDLTime(Uint32 dostime) #define ZIP_END_OF_CENTRAL_DIR_SIG 0x06054b50 #define ZIP64_END_OF_CENTRAL_DIR_SIG 0x06064b50 #define ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG 0x07064b50 +#define ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG 0x0001 static bool ProcessZip(SDL_IOStream *io, APKNode *root) { @@ -2037,7 +2038,7 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) return false; } - //bool zip64 = false; + bool zip64 = false; Sint64 centraldir = -1; Uint64 num_entries = 0; Uint16 val16 = 0; @@ -2079,7 +2080,7 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) goto ioerr; } - //zip64 = true; + zip64 = true; centraldir = (Sint64) val64; } else if (SDL_SeekIO(io, eocd + 4 + 6, SDL_IO_SEEK_SET) < 0) { // skip back to where we were, plus skip some fields we don't care about. goto ioerr; @@ -2102,7 +2103,8 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) Uint16 extralen = 0; Uint16 commentlen = 0; Uint32 dosmodtime = 0; - Uint32 uncompressed = 0; + Uint32 uncompressed32 = 0; + Uint64 uncompressed64 = 0; // we don't care about most of this information, just parse through it to get what we need. if (SDL_SeekIO(io, centraldir, SDL_IO_SEEK_SET) < 0) { @@ -2125,7 +2127,7 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) goto ioerr; } else if (!SDL_ReadU32LE(io, &val32)) { // compressed size goto ioerr; - } else if (!SDL_ReadU32LE(io, &uncompressed)) { // uncompressed size + } else if (!SDL_ReadU32LE(io, &uncompressed32)) { // uncompressed size goto ioerr; } else if (!SDL_ReadU16LE(io, &fnamelen)) { // filename length goto ioerr; @@ -2148,14 +2150,45 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) goto ioerr; } - // !!! FIXME: parse out the extralen section for zip64 file sizes; needed if a file is > 4 gigabytes. - // technically zip files might have '\\' dir separators, but these were mostly old DOS files and not Android APKs, I think. Revisit if necessary. fnamebuf[fnamelen] = '\0'; // make sure the string is null-terminated. //SDL_Log("ANDROID: Saw ZIP entry '%s'", fnamebuf); + uncompressed64 = (Uint64) uncompressed32; + if (zip64 && (uncompressed32 == 0xFFFFFFFF)) { // file is larger than 4gig, find the zip64 extended info field in the extra section. + bool found = false; + Uint16 remaining = extralen; + while (remaining > 4) { // Two 16-bit values at a minimum, tag and len. + Uint16 tag, len; + if (!SDL_ReadU16LE(io, &tag) || !SDL_ReadU16LE(io, &len)) { + goto ioerr; + } else if (remaining < (len + 4)) { + goto corrupterr; + } else if (tag != ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG) { // not the field we need, skip over it. + if (SDL_SeekIO(io, (Sint64) len, SDL_IO_SEEK_CUR) < 0) { + goto ioerr; + } + } else if (len < 8) { + goto corrupterr; + } else if ((uncompressed32 == 0xFFFFFFFF) && !SDL_ReadU64LE(io, &uncompressed64)) { + goto ioerr; + + // there are other values in here, but we don't care about them and we're done, so don't try to skip over them. + + } else { + found = true; + break; // got what we need, drop out. + } + remaining -= len + 4; + } + + if (!found) { + goto corrupterr; + } + } + char *ptr = fnamebuf; while (*ptr == '/') { // drop absolute paths. ptr++; @@ -2180,7 +2213,7 @@ static bool ProcessZip(SDL_IOStream *io, APKNode *root) goto ioerr; // (probably out of memory.) } node->info.type = SDL_PATHTYPE_FILE; - node->info.size = (Uint64) uncompressed; + node->info.size = uncompressed64; } node->info.create_time = node->info.modify_time = node->info.access_time = modtime; } From 9235ac4efdbd175d0c217ca0fd1bc824ccb968a0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 28 Apr 2026 10:45:34 -0400 Subject: [PATCH 201/407] android: Parsing the APK's central dir is separate from the AAssetManager. Only parse when necessary, which it isn't when opening a file, so this is now separated from creating the cached AAssetManager object. --- src/core/android/SDL_android.c | 93 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 8919b87b58..3b642d2a8d 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2236,24 +2236,6 @@ static bool CreateAPKNodes(const char *path) { SDL_Log("ANDROID: Parsing APK file '%s' ...", path); - SDL_PathInfo apkinfo; - SDL_assert(path[0] == '/'); // So SDL_GetPathInfo goes through the `stat` path and doesn't try to dig into the APK. - if (!SDL_GetPathInfo(path, &apkinfo)) { - SDL_zero(apkinfo); // we just want the file times here, so oh well. - } - - if (!APKRootNode) { - APKRootNode = (APKNode *) SDL_calloc(1, sizeof (*APKRootNode)); - if (!APKRootNode) { - SDL_Log("ANDROID: Can't open APK (out of memory). Filesystem enumeration will fail."); - return false; - } - APKRootNode->info.type = SDL_PATHTYPE_DIRECTORY; - APKRootNode->info.create_time = apkinfo.create_time; - APKRootNode->info.modify_time = apkinfo.modify_time; - APKRootNode->info.access_time = apkinfo.access_time; - } - SDL_IOStream *io = SDL_IOFromFile(path, "rb"); if (!io) { SDL_Log("ANDROID: Can't open APK '%s' for reading (%s). Filesystem enumeration will fail.", path, SDL_GetError()); @@ -2261,12 +2243,51 @@ static bool CreateAPKNodes(const char *path) ProcessZip(io, APKRootNode); SDL_CloseIO(io); } - return true; // even on failure, leave an empty root node so we have zero files and don't try to load the .zip again. + return true; +} + +static bool PrepareAPK(void) +{ + // the assetmanager isn't useful for enumerating directories, so parse the APK directly for that info upfront. + bool retval = (APKRootNode != NULL); + if (!retval) { + // allocate this upfront, so if there's a failure, we'll not try again and just have an empty file tree. + APKRootNode = (APKNode *) SDL_calloc(1, sizeof (*APKRootNode)); + if (!APKRootNode) { + return false; // oh well. + } + APKRootNode->info.type = SDL_PATHTYPE_DIRECTORY; + + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(SDL_FUNCTION); + JNIEnv *env = Android_JNI_GetEnv(); + if (LocalReferenceHolder_Init(&refs, env)) { + jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); + jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), "getPackageResourcePath", "()Ljava/lang/String;"); + jstring jstr = (jstring)(*env)->CallObjectMethod(env, context, mid); + jthrowable jexception = (*env)->ExceptionOccurred(env); + if (jexception != NULL) { + (*env)->ExceptionClear(env); // oh well + } else { + const char *apkpath = (*env)->GetStringUTFChars(env, jstr, NULL); + SDL_PathInfo apkinfo; + SDL_assert(apkpath[0] == '/'); // So SDL_GetPathInfo goes through the `stat` path and doesn't try to dig into the APK. + if (SDL_GetPathInfo(apkpath, &apkinfo)) { // we just want the file times here, so oh well if it fails. + APKRootNode->info.create_time = apkinfo.create_time; + APKRootNode->info.modify_time = apkinfo.modify_time; + APKRootNode->info.access_time = apkinfo.access_time; + } + CreateAPKNodes(apkpath); + (*env)->ReleaseStringUTFChars(env, jstr, apkpath); + retval = true; + } + } + LocalReferenceHolder_Cleanup(&refs); + } + return retval; // even on failure, leave an empty root node so we have zero files and don't try to load the .zip again. } static void Internal_Android_Create_AssetManager(void) { - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(SDL_FUNCTION); JNIEnv *env = Android_JNI_GetEnv(); jmethodID mid; @@ -2300,21 +2321,6 @@ static void Internal_Android_Create_AssetManager(void) Android_JNI_ExceptionOccurred(true); } - // the assetmanager isn't useful for enumerating directories, so parse the APK directly for that info upfront. - jthrowable jexception = 0; - jstring jstr = 0; - - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), "getPackageResourcePath", "()Ljava/lang/String;"); - jstr = (jstring)(*env)->CallObjectMethod(env, context, mid); - jexception = (*env)->ExceptionOccurred(env); - if (jexception != NULL) { - (*env)->ExceptionClear(env); // oh well - } else { - const char *apkpath = (*env)->GetStringUTFChars(env, jstr, NULL); - CreateAPKNodes(apkpath); - (*env)->ReleaseStringUTFChars(env, jstr, apkpath); - } - LocalReferenceHolder_Cleanup(&refs); } @@ -2409,17 +2415,13 @@ bool Android_JNI_EnumerateAssetDirectory(const char *path, SDL_EnumerateDirector { SDL_assert(path != NULL); - if (!asset_manager) { - Internal_Android_Create_AssetManager(); - if (!asset_manager) { - return SDL_SetError("Couldn't create asset manager"); - } + if (!PrepareAPK()) { + return false; } SDL_EnumerationResult result = SDL_ENUM_CONTINUE; const char *asset_path = GetAssetPath(path); - // check our tree we built from the APK first. const APKNode *apknode = FindAPKNode(asset_path); if (!apknode) { return SDL_SetError("No such directory"); @@ -2436,11 +2438,10 @@ bool Android_JNI_EnumerateAssetDirectory(const char *path, SDL_EnumerateDirector bool Android_JNI_GetAssetPathInfo(const char *path, SDL_PathInfo *info) { - if (!asset_manager) { - Internal_Android_Create_AssetManager(); - if (!asset_manager) { - return SDL_SetError("Couldn't create asset manager"); - } + SDL_assert(path != NULL); + + if (!PrepareAPK()) { + return false; } path = GetAssetPath(path); From e1e6cbe6ecf78da703829c62ff5335e7e9a16774 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Apr 2026 17:26:11 -0700 Subject: [PATCH 202/407] Disable accidentally enabled debug logging --- src/joystick/hidapi/SDL_hidapi_xboxone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 13a2bdc7b6..c94b9b5a88 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -34,7 +34,7 @@ // #define DEBUG_JOYSTICK // Define this if you want to log all packets from the controller -#if 1 +#if 0 #define DEBUG_XBOX_PROTOCOL #endif From 1aa72247af95802d897dabd51b29311e87c41ae0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 28 Apr 2026 21:52:21 -0500 Subject: [PATCH 203/407] pen: Only create touch emulation device when a pen is present --- src/events/SDL_mouse.c | 13 +++---------- src/events/SDL_pen.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 80bd6495f2..e389e47a16 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -194,16 +194,9 @@ static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, mouse->pen_touch_events = SDL_GetStringBoolean(hint, true); - if (mouse->pen_touch_events) { - if (!mouse->added_pen_touch_device) { - SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input"); - mouse->added_pen_touch_device = true; - } - } else { - if (mouse->added_pen_touch_device) { - SDL_DelTouch(SDL_PEN_TOUCHID); - mouse->added_pen_touch_device = false; - } + if (!mouse->pen_touch_events && mouse->added_pen_touch_device) { + SDL_DelTouch(SDL_PEN_TOUCHID); + mouse->added_pen_touch_device = false; } } diff --git a/src/events/SDL_pen.c b/src/events/SDL_pen.c index 61d41e1fea..83543a695e 100644 --- a/src/events/SDL_pen.c +++ b/src/events/SDL_pen.c @@ -228,6 +228,7 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo SDL_LockRWLockForWriting(pen_device_rwlock); + bool first_device = false; SDL_Pen *pen = NULL; void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen)); if (ptr) { @@ -236,6 +237,8 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo pen = &pen_devices[pen_device_count]; pen_device_count++; + first_device = (pen_device_count == 1); + SDL_zerop(pen); pen->instance_id = result; pen->name = namecpy; @@ -251,6 +254,14 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo SDL_free(namecpy); } + if (first_device) { + SDL_Mouse *mouse = SDL_GetMouse(); + if (mouse->pen_touch_events && !mouse->added_pen_touch_device) { + SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input"); + mouse->added_pen_touch_device = true; + } + } + if (result && in_proximity) { SDL_SendPenProximity(timestamp, result, window, true, true); } @@ -267,6 +278,7 @@ void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instanc SDL_SendPenProximity(timestamp, instance_id, window, false, true); // bye bye SDL_LockRWLockForWriting(pen_device_rwlock); + bool last_device = false; SDL_Pen *pen = FindPenByInstanceId(instance_id); if (pen) { SDL_free(pen->name); @@ -288,9 +300,18 @@ void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instanc } else { SDL_free(pen_devices); pen_devices = NULL; + last_device = true; } } SDL_UnlockRWLock(pen_device_rwlock); + + if (last_device) { + SDL_Mouse *mouse = SDL_GetMouse(); + if (mouse->added_pen_touch_device) { + SDL_DelTouch(SDL_PEN_TOUCHID); + mouse->added_pen_touch_device = false; + } + } } // This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here. From 1492911c7d752e5dc73b836ca25490919b344508 Mon Sep 17 00:00:00 2001 From: Jakub Wasilewski Date: Wed, 29 Apr 2026 10:26:35 +0200 Subject: [PATCH 204/407] metal: Added missing lock in METAL_INTERNAL_PerformPendingDestroys. Without this lock, a concurrent call to SDL_ReleaseGPUBuffer, SDL_ReleaseGPUTransferBuffer or SDL_ReleaseGPUTexture can cause one of the arrays to be reallocated while METAL_INTERNAL_PerformPendingDestroys is iterating over it, causing a bad day all around. --- src/gpu/metal/SDL_gpu_metal.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 1b69546c7f..de6c7b7fc8 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -3551,6 +3551,8 @@ static void METAL_INTERNAL_PerformPendingDestroys( Sint32 i; Uint32 j; + SDL_LockMutex(renderer->disposeLock); + for (i = renderer->bufferContainersToDestroyCount - 1; i >= 0; i -= 1) { referenceCount = 0; for (j = 0; j < renderer->bufferContainersToDestroy[i]->bufferCount; j += 1) { @@ -3580,6 +3582,8 @@ static void METAL_INTERNAL_PerformPendingDestroys( renderer->textureContainersToDestroyCount -= 1; } } + + SDL_UnlockMutex(renderer->disposeLock); } // Fences From 81cde11d1e680e2d8ba779377209f398a35c0c4c Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 29 Apr 2026 20:30:14 +0200 Subject: [PATCH 205/407] tests: fix test/emscripten/server.py when running without --map --- test/emscripten/server.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/emscripten/server.py b/test/emscripten/server.py index 103d1645c0..2e3849cd37 100755 --- a/test/emscripten/server.py +++ b/test/emscripten/server.py @@ -14,11 +14,14 @@ class MyHTTPRequestHandler(SimpleHTTPRequestHandler): extensions_map = { ".manifest": "text/cache-manifest", ".html": "text/html", + ".cmake": "text/cmake", + ".pc": "text/pkg-config", ".png": "image/png", ".jpg": "image/jpg", - ".svg": "image/svg+xml", - ".css": "text/css", - ".js": "application/x-javascript", + ".svg": "image/svg+xml", + ".css": "text/css", + ".js": "application/x-javascript", + ".map": "application/json", ".wasm": "application/wasm", "": "application/octet-stream", } @@ -65,7 +68,7 @@ def main(): parser = ArgumentParser(allow_abbrev=False) parser.add_argument("port", nargs="?", type=int, default=8080) parser.add_argument("-d", dest="directory", type=str, default=None) - parser.add_argument("--map", dest="maps", nargs="+", type=str, help="Mappings, used as e.g. \"$HOME/projects/SDL:/sdl\"") + parser.add_argument("--map", dest="maps", nargs="+", default=[], type=str, help="Mappings, used as e.g. \"$HOME/projects/SDL:/sdl\"") args = parser.parse_args() maps = [] From 41f079491a0e79b22441fd32a7c8ad91db237744 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 29 Apr 2026 17:51:26 -0500 Subject: [PATCH 206/407] pen: Fix enabling touch emulation while a pen is connected --- src/events/SDL_mouse.c | 18 -------------- src/events/SDL_pen.c | 55 +++++++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index e389e47a16..5dd25d713a 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -188,18 +188,6 @@ static void SDLCALL SDL_PenMouseEventsChanged(void *userdata, const char *name, mouse->pen_mouse_events = SDL_GetStringBoolean(hint, true); } -static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) -{ - SDL_Mouse *mouse = (SDL_Mouse *)userdata; - - mouse->pen_touch_events = SDL_GetStringBoolean(hint, true); - - if (!mouse->pen_touch_events && mouse->added_pen_touch_device) { - SDL_DelTouch(SDL_PEN_TOUCHID); - mouse->added_pen_touch_device = false; - } -} - static void SDLCALL SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; @@ -282,9 +270,6 @@ bool SDL_PreInitMouse(void) SDL_AddHintCallback(SDL_HINT_PEN_MOUSE_EVENTS, SDL_PenMouseEventsChanged, mouse); - SDL_AddHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, - SDL_PenTouchEventsChanged, mouse); - SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, SDL_MouseAutoCaptureChanged, mouse); @@ -1149,9 +1134,6 @@ void SDL_QuitMouse(void) SDL_RemoveHintCallback(SDL_HINT_PEN_MOUSE_EVENTS, SDL_PenMouseEventsChanged, mouse); - SDL_RemoveHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, - SDL_PenTouchEventsChanged, mouse); - SDL_RemoveHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, SDL_MouseAutoCaptureChanged, mouse); diff --git a/src/events/SDL_pen.c b/src/events/SDL_pen.c index 83543a695e..d70542b9f9 100644 --- a/src/events/SDL_pen.c +++ b/src/events/SDL_pen.c @@ -93,6 +93,33 @@ SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), return result; } +static void UpdateTouchEmulationDevicePresence(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + SDL_LockRWLockForReading(pen_device_rwlock); + bool has_pen = (pen_device_count != 0); + SDL_UnlockRWLock(pen_device_rwlock); + + if (!mouse->pen_touch_events || !has_pen) { + if (mouse->added_pen_touch_device) { + SDL_DelTouch(SDL_PEN_TOUCHID); + mouse->added_pen_touch_device = false; + } + } else if (!mouse->added_pen_touch_device) { + SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input"); + mouse->added_pen_touch_device = true; + } +} + +static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + mouse->pen_touch_events = SDL_GetStringBoolean(hint, true); + + UpdateTouchEmulationDevicePresence(); +} // public API ... @@ -106,11 +133,18 @@ bool SDL_InitPen(void) if (!pen_device_rwlock) { return false; } + + SDL_AddHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, + SDL_PenTouchEventsChanged, NULL); + return true; } void SDL_QuitPen(void) { + SDL_RemoveHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, + SDL_PenTouchEventsChanged, NULL); + SDL_RemoveAllPenDevices(NULL, NULL); SDL_DestroyRWLock(pen_device_rwlock); pen_device_rwlock = NULL; @@ -228,7 +262,6 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo SDL_LockRWLockForWriting(pen_device_rwlock); - bool first_device = false; SDL_Pen *pen = NULL; void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen)); if (ptr) { @@ -237,8 +270,6 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo pen = &pen_devices[pen_device_count]; pen_device_count++; - first_device = (pen_device_count == 1); - SDL_zerop(pen); pen->instance_id = result; pen->name = namecpy; @@ -254,13 +285,7 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *windo SDL_free(namecpy); } - if (first_device) { - SDL_Mouse *mouse = SDL_GetMouse(); - if (mouse->pen_touch_events && !mouse->added_pen_touch_device) { - SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input"); - mouse->added_pen_touch_device = true; - } - } + UpdateTouchEmulationDevicePresence(); if (result && in_proximity) { SDL_SendPenProximity(timestamp, result, window, true, true); @@ -278,7 +303,6 @@ void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instanc SDL_SendPenProximity(timestamp, instance_id, window, false, true); // bye bye SDL_LockRWLockForWriting(pen_device_rwlock); - bool last_device = false; SDL_Pen *pen = FindPenByInstanceId(instance_id); if (pen) { SDL_free(pen->name); @@ -300,18 +324,11 @@ void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instanc } else { SDL_free(pen_devices); pen_devices = NULL; - last_device = true; } } SDL_UnlockRWLock(pen_device_rwlock); - if (last_device) { - SDL_Mouse *mouse = SDL_GetMouse(); - if (mouse->added_pen_touch_device) { - SDL_DelTouch(SDL_PEN_TOUCHID); - mouse->added_pen_touch_device = false; - } - } + UpdateTouchEmulationDevicePresence(); } // This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here. From e9a6d7eda0bbd7c4468fc9b4e2a37e4e3b584985 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 30 Apr 2026 19:55:24 -0700 Subject: [PATCH 207/407] Fixed copyright on SDL_hidapi_steam_triton.c Fixes https://github.com/libsdl-org/SDL/issues/15486 Closes https://github.com/libsdl-org/SDL/pull/15487 --- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index aad2f3bfae..b911dae02e 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 2023 Max Maisel + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -84,7 +84,7 @@ typedef enum STEAM_BUTTON_LEFTPAD_CLICKED_MASK, // Left Pressure Click 0x04000000 STEAM_LEFT_TRIGGER_MASK, // Left Trigger Click 0x08000000 STEAM_RIGHT_AUX_MASK, // Right Pinky Touch 0x10000000 - STEAM_LEFT_AUX_MASK, // Left Pinky Touch 0x20000000 + STEAM_LEFT_AUX_MASK, // Left Pinky Touch 0x20000000 */ } TritonButtons; From c677c913a634a9ecf1e131f089fb31415382b722 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 30 Apr 2026 21:57:50 -0500 Subject: [PATCH 208/407] haptic: Enable gamepad haptic support under sdl2-compat --- src/haptic/SDL_haptic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index 5eaf095b4b..577502c922 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -306,9 +306,9 @@ bool SDL_IsJoystickHaptic(SDL_Joystick *joystick) SDL_LockJoysticks(); { - // Must be a valid joystick + // Must be a valid joystick, but not a gamepad unless running under sdl2-compat if (SDL_IsJoystickValid(joystick) && - !SDL_IsGamepad(SDL_GetJoystickID(joystick))) { + (SDL_GetHintBoolean("SDL2_COMPAT", false) || !SDL_IsGamepad(SDL_GetJoystickID(joystick)))) { #ifdef SDL_JOYSTICK_HIDAPI result = SDL_SYS_JoystickIsHaptic(joystick) || SDL_HIDAPI_JoystickIsHaptic(joystick); #else From f0b89704e915bc0d678cec9efbf961cf979d1ba6 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 29 Apr 2026 22:17:44 +0200 Subject: [PATCH 209/407] stdinc: use _Countof in SDL_arraysize _Countof is a compiler intrinsics that errors when using a pointer argument --- include/SDL3/SDL_begin_code.h | 24 ++++++++++++++++++++++++ include/SDL3/SDL_stdinc.h | 13 ++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_begin_code.h b/include/SDL3/SDL_begin_code.h index 4f3fe2d984..0c1feb0914 100644 --- a/include/SDL3/SDL_begin_code.h +++ b/include/SDL3/SDL_begin_code.h @@ -281,6 +281,22 @@ */ #define SDL_HAS_BUILTIN(x) __has_builtin(x) +/** + * Check if the compiler supports a given extension. + * + * This allows preprocessor checks for things that otherwise might fail to + * compile. + * + * Supported by virtually all clang versions and more-recent GCCs. Use this + * instead of checking the clang version if possible. + * + * On compilers without has_extension support, this is defined to 0 (always + * false). + * + * \since This macro is available since SDL 3.2.0. + */ +#define SDL_HAS_EXTENSION(x) __has_extension(x) + /** * A macro to specify data alignment. * @@ -344,6 +360,14 @@ #endif #endif +#ifndef SDL_HAS_EXTENSION +#ifdef __has_extension +#define SDL_HAS_EXTENSION(x) __has_extension(x) +#else +#define SDL_HAS_EXTENSION(x) 0 +#endif +#endif + #ifndef SDL_DEPRECATED # if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ # define SDL_DEPRECATED __attribute__((deprecated)) diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index ce8c7dbd5e..3e2266dc8f 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -52,6 +52,8 @@ #include #include +#include + /* Most everything except Visual Studio 2008 and earlier has stdint.h now */ #if defined(_MSC_VER) && (_MSC_VER < 1600) typedef signed __int8 int8_t; @@ -237,6 +239,8 @@ void *alloca(size_t); typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] #endif +#ifdef SDL_WIKI_DOCUMENTATION_SECTION + /** * The number of elements in a static array. * @@ -249,7 +253,15 @@ void *alloca(size_t); * * \since This macro is available since SDL 3.2.0. */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) /* or `_Countof(array)` on recent gcc and clang */ + +#else +#if (defined(__GNUC__) && __GNUC__ >= 16) || SDL_HAS_EXTENSION(c_countof) +#define SDL_arraysize(array) _Countof(array) +#else #define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#endif +#endif /** * Macro useful for building other macros with strings in them. @@ -1209,7 +1221,6 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); #endif /* DOXYGEN_SHOULD_IGNORE_THIS */ /** \endcond */ -#include /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus extern "C" { From 1cb61df1e51a715916233ba91e845c66a5a87e81 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Fri, 1 May 2026 11:14:17 +0200 Subject: [PATCH 210/407] [N-Gage] Fix image transformations, add color keying, and improve overall rendering performance. Fixes #15427 [N-Gage] Correct SDL_FLIP_HORIZONTAL for sprite sheet textures - ApplyFlip: swap toward midpoint when dest == source to avoid overwriting pixels before they are read - CopyEx: restore original bitmap pixels after BitBlt so the texture is not permanently mutated across frames - CopyEx: extract srcrect sub-region before transforming so flip/ rotate/scale operate on the correct pixels, not the full texture [N-Gage] Use scratch bitmap in CopyEx to avoid mutating source texture. Replace the write-then-restore pattern on the source texture with a persistent iScratchBitmap. The transform pipeline operates entirely within iPixelBufferA/B; the final result is copied into iScratchBitmap and BitBlt reads from there. The source texture is never written to. [N-Gage] Fix Copy() for render-target textures by using direct BitBlt Bypass pixel readback for SDL_TEXTUREACCESS_TARGET textures in CRenderer::Copy(). Reading raw pixels via DataAddress() on a server-side bitmap is unreliable; use BitBlt directly instead. [N-Gage] Implement color-key masking using Symbian's BitBltMasked. This implementation works fine, but relies on a platform specific property. This isn't ideal. Todo: Add SDL_PIXELFORMAT_ARGB4444 to the N-Gage's rendering back-end. [N-Gage] Avoid using BitBltMasked to improve performance. Much better! Write only non-color-key source pixels directly into the destination bitmap preserving existing destination pixels wherever the color key matches. This replaces BitBltMasked and avoids the cost of building an EGray2 mask. [N-Gage] Remove redundant function call since we're not using BitBltMasked() anymore. [N-Gage] Remove SDL_PROP_TEXTURE_NGAGE_COLOR_KEY_NUMBER - Promote SDL_PIXELFORMAT_XRGB4444 to SDL_PIXELFORMAT_ARGB4444 instead. - Remove now unused functions. --- src/render/SDL_render.c | 10 +- src/render/ngage/SDL_render_ngage.c | 17 +- src/render/ngage/SDL_render_ngage.cpp | 258 +++++++++++++++++++----- src/render/ngage/SDL_render_ngage_c.h | 7 +- src/render/ngage/SDL_render_ngage_c.hpp | 5 +- src/render/ngage/SDL_render_ops.cpp | 71 ++++++- src/render/ngage/SDL_render_ops.hpp | 2 + 7 files changed, 307 insertions(+), 63 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 4d76a7405e..5f80fae6d6 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1799,6 +1799,13 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s break; } } + } else if (surface->format == SDL_PIXELFORMAT_XRGB4444) { + for (i = 0; i < renderer->num_texture_formats; ++i) { + if (renderer->texture_formats[i] == SDL_PIXELFORMAT_ARGB4444) { + format = SDL_PIXELFORMAT_ARGB4444; + break; + } + } } } else { // Exact match would be fine @@ -1893,7 +1900,8 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h); - texture = SDL_CreateTextureWithProperties(renderer, props); + +texture = SDL_CreateTextureWithProperties(renderer, props); SDL_DestroyProperties(props); if (!texture) { return NULL; diff --git a/src/render/ngage/SDL_render_ngage.c b/src/render/ngage/SDL_render_ngage.c index b3710c39dc..bee541d280 100644 --- a/src/render/ngage/SDL_render_ngage.c +++ b/src/render/ngage/SDL_render_ngage.c @@ -116,6 +116,7 @@ static bool NGAGE_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL renderer->npot_texture_wrap_unsupported = true; SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB4444); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB4444); SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 1024); SDL_SetHintWithPriority(SDL_HINT_RENDER_LINE_METHOD, "2", SDL_HINT_OVERRIDE); @@ -162,6 +163,12 @@ static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD texture->internal = data; + // ARGB4444 textures are color-keyed: alpha=0 pixels are transparent. + if (texture->format == SDL_PIXELFORMAT_ARGB4444) { + data->has_color_key = true; + data->mask_dirty = true; + } + return true; } @@ -454,7 +461,7 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co } const int bytes_per_pixel = 2; - const int bitmap_pitch = texture->w * bytes_per_pixel; + const int bitmap_pitch = NGAGE_GetBitmapScanLineLength(phdata); const Uint8 *src = (const Uint8 *)pixels; dst += rect->y * bitmap_pitch + rect->x * bytes_per_pixel; @@ -466,6 +473,8 @@ static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, co dst += bitmap_pitch; } + phdata->mask_dirty = true; + return true; } @@ -483,7 +492,7 @@ static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons } const int bytes_per_pixel = 2; - const int bitmap_pitch = texture->w * bytes_per_pixel; + const int bitmap_pitch = NGAGE_GetBitmapScanLineLength(phdata); *pixels = (void *)(data + rect->y * bitmap_pitch + rect->x * bytes_per_pixel); *pitch = bitmap_pitch; @@ -492,6 +501,10 @@ static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { + NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; + if (phdata) { + phdata->mask_dirty = true; + } } static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index a4b9a6d0a1..cd312406af 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -75,6 +75,10 @@ void NGAGE_DestroyTextureData(NGAGE_TextureData *data) delete data->device; data->device = NULL; } + if (data->mask_bitmap) { + delete data->mask_bitmap; + data->mask_bitmap = NULL; + } delete data->bitmap; data->bitmap = NULL; } @@ -88,6 +92,14 @@ void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data) return data->bitmap->DataAddress(); } +int NGAGE_GetBitmapScanLineLength(NGAGE_TextureData *data) +{ + if (!data || !data->bitmap) { + return 0; + } + return (int)CFbsBitmap::ScanLineLength(data->bitmap->SizeInPixels().iWidth, EColor4K); +} + void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count) { gRenderer->DrawLines(verts, count); @@ -150,7 +162,7 @@ CRenderer *CRenderer::NewL() return self; } -CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iCurrentRenderTarget(0), iPixelBufferA(0), iPixelBufferB(0), iPixelBufferSize(0), iPointsBuffer(0), iPointsBufferSize(0) {} +CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0), iCurrentRenderTarget(0), iPixelBufferA(0), iPixelBufferB(0), iPixelBufferSize(0), iScratchBitmap(0), iMaskBitmap(0), iPointsBuffer(0), iPointsBufferSize(0) {} CRenderer::~CRenderer() { @@ -159,6 +171,10 @@ CRenderer::~CRenderer() SDL_free(iPixelBufferA); SDL_free(iPixelBufferB); + delete iScratchBitmap; + iScratchBitmap = 0; + delete iMaskBitmap; + iMaskBitmap = 0; delete[] iPointsBuffer; } @@ -326,18 +342,55 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec } SDL_FColor *c = &texture->color; - int w = texture->w; - int h = texture->h; const int bytes_per_pixel = 2; - int pitch = w * bytes_per_pixel; - void *source = phdata->bitmap->DataAddress(); - void *dest; - if (!source) { + int sw = srcrect->w; + int sh = srcrect->h; + + // Fast path: render target texture with no color mod. + // BitBlt directly from its bitmap — DataAddress() is unreliable + // for bitmaps that have been drawn into via a CFbsBitGc. + bool no_color_mod = (c->a == 1.f && c->r == 1.f && c->g == 1.f && c->b == 1.f); + float sx, sy; + SDL_GetRenderScale(renderer, &sx, &sy); + bool no_scale = (sx == 1.f && sy == 1.f); + + SDL_BlendMode blend; + SDL_GetTextureBlendMode(texture, &blend); + bool no_color_key = (blend != SDL_BLENDMODE_BLEND); + + if (phdata->gc && no_color_mod && no_scale && no_color_key) { + CFbsBitGc *gc = GetCurrentGc(); + if (gc) { + TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(sw, sh)); + TPoint aDest(dstrect->x, dstrect->y); + gc->BitBlt(aDest, phdata->bitmap, aSource); + } + return true; + } + + // Fast path: color-key with no color mod and no scale. + // Blit directly from the source bitmap into the destination, skipping transparent pixels. + if (no_color_mod && no_scale && !no_color_key && phdata->has_color_key) { + void *tex_data_ck = phdata->bitmap->DataAddress(); + CFbsBitmap *dst_bmp = GetCurrentBitmap(); + if (dst_bmp && tex_data_ck) { + int tex_stride_ck = CFbsBitmap::ScanLineLength(phdata->bitmap->SizeInPixels().iWidth, EColor4K) / 2; + TUint16 *src_base = static_cast(tex_data_ck) + srcrect->y * tex_stride_ck + srcrect->x; + BlitWithAlphaKey(dst_bmp, dstrect->x, dstrect->y, src_base, sw, sh, tex_stride_ck); + } + return true; + } + + int src_pitch = sw * bytes_per_pixel; + int tex_pitch = CFbsBitmap::ScanLineLength(texture->w, EColor4K); + + void *tex_data = phdata->bitmap->DataAddress(); + if (!tex_data) { return false; } - TInt required_size = pitch * h; + TInt required_size = src_pitch * sh; if (required_size > iPixelBufferSize) { void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size); if (!new_buffer_a) { @@ -354,39 +407,82 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec iPixelBufferSize = required_size; } - dest = iPixelBufferA; - - if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { - ApplyColorMod(dest, source, pitch, w, h, texture->color); - - source = dest; + // Ensure scratch bitmap is allocated and large enough. + if (!iScratchBitmap) { + iScratchBitmap = new CFbsBitmap(); + if (!iScratchBitmap) { + return false; + } + } + TSize scratch_size = iScratchBitmap->SizeInPixels(); + if (scratch_size.iWidth < sw || scratch_size.iHeight < sh) { + iScratchBitmap->Reset(); + TInt err = iScratchBitmap->Create(TSize(sw, sh), EColor4K); + if (err != KErrNone) { + return false; + } } - float sx; - float sy; - SDL_GetRenderScale(renderer, &sx, &sy); + // Extract the srcrect region from the texture into buffer A. + { + TUint16 *tex_pixels = (TUint16 *)tex_data; + TUint16 *buf_pixels = (TUint16 *)iPixelBufferA; + int tex_pitch_u16 = tex_pitch / 2; + for (int y = 0; y < sh; ++y) { + TUint16 *src_row = tex_pixels + (srcrect->y + y) * tex_pitch_u16 + srcrect->x; + TUint16 *dst_row = buf_pixels + y * sw; + Mem::Copy(dst_row, src_row, src_pitch); + } + } - if (sx != 1.f || sy != 1.f) { + void *source = iPixelBufferA; + void *dest = iPixelBufferB; + + if (!no_color_mod) { + ApplyColorMod(dest, source, src_pitch, sw, sh, texture->color); + void *tmp = source; + source = dest; + dest = tmp; + } + + if (!no_scale) { TFixed scale_x = Real2Fix(sx); TFixed scale_y = Real2Fix(sy); - TFixed center_x = Int2Fix(w / 2); - TFixed center_y = Int2Fix(h / 2); - - dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; - - ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y); - + TFixed center_x = Int2Fix(sw / 2); + TFixed center_y = Int2Fix(sh / 2); + ApplyScale(dest, source, src_pitch, sw, sh, center_x, center_y, scale_x, scale_y); + void *tmp = source; source = dest; + dest = tmp; } - Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); + // Copy result into scratch bitmap and blit from there. + // The source texture is never modified. + { + TUint16 *scratch_pixels = (TUint16 *)iScratchBitmap->DataAddress(); + TUint16 *res_pixels = (TUint16 *)source; + int scratch_pitch_u16 = CFbsBitmap::ScanLineLength(iScratchBitmap->SizeInPixels().iWidth, EColor4K) / 2; + + // Always copy all pixels into the scratch bitmap. + for (int y = 0; y < sh; ++y) { + TUint16 *dst_row = scratch_pixels + y * scratch_pitch_u16; + TUint16 *src_row = res_pixels + y * sw; + Mem::Copy(dst_row, src_row, src_pitch); + } - if (phdata->bitmap) { CFbsBitGc *gc = GetCurrentGc(); if (gc) { - TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h)); + TRect aSource(TPoint(0, 0), TSize(sw, sh)); TPoint aDest(dstrect->x, dstrect->y); - gc->BitBlt(aDest, phdata->bitmap, aSource); + + if (!no_color_key && phdata->has_color_key) { + CFbsBitmap *dst_bmp = GetCurrentBitmap(); + if (dst_bmp) { + BlitWithAlphaKey(dst_bmp, dstrect->x, dstrect->y, res_pixels, sw, sh, sw); + } + } else { + gc->BitBlt(aDest, iScratchBitmap, aSource); + } } } @@ -401,18 +497,19 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE } SDL_FColor *c = &texture->color; - int w = texture->w; - int h = texture->h; const int bytes_per_pixel = 2; - int pitch = w * bytes_per_pixel; - void *source = phdata->bitmap->DataAddress(); - void *dest; - if (!source) { + int sw = copydata->srcrect.w; + int sh = copydata->srcrect.h; + int src_pitch = sw * bytes_per_pixel; + int tex_pitch = CFbsBitmap::ScanLineLength(texture->w, EColor4K); + + void *tex_data = phdata->bitmap->DataAddress(); + if (!tex_data) { return false; } - TInt required_size = pitch * h; + TInt required_size = src_pitch * sh; if (required_size > iPixelBufferSize) { void *new_buffer_a = SDL_realloc(iPixelBufferA, required_size); if (!new_buffer_a) { @@ -429,39 +526,96 @@ bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE iPixelBufferSize = required_size; } - dest = iPixelBufferA; + // Ensure scratch bitmap is allocated and large enough for the srcrect. + if (!iScratchBitmap) { + iScratchBitmap = new CFbsBitmap(); + if (!iScratchBitmap) { + return false; + } + } + TSize scratch_size = iScratchBitmap->SizeInPixels(); + if (scratch_size.iWidth < sw || scratch_size.iHeight < sh) { + iScratchBitmap->Reset(); + TInt err = iScratchBitmap->Create(TSize(sw, sh), EColor4K); + if (err != KErrNone) { + return false; + } + } + + // Extract the srcrect region from the texture into buffer A. + { + TUint16 *tex_pixels = (TUint16 *)tex_data; + TUint16 *buf_pixels = (TUint16 *)iPixelBufferA; + int tex_pitch_u16 = tex_pitch / 2; + for (int y = 0; y < sh; ++y) { + TUint16 *src_row = tex_pixels + (copydata->srcrect.y + y) * tex_pitch_u16 + copydata->srcrect.x; + TUint16 *dst_row = buf_pixels + y * sw; + Mem::Copy(dst_row, src_row, src_pitch); + } + } + + void *source = iPixelBufferA; + void *dest = iPixelBufferB; if (copydata->flip) { - ApplyFlip(dest, source, pitch, w, h, copydata->flip); + ApplyFlip(dest, source, src_pitch, sw, sh, copydata->flip); + void *tmp = source; source = dest; + dest = tmp; } if (copydata->scale_x != 1.f || copydata->scale_y != 1.f) { - dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; - ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); + ApplyScale(dest, source, src_pitch, sw, sh, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y); + void *tmp = source; source = dest; + dest = tmp; } if (copydata->angle) { - dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; - ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle); + ApplyRotation(dest, source, src_pitch, sw, sh, copydata->center.x, copydata->center.y, copydata->angle); + void *tmp = source; source = dest; + dest = tmp; } if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) { - dest == iPixelBufferA ? dest = iPixelBufferB : dest = iPixelBufferA; - ApplyColorMod(dest, source, pitch, w, h, texture->color); + ApplyColorMod(dest, source, src_pitch, sw, sh, texture->color); + void *tmp = source; source = dest; + dest = tmp; } - Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h); + // Copy the final result into the scratch bitmap and blit from there. + // The source texture is never modified. + { + SDL_BlendMode blend; + SDL_GetTextureBlendMode(texture, &blend); + bool has_color_key = (blend == SDL_BLENDMODE_BLEND); + + TUint16 *scratch_pixels = (TUint16 *)iScratchBitmap->DataAddress(); + TUint16 *res_pixels = (TUint16 *)source; + int scratch_pitch_u16 = CFbsBitmap::ScanLineLength(iScratchBitmap->SizeInPixels().iWidth, EColor4K) / 2; + + // Always copy all pixels into the scratch bitmap. + for (int y = 0; y < sh; ++y) { + TUint16 *dst_row = scratch_pixels + y * scratch_pitch_u16; + TUint16 *src_row = res_pixels + y * sw; + Mem::Copy(dst_row, src_row, src_pitch); + } - if (phdata->bitmap) { CFbsBitGc *gc = GetCurrentGc(); if (gc) { - TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h)); + TRect aSource(TPoint(0, 0), TSize(sw, sh)); TPoint aDest(copydata->dstrect.x, copydata->dstrect.y); - gc->BitBlt(aDest, phdata->bitmap, aSource); + + if (has_color_key && phdata->has_color_key) { + CFbsBitmap *dst_bmp = GetCurrentBitmap(); + if (dst_bmp) { + BlitWithAlphaKey(dst_bmp, copydata->dstrect.x, copydata->dstrect.y, res_pixels, sw, sh, sw); + } + } else { + gc->BitBlt(aDest, iScratchBitmap, aSource); + } } } @@ -684,6 +838,14 @@ CFbsBitGc *CRenderer::GetCurrentGc() return iRenderer ? iRenderer->Gc() : NULL; } +CFbsBitmap *CRenderer::GetCurrentBitmap() +{ + if (iCurrentRenderTarget && iCurrentRenderTarget->bitmap) { + return iCurrentRenderTarget->bitmap; + } + return iRenderer ? iRenderer->Bitmap() : NULL; +} + static SDL_Scancode ConvertScancode(int key) { SDL_Keycode keycode; diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index 20f1af17cf..76a3619989 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -30,6 +30,7 @@ extern "C" { #endif #include "../SDL_sysrender.h" +#include "SDL3/SDL_render.h" typedef struct NGAGE_RendererData { @@ -63,6 +64,9 @@ typedef struct NGAGE_TextureData CFbsBitmap *bitmap; CFbsBitGc *gc; CFbsDevice *device; + CFbsBitmap *mask_bitmap; + bool has_color_key; + bool mask_dirty; } NGAGE_TextureData; @@ -93,7 +97,8 @@ bool NGAGE_Copy(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Rect *srcrect, bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData *copydata); bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height, const int access); void NGAGE_DestroyTextureData(NGAGE_TextureData *data); -void* NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); +void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); +int NGAGE_GetBitmapScanLineLength(NGAGE_TextureData *data); void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count); void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count); void NGAGE_FillRects(NGAGE_Vertex *verts, const int count); diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index b7776ec589..97e4ff272a 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -49,7 +49,8 @@ class CRenderer : public MDirectScreenAccess // Render target management. void SetRenderTarget(NGAGE_TextureData *aTarget); - CFbsBitGc* GetCurrentGc(); + CFbsBitGc *GetCurrentGc(); + CFbsBitmap *GetCurrentBitmap(); // Event handling. void DisableKeyBlocking(); @@ -98,6 +99,8 @@ class CRenderer : public MDirectScreenAccess void *iPixelBufferA; void *iPixelBufferB; TInt iPixelBufferSize; + CFbsBitmap *iScratchBitmap; + CFbsBitmap *iMaskBitmap; TPoint *iPointsBuffer; TInt iPointsBufferSize; }; diff --git a/src/render/ngage/SDL_render_ops.cpp b/src/render/ngage/SDL_render_ops.cpp index 3b998d8132..51d369d457 100644 --- a/src/render/ngage/SDL_render_ops.cpp +++ b/src/render/ngage/SDL_render_ops.cpp @@ -64,6 +64,36 @@ void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, S } } +void BlitWithAlphaKey(CFbsBitmap *dst, int dst_x, int dst_y, const void *src, int src_width, int src_height, int src_stride_u16) +{ + // Write only non-transparent (alpha != 0) source pixels into the destination bitmap. + // Pixels with alpha nibble == 0 are treated as color-key (transparent) and skipped. + TUint16 *dst_data = static_cast(static_cast(dst->DataAddress())); + const TUint16 *src_pixels = static_cast(src); + TSize dst_size = dst->SizeInPixels(); + int dst_stride_u16 = CFbsBitmap::ScanLineLength(dst_size.iWidth, EColor4K) / 2; + + for (int y = 0; y < src_height; ++y) { + int dy = dst_y + y; + if (dy < 0 || dy >= dst_size.iHeight) { + continue; + } + const TUint16 *src_row = src_pixels + y * src_stride_u16; + TUint16 *dst_row = dst_data + dy * dst_stride_u16; + for (int x = 0; x < src_width; ++x) { + int dx = dst_x + x; + if (dx < 0 || dx >= dst_size.iWidth) { + continue; + } + TUint16 p = src_row[x]; + if (p & 0xF000) { + // Strip the alpha nibble and write the RGB444 pixel. + dst_row[dx] = p & 0x0FFF; + } + } + } +} + void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_FlipMode flip) { TUint16 *src_pixels = static_cast(source); @@ -87,12 +117,19 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F // Fast path: horizontal flip only. if (flip == SDL_FLIP_HORIZONTAL) { + int width_minus_1 = width - 1; for (int y = 0; y < height; ++y) { - int dst_row_offset = y * pitch_offset; - int src_row_offset = y * pitch_offset; - int width_minus_1 = width - 1; - for (int x = 0; x < width; ++x) { - dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; + int row_offset = y * pitch_offset; + if (dest == source) { + for (int x = 0; x < width / 2; ++x) { + TUint16 tmp = src_pixels[row_offset + x]; + src_pixels[row_offset + x] = src_pixels[row_offset + (width_minus_1 - x)]; + src_pixels[row_offset + (width_minus_1 - x)] = tmp; + } + } else { + for (int x = 0; x < width; ++x) { + dst_pixels[row_offset + x] = src_pixels[row_offset + (width_minus_1 - x)]; + } } } return; @@ -114,11 +151,25 @@ void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_F // Both horizontal and vertical flip int width_minus_1 = width - 1; int height_minus_1 = height - 1; - for (int y = 0; y < height; ++y) { - int dst_row_offset = y * pitch_offset; - int src_row_offset = (height_minus_1 - y) * pitch_offset; - for (int x = 0; x < width; ++x) { - dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; + if (dest == source) { + // Swap pixels across the center point. + for (int y = 0; y < (height + 1) / 2; ++y) { + int top_offset = y * pitch_offset; + int bot_offset = (height_minus_1 - y) * pitch_offset; + int x_limit = (y == height_minus_1 - y) ? width / 2 : width; + for (int x = 0; x < x_limit; ++x) { + TUint16 tmp = src_pixels[top_offset + x]; + src_pixels[top_offset + x] = src_pixels[bot_offset + (width_minus_1 - x)]; + src_pixels[bot_offset + (width_minus_1 - x)] = tmp; + } + } + } else { + for (int y = 0; y < height; ++y) { + int dst_row_offset = y * pitch_offset; + int src_row_offset = (height_minus_1 - y) * pitch_offset; + for (int x = 0; x < width; ++x) { + dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; + } } } } diff --git a/src/render/ngage/SDL_render_ops.hpp b/src/render/ngage/SDL_render_ops.hpp index 65e92e5bca..08281e95a8 100644 --- a/src/render/ngage/SDL_render_ops.hpp +++ b/src/render/ngage/SDL_render_ops.hpp @@ -23,8 +23,10 @@ #define ngage_video_render_ops_hpp #include <3dtypes.h> +#include void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color); +void BlitWithAlphaKey(CFbsBitmap *dst, int dst_x, int dst_y, const void *src, int src_width, int src_height, int src_stride_u16); void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_FlipMode flip); void ApplyRotation(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle); void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y); From e70f1bfc29aa0aa9a4c066725df48ab336067d73 Mon Sep 17 00:00:00 2001 From: Igor <85039990+igorcafe@users.noreply.github.com> Date: Fri, 1 May 2026 18:01:13 -0300 Subject: [PATCH 211/407] X11TK: fix late null-check causing segfault The code is using `controls.window` before checking if it isn't null. I found this bug by accident when I tried to run `SDL_ShowSimpleMessageBox`. It first tried using Wayland with `zenity`, but since I don't have `zenity`, it fallbacked to `X11_ShowMessageBoxImpl`. For some reason it couldn't create a window, maybe something related to XWayland, so `controls.window` was `NULL`. --- src/video/x11/SDL_x11messagebox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index 251079a5d5..eff7aebe52 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -250,11 +250,11 @@ static bool X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int #else controls.window = X11Toolkit_CreateWindowStruct(parent_window, NULL, SDL_TOOLKIT_WINDOW_MODE_X11_DIALOG, colorhints, false); #endif - controls.window->cb_data = &controls; - controls.window->cb_on_scale_change = X11_OnMessageBoxScaleChange; if (!controls.window) { return false; } + controls.window->cb_data = &controls; + controls.window->cb_on_scale_change = X11_OnMessageBoxScaleChange; /* Create controls */ controls.buttonID = buttonID; From 4a52a5ee04cd5cd3e2757aa165b4cb7b96857c92 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 1 May 2026 16:57:07 -0700 Subject: [PATCH 212/407] Fixed crash on Windows when a controller is connected --- src/joystick/hidapi/SDL_hidapi_xboxone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index c94b9b5a88..a3fa66e7c8 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -376,7 +376,7 @@ static bool HIDAPI_DriverXboxOne_IsSupportedDevice(SDL_HIDAPI_Device *device, co } #endif #ifdef SDL_PLATFORM_WIN32 - if (SDL_strncmp(device->path, "\\\\?\\HID#", 8) == 0) { + if (device && SDL_strncmp(device->path, "\\\\?\\HID#", 8) == 0) { // Windows provides a fake HID endpoint for XGIP controllers, don't use this return false; } From 7629a5cf9add411269cd6ae1f3d6b18fd160beb1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 2 May 2026 20:21:20 +0300 Subject: [PATCH 213/407] SDL_test_memory.c: revised DWORD64 print --- src/test/SDL_test_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index 0536e7dad4..d4c6e64aa8 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -434,7 +434,7 @@ void SDLTest_LogAllocations(void) } dyn_dbghelp.pSymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)entry->stack[stack_index], &lineColumn, &dbg_line); } - SDL_snprintf(stack_entry_description, sizeof(stack_entry_description), "%s+0x%I64x %s:%u", pSymbol->Name, dwDisplacement, dbg_line.FileName, (Uint32)dbg_line.LineNumber); + SDL_snprintf(stack_entry_description, sizeof(stack_entry_description), "%s+0x%" SDL_PRIx64 " %s:%u", pSymbol->Name, (Uint64)dwDisplacement, dbg_line.FileName, (Uint32)dbg_line.LineNumber); } #endif (void)SDL_snprintf(line, sizeof(line), "\t0x%" SDL_PRIx64 ": %s\n", entry->stack[stack_index], stack_entry_description); From c805a4d6327dc33a8a9df0ccfc393967d10dade8 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Sun, 3 May 2026 21:26:15 +0500 Subject: [PATCH 214/407] Fix Xbox controller names in MFI joystick backend (#15499) controller.vendorName returns a generic name for Xbox controllers ("Controller"), so we have to give them proper names. --- src/joystick/apple/SDL_mfijoystick.m | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m index d512521a4b..758da44482 100644 --- a/src/joystick/apple/SDL_mfijoystick.m +++ b/src/joystick/apple/SDL_mfijoystick.m @@ -340,8 +340,6 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle name = "MFi Gamepad"; } - device->name = SDL_CreateJoystickName(0, 0, NULL, name); - #ifdef DEBUG_CONTROLLER_PROFILE NSLog(@"Product name: %@\n", controller.vendorName); NSLog(@"Product category: %@\n", controller.productCategory); @@ -428,12 +426,19 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle if (device->has_xbox_paddles) { // Assume Xbox One Elite Series 2 Controller unless/until GCController flows VID/PID product = USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH; + + // controller.vendorName returns a generic name for Xbox controllers ("Controller"), + // and controller.productCategory only returns "Xbox One" for those controllers, + // so we give them proper names based on the ones from SDL_gamepad_db.h + name = "Xbox One Elite 2 Controller"; } else if (device->has_xbox_share_button) { // Assume Xbox Series X Controller unless/until GCController flows VID/PID product = USB_PRODUCT_XBOX_SERIES_X_BLE; + name = "Xbox Series X Controller"; } else { // Assume Xbox One S Bluetooth Controller unless/until GCController flows VID/PID product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH; + name = "Xbox One Wireless Controller"; } } else if (device->is_ps4) { // Assume DS4 Slim unless/until GCController flows VID/PID @@ -611,6 +616,8 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle // We don't know how to get input events from this device return false; } + + device->name = SDL_CreateJoystickName(0, 0, NULL, name); Uint16 signature; if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { From 3ee0439ae508671ec9e5dc54b4a3e59105ad6972 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 3 May 2026 17:31:37 -0400 Subject: [PATCH 215/407] wayland: Pass the inverted flag for horizontal scroll events Natural scrolling affects both axes, and the compositor may not send the vertical axis orientation if the frame has no vertical scroll motion, so purely horizontal events need to be flagged as inverted as well. --- src/video/wayland/SDL_waylandevents.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index b974b7fe44..d2d492afbc 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1207,9 +1207,7 @@ static void pointer_handle_axis_relative_direction(void *data, struct wl_pointer uint32_t axis, uint32_t axis_relative_direction) { SDL_WaylandSeat *seat = data; - if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) { - return; - } + switch (axis_relative_direction) { case WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL: seat->pointer.pending_frame.axis.direction = SDL_MOUSEWHEEL_NORMAL; From c699512adcc139ec1a355ff97cb2e5dbab3c9ac2 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Mon, 4 May 2026 00:35:34 +0500 Subject: [PATCH 216/407] Add support for joystick motion sensors on Android --- .../org/libsdl/app/SDLControllerManager.java | 78 ++++++++++++++++++- src/core/android/SDL_android.c | 37 +++++++-- src/core/android/SDL_android.h | 1 + src/joystick/android/SDL_sysjoystick.c | 51 +++++++++++- src/joystick/android/SDL_sysjoystick_c.h | 6 +- 5 files changed, 163 insertions(+), 10 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 7655ecfd6f..03db25a467 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -10,6 +10,10 @@ import android.hardware.lights.Light; import android.hardware.lights.LightsRequest; import android.hardware.lights.LightsManager; import android.hardware.lights.LightState; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.graphics.Color; import android.os.Build; import android.os.VibrationEffect; @@ -30,7 +34,8 @@ public class SDLControllerManager static native void nativeAddJoystick(int device_id, String name, String desc, int vendor_id, int product_id, int button_mask, - int naxes, int axis_mask, int nhats, boolean can_rumble, boolean has_rgb_led); + int naxes, int axis_mask, int nhats, boolean can_rumble, boolean has_rgb_led, + boolean has_accelerometer, boolean has_gyroscope); static native void nativeRemoveJoystick(int device_id); static native void nativeAddHaptic(int device_id, String name); static native void nativeRemoveHaptic(int device_id); @@ -40,6 +45,7 @@ public class SDLControllerManager float value); static native void onNativeHat(int device_id, int hat_id, int x, int y); + static native void onNativeJoySensor(int device_id, int sensor_type, long sensor_timestamp, float x, float y, float z); protected static SDLJoystickHandler mJoystickHandler; protected static SDLHapticHandler mHapticHandler; @@ -81,6 +87,13 @@ public class SDLControllerManager mJoystickHandler.setLED(device_id, red, green, blue); } + /** + * This method is called by SDL using JNI. + */ + static void joystickSetSensorsEnabled(int device_id, boolean enabled) { + mJoystickHandler.setSensorsEnabled(device_id, enabled); + } + /** * This method is called by SDL using JNI. */ @@ -153,6 +166,10 @@ class SDLJoystickHandler { ArrayList hats; ArrayList lights; LightsManager.LightsSession lightsSession; + SensorManager sensorManager; + SDLJoySensorListener sensorListener; + Sensor accelerometerSensor; + Sensor gyroscopeSensor; } static class RangeComparator implements Comparator { @Override @@ -241,6 +258,8 @@ class SDLJoystickHandler { boolean can_rumble = false; boolean has_rgb_led = false; + boolean has_accelerometer = false; + boolean has_gyroscope = false; if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) { VibratorManager vibratorManager = joystickDevice.getVibratorManager(); int[] vibrators = vibratorManager.getVibratorIds(); @@ -258,12 +277,26 @@ class SDLJoystickHandler { joystick.lightsSession = lightsManager.openSession(); has_rgb_led = true; } + SensorManager sensorManager = joystickDevice.getSensorManager(); + if (sensorManager != null) { + joystick.sensorManager = sensorManager; + joystick.sensorListener = new SDLJoySensorListener(joystick.device_id); + joystick.accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (joystick.accelerometerSensor != null) { + has_accelerometer = true; + } + joystick.gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); + if (joystick.gyroscopeSensor != null) { + has_gyroscope = true; + } + } } mJoysticks.add(joystick); SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), - getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, can_rumble, has_rgb_led); + getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, can_rumble, has_rgb_led, + has_accelerometer, has_gyroscope); } } } @@ -508,6 +541,31 @@ class SDLJoystickHandler { } joystick.lightsSession.requestLights(lightsRequest.build()); } + + void setSensorsEnabled(int device_id, boolean enabled) { + if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) { + return; + } + SDLJoystick joystick = getJoystick(device_id); + if (joystick == null || joystick.sensorManager == null) { + return; + } + if (enabled) { + if (joystick.accelerometerSensor != null) { + joystick.sensorManager.registerListener(joystick.sensorListener, joystick.accelerometerSensor, SensorManager.SENSOR_DELAY_GAME, null); + } + if (joystick.gyroscopeSensor != null) { + joystick.sensorManager.registerListener(joystick.sensorListener, joystick.gyroscopeSensor, SensorManager.SENSOR_DELAY_GAME, null); + } + } else { + if (joystick.accelerometerSensor != null) { + joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.accelerometerSensor); + } + if (joystick.gyroscopeSensor != null) { + joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.gyroscopeSensor); + } + } + } } class SDLHapticHandler_API31 extends SDLHapticHandler { @@ -933,3 +991,19 @@ class SDLGenericMotionListener_API29 extends SDLGenericMotionListener_API26 { return penDevice.isExternal() ? SDL_PEN_DEVICE_TYPE_INDIRECT : SDL_PEN_DEVICE_TYPE_DIRECT; } } + +class SDLJoySensorListener implements SensorEventListener { + int device_id; + + public SDLJoySensorListener(int device_id) { + this.device_id = device_id; + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + SDLControllerManager.onNativeJoySensor(device_id, event.sensor.getType(), event.timestamp, event.values[0], event.values[1], event.values[2]); + } +} diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 3b642d2a8d..1781f703a9 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -312,10 +312,15 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEnv *env, jclass jcls, jint device_id, jint hat_id, jint x, jint y); +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor)( + JNIEnv *env, jclass jcls, + jint device_id, jint sensor_type, jlong sensor_timestamp, jfloat x, jfloat y, jfloat z); + JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv *env, jclass jcls, jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, - jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led); + jint button_mask, jint naxes, jint axis_mask, jint nhats, + jboolean can_rumble, jboolean has_rgb_led, jboolean has_accelerometer, jboolean has_gyroscope); JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( JNIEnv *env, jclass jcls, @@ -335,7 +340,8 @@ static JNINativeMethod SDLControllerManager_tab[] = { { "onNativePadUp", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) }, { "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) }, { "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) }, - { "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIIIIIZZ)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) }, + { "onNativeJoySensor", "(IIJFFF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor) }, + { "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIIIIIZZZZ)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) }, { "nativeRemoveJoystick", "(I)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) }, { "nativeAddHaptic", "(ILjava/lang/String;)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) }, { "nativeRemoveHaptic", "(I)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) } @@ -408,6 +414,7 @@ static jclass mControllerManagerClass; // method signatures static jmethodID midPollInputDevices; static jmethodID midJoystickSetLED; +static jmethodID midJoystickSetSensorsEnabled; static jmethodID midPollHapticDevices; static jmethodID midHapticRun; static jmethodID midHapticRumble; @@ -756,6 +763,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env "pollInputDevices", "()V"); midJoystickSetLED = (*env)->GetStaticMethodID(env, mControllerManagerClass, "joystickSetLED", "(IIII)V"); + midJoystickSetSensorsEnabled = (*env)->GetStaticMethodID(env, mControllerManagerClass, + "joystickSetSensorsEnabled", "(IZ)V"); midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass, "pollHapticDevices", "()V"); midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass, @@ -765,7 +774,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass, "hapticStop", "(I)V"); - if (!midPollInputDevices || !midJoystickSetLED || !midPollHapticDevices || !midHapticRun || !midHapticRumble || !midHapticStop) { + if (!midPollInputDevices || !midJoystickSetLED || !midJoystickSetSensorsEnabled || !midPollHapticDevices || !midHapticRun || !midHapticRumble || !midHapticStop) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); } @@ -1191,17 +1200,29 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( #endif // SDL_JOYSTICK_ANDROID } +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor)( + JNIEnv *env, jclass jcls, + jint device_id, jint sensor_type, jlong sensor_timestamp, jfloat x, jfloat y, jfloat z) +{ +#ifdef SDL_JOYSTICK_ANDROID + // In Java there's no Uint64 type, so pass Sint64 as if it was Uint64. + Android_OnJoySensor(device_id, sensor_type, sensor_timestamp, x, y, z); +#endif // SDL_JOYSTICK_ANDROID +} + JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv *env, jclass jcls, jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, - jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led) + jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led, + jboolean has_accelerometer, jboolean has_gyroscope) { #ifdef SDL_JOYSTICK_ANDROID const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL); - Android_AddJoystick(device_id, name, desc, vendor_id, product_id, button_mask, naxes, axis_mask, nhats, can_rumble, has_rgb_led); + Android_AddJoystick(device_id, name, desc, vendor_id, product_id, button_mask, naxes, axis_mask, nhats, + can_rumble, has_rgb_led, has_accelerometer, has_gyroscope); (*env)->ReleaseStringUTFChars(env, device_name, name); (*env)->ReleaseStringUTFChars(env, device_desc, desc); @@ -2626,6 +2647,12 @@ void Android_JNI_JoystickSetLED(int device_id, int red, int green, int blue) (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midJoystickSetLED, device_id, red, green, blue); } +void Android_JNI_JoystickSetSensorsEnabled(int device_id, bool enabled) +{ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midJoystickSetSensorsEnabled, device_id, (enabled == 1)); +} + void Android_JNI_PollHapticDevices(void) { JNIEnv *env = Android_JNI_GetEnv(); diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 9bb44eb49d..fa646e763d 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -105,6 +105,7 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco // Joystick support void Android_JNI_PollInputDevices(void); void Android_JNI_JoystickSetLED(int device_id, int red, int green, int blue); +void Android_JNI_JoystickSetSensorsEnabled(int device_id, bool enabled); // Haptic support void Android_JNI_PollHapticDevices(void); diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index feba3cdd32..671445e5bc 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -306,7 +306,37 @@ bool Android_OnHat(int device_id, int hat_id, int x, int y) return false; } -void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble, bool has_rgb_led) +void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp, float x, float y, float z) +{ + Uint64 timestamp = SDL_GetTicksNS(); + SDL_joylist_item *item; + SDL_SensorType sensor; + float data[3]; + + if (sensor_type == 1) { // Sensor.TYPE_ACCELEROMETER + sensor = SDL_SENSOR_ACCEL; + } else if (sensor_type == 4) { // Sensor.TYPE_GYROSCOPE + sensor = SDL_SENSOR_GYRO; + } else { + // Unsupported sensor + return; + } + + // The axes of sensor events and their signs are the same as SDL's, so no conversion required + data[0] = x; + data[1] = y; + data[2] = z; + + SDL_LockJoysticks(); + item = JoystickByDeviceId(device_id); + if (item && item->joystick) { + SDL_SendJoystickSensor(timestamp, item->joystick, sensor, sensor_timestamp, data, 3); + } + SDL_UnlockJoysticks(); +} + +void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, + bool can_rumble, bool has_rgb_led, bool has_accelerometer, bool has_gyroscope) { SDL_joylist_item *item; SDL_GUID guid; @@ -382,6 +412,8 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int item->nhats = nhats; item->can_rumble = can_rumble; item->has_rgb_led = has_rgb_led; + item->has_accelerometer = has_accelerometer; + item->has_gyroscope = has_accelerometer; item->device_instance = SDL_GetNextObjectID(); if (!SDL_joylist_tail) { SDL_joylist = SDL_joylist_tail = item; @@ -587,6 +619,13 @@ static bool ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index) SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, true); } + if (item->has_accelerometer) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f); + } + if (item->has_gyroscope) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f); + } + return true; } @@ -631,7 +670,15 @@ static bool ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data, static bool ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled) { - return SDL_Unsupported(); + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; + if (!item) { + return SDL_SetError("SetSensorsEnabled failed, device disconnected"); + } + if (!item->has_accelerometer && !item->has_gyroscope) { + return SDL_Unsupported(); + } + Android_JNI_JoystickSetSensorsEnabled(item->device_id, enabled); + return true; } static void ANDROID_JoystickUpdate(SDL_Joystick *joystick) diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h index 48f7ae2256..cd00380f75 100644 --- a/src/joystick/android/SDL_sysjoystick_c.h +++ b/src/joystick/android/SDL_sysjoystick_c.h @@ -32,7 +32,9 @@ extern bool Android_OnPadDown(int device_id, int keycode); extern bool Android_OnPadUp(int device_id, int keycode); extern bool Android_OnJoy(int device_id, int axisnum, float value); extern bool Android_OnHat(int device_id, int hat_id, int x, int y); -extern void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble, bool has_rgb_led); +extern void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp, float x, float y, float z); +extern void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, + bool can_rumble, bool has_rgb_led, bool has_accelerometer, bool has_gyroscope); extern void Android_RemoveJoystick(int device_id); // A linked list of available joysticks @@ -47,6 +49,8 @@ typedef struct SDL_joylist_item int dpad_state; bool can_rumble; bool has_rgb_led; + bool has_accelerometer; + bool has_gyroscope; struct SDL_joylist_item *next; } SDL_joylist_item; From 3c1636a9584e5ccaecd9371bdf92520ec39cd04e Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Mon, 4 May 2026 20:41:48 +0500 Subject: [PATCH 217/407] Fix JoyCon mappings on Android --- .../main/java/org/libsdl/app/SDLActivity.java | 8 +- .../org/libsdl/app/SDLControllerManager.java | 4 +- src/core/android/SDL_android.c | 16 +- src/joystick/SDL_gamepad.c | 185 ++++++++++-------- src/joystick/android/SDL_sysjoystick.c | 40 +++- src/joystick/android/SDL_sysjoystick_c.h | 4 +- 6 files changed, 159 insertions(+), 98 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index c5777dccc4..0491ccab20 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -1478,14 +1478,16 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and // SOURCE_JOYSTICK, while its key events arrive from the keyboard source // So, retrieve the device itself and check all of its sources - if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) { + // + // Echo events (event.getRepeatCount() > 0) should be ignored + if (SDLControllerManager.isDeviceSDLJoystick(deviceId) && event.getRepeatCount() == 0) { // Note that we process events with specific key codes here if (event.getAction() == KeyEvent.ACTION_DOWN) { - if (SDLControllerManager.onNativePadDown(deviceId, keyCode)) { + if (SDLControllerManager.onNativePadDown(deviceId, keyCode, event.getScanCode())) { return true; } } else if (event.getAction() == KeyEvent.ACTION_UP) { - if (SDLControllerManager.onNativePadUp(deviceId, keyCode)) { + if (SDLControllerManager.onNativePadUp(deviceId, keyCode, event.getScanCode())) { return true; } } diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 03db25a467..bcdf33233a 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -39,8 +39,8 @@ public class SDLControllerManager static native void nativeRemoveJoystick(int device_id); static native void nativeAddHaptic(int device_id, String name); static native void nativeRemoveHaptic(int device_id); - static public native boolean onNativePadDown(int device_id, int keycode); - static public native boolean onNativePadUp(int device_id, int keycode); + static public native boolean onNativePadDown(int device_id, int keycode, int scancode); + static public native boolean onNativePadUp(int device_id, int keycode, int scancode); static native void onNativeJoy(int device_id, int axis, float value); static native void onNativeHat(int device_id, int hat_id, diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 1781f703a9..3e24056bd5 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -298,11 +298,11 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)( JNIEXPORT jboolean JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( JNIEnv *env, jclass jcls, - jint device_id, jint keycode); + jint device_id, jint keycode, jint scancode); JNIEXPORT jboolean JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( JNIEnv *env, jclass jcls, - jint device_id, jint keycode); + jint device_id, jint keycode, jint scancode); JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( JNIEnv *env, jclass jcls, @@ -336,8 +336,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( static JNINativeMethod SDLControllerManager_tab[] = { { "nativeSetupJNI", "()V", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) }, - { "onNativePadDown", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) }, - { "onNativePadUp", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) }, + { "onNativePadDown", "(III)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) }, + { "onNativePadUp", "(III)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) }, { "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) }, { "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) }, { "onNativeJoySensor", "(IIJFFF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor) }, @@ -1159,10 +1159,10 @@ SDL_JAVA_AUDIO_INTERFACE(nativeRemoveAudioDevice)(JNIEnv *env, jclass jcls, jboo // Paddown JNIEXPORT jboolean JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( JNIEnv *env, jclass jcls, - jint device_id, jint keycode) + jint device_id, jint keycode, jint scancode) { #ifdef SDL_JOYSTICK_ANDROID - return Android_OnPadDown(device_id, keycode); + return Android_OnPadDown(device_id, keycode, scancode); #else return false; #endif // SDL_JOYSTICK_ANDROID @@ -1171,10 +1171,10 @@ JNIEXPORT jboolean JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( // Padup JNIEXPORT jboolean JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( JNIEnv *env, jclass jcls, - jint device_id, jint keycode) + jint device_id, jint keycode, jint scancode) { #ifdef SDL_JOYSTICK_ANDROID - return Android_OnPadUp(device_id, keycode); + return Android_OnPadUp(device_id, keycode, scancode); #else return false; #endif // SDL_JOYSTICK_ANDROID diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 72d43a5552..71419ed3cd 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -713,91 +713,116 @@ static GamepadMapping_t *SDL_CreateMappingForAndroidGamepad(SDL_GUID guid) char mapping_string[1024]; int button_mask; int axis_mask; + Uint16 vendor, product; + + SDL_strlcpy(mapping_string, "none,", sizeof(mapping_string)); - button_mask = SDL_Swap16LE(*(Uint16 *)(&guid.data[sizeof(guid.data) - 4])); - axis_mask = SDL_Swap16LE(*(Uint16 *)(&guid.data[sizeof(guid.data) - 2])); - if (!button_mask && !axis_mask) { - // Accelerometer, shouldn't have a gamepad mapping - return NULL; - } - if (!(button_mask & face_button_mask)) { - // We don't know what buttons or axes are supported, don't make up a mapping - return NULL; - } + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + if (vendor == USB_VENDOR_NINTENDO) { + if (product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) { + // FIXME: Should we have a separate hint for non-HIDAPI JoyCon handling? + // Android doesn't report JoyCon SL/SR presses for some reason, so no horizontal triggers/vertical paddles + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, false)) { + // Vertical mode + if (product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT) { + SDL_strlcat(mapping_string, "Nintendo Switch Joy-Con (L),back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,misc1:b18,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "Nintendo Switch Joy-Con (R),a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a0,righty:a1,start:b6,x:b3,y:b2,", sizeof(mapping_string)); + } + } else { + // Mini gamepad mode + if (product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT) { + SDL_strlcat(mapping_string, "Nintendo Switch Joy-Con (L),a:b13,b:b12,guide:b18,leftstick:b7,leftx:a1,lefty:a0~,start:b4,x:b11,y:b14,paddle2:b9,paddle4:b15,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "Nintendo Switch Joy-Con (R),a:b1,b:b2,guide:b5,leftstick:b8,leftx:a1~,lefty:a0,start:b6,x:b0,y:b3,paddle1:b10,paddle3:b16,", sizeof(mapping_string)); + } + } + } + } else { + button_mask = SDL_Swap16LE(*(Uint16 *)(&guid.data[sizeof(guid.data) - 4])); + axis_mask = SDL_Swap16LE(*(Uint16 *)(&guid.data[sizeof(guid.data) - 2])); + if (!button_mask && !axis_mask) { + // Accelerometer, shouldn't have a gamepad mapping + return NULL; + } + if (!(button_mask & face_button_mask)) { + // We don't know what buttons or axes are supported, don't make up a mapping + return NULL; + } - SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + SDL_strlcpy(mapping_string, "*,", sizeof(mapping_string)); - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_SOUTH)) { - SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_EAST)) { - SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string)); - } else if (button_mask & (1 << SDL_GAMEPAD_BUTTON_BACK)) { - // Use the back button as "B" for easy UI navigation with TV remotes - SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string)); - button_mask &= ~(1 << SDL_GAMEPAD_BUTTON_BACK); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_WEST)) { - SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_NORTH)) { - SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_BACK)) { - SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_GUIDE)) { - // The guide button generally isn't functional (or acts as a home button) on most Android gamepads before Android 11 - if (SDL_GetAndroidSDKVersion() >= 30 /* Android 11 */) { - SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string)); + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_SOUTH)) { + SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_EAST)) { + SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string)); + } else if (button_mask & (1 << SDL_GAMEPAD_BUTTON_BACK)) { + // Use the back button as "B" for easy UI navigation with TV remotes + SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string)); + button_mask &= ~(1 << SDL_GAMEPAD_BUTTON_BACK); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_WEST)) { + SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_NORTH)) { + SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_BACK)) { + SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_GUIDE)) { + // The guide button generally isn't functional (or acts as a home button) on most Android gamepads before Android 11 + if (SDL_GetAndroidSDKVersion() >= 30 /* Android 11 */) { + SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string)); + } + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_START)) { + SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_STICK)) { + SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_STICK)) { + SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_SHOULDER)) { + SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER)) { + SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_UP)) { + SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN)) { + SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT)) { + SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_RIGHT)) { + SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFTX)) { + SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFTY)) { + SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHTX)) { + SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHTY)) { + SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER)) { + SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER)) { + SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string)); } } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_START)) { - SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_STICK)) { - SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_STICK)) { - SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_SHOULDER)) { - SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER)) { - SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_UP)) { - SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN)) { - SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT)) { - SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_GAMEPAD_BUTTON_DPAD_RIGHT)) { - SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFTX)) { - SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFTY)) { - SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHTX)) { - SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHTY)) { - SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER)) { - SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER)) { - SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string)); - } - return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_GAMEPAD_MAPPING_PRIORITY_DEFAULT); } #endif // SDL_PLATFORM_ANDROID diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 671445e5bc..265c32e391 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -29,8 +29,10 @@ #include "../../events/SDL_keyboard_c.h" #include "../../core/android/SDL_android.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../usb_ids.h" #include "android/keycodes.h" +#include // As of platform android-14, android/keycodes.h is missing these defines #ifndef AKEYCODE_BUTTON_1 @@ -170,6 +172,31 @@ static int keycode_to_SDL(int keycode) return button; } +static int scancode_to_SDL(int scancode) +{ + int button = 0; + switch (scancode) { + // D-Pad buttons on the left JoyCon + case BTN_DPAD_UP: + button = SDL_GAMEPAD_BUTTON_DPAD_UP; + break; + case BTN_DPAD_DOWN: + button = SDL_GAMEPAD_BUTTON_DPAD_DOWN; + break; + case BTN_DPAD_LEFT: + button = SDL_GAMEPAD_BUTTON_DPAD_LEFT; + break; + case BTN_DPAD_RIGHT: + button = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; + break; + + default: + return -1; + } + SDL_assert(button < ANDROID_MAX_NBUTTONS); + return button; +} + static SDL_Scancode button_to_scancode(int button) { switch (button) { @@ -195,11 +222,14 @@ static SDL_Scancode button_to_scancode(int button) return SDL_SCANCODE_UNKNOWN; } -bool Android_OnPadDown(int device_id, int keycode) +bool Android_OnPadDown(int device_id, int keycode, int scancode) { Uint64 timestamp = SDL_GetTicksNS(); SDL_joylist_item *item; int button = keycode_to_SDL(keycode); + if (button < 0) { + button = scancode_to_SDL(scancode); + } if (button >= 0) { SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); @@ -215,11 +245,14 @@ bool Android_OnPadDown(int device_id, int keycode) return false; } -bool Android_OnPadUp(int device_id, int keycode) +bool Android_OnPadUp(int device_id, int keycode, int scancode) { Uint64 timestamp = SDL_GetTicksNS(); SDL_joylist_item *item; int button = keycode_to_SDL(keycode); + if (button < 0) { + button = scancode_to_SDL(scancode); + } if (button >= 0) { SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); @@ -367,8 +400,9 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats", name, desc, vendor_id, product_id, naxes, nhats); #endif - if (nhats > 0) { + if (nhats > 0 || (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT)) { // Hat is translated into DPAD buttons + // D-Pad on the left JoyCon is a special case, it's not recognized via keycodes or hats, only scancodes button_mask |= ((1 << SDL_GAMEPAD_BUTTON_DPAD_UP) | (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN) | (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT) | diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h index cd00380f75..f99abb5e61 100644 --- a/src/joystick/android/SDL_sysjoystick_c.h +++ b/src/joystick/android/SDL_sysjoystick_c.h @@ -28,8 +28,8 @@ #include "../SDL_sysjoystick.h" -extern bool Android_OnPadDown(int device_id, int keycode); -extern bool Android_OnPadUp(int device_id, int keycode); +extern bool Android_OnPadDown(int device_id, int keycode, int scancode); +extern bool Android_OnPadUp(int device_id, int keycode, int scancode); extern bool Android_OnJoy(int device_id, int axisnum, float value); extern bool Android_OnHat(int device_id, int hat_id, int x, int y); extern void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp, float x, float y, float z); From 922b872b4f3ea0fa5ae959040fe14157ac295449 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 May 2026 23:43:34 -0400 Subject: [PATCH 218/407] thread: Remove semaphore in thread creation. This was added so that the new thread definitely has its threadid set, via SDL_GetCurrentThreadID(), before SDL_CreatThread returns, but this broke Emscripten, which can't wait on a newly-created thread, since the thread won't start until a later mainloop iteration. Now we have the creating thread set this id in SDL_SYS_CreateThread, where platform-specific logic can figure out how to calculate the new thread's ID from the parent thread, without using SDL_GetCurrentThreadID(). Fixes #15509. --- src/thread/SDL_thread.c | 17 ----------------- src/thread/SDL_thread_c.h | 1 - src/thread/dos/SDL_systhread.c | 2 ++ src/thread/n3ds/SDL_systhread.c | 4 ++++ src/thread/ps2/SDL_systhread.c | 3 +++ src/thread/psp/SDL_systhread.c | 2 ++ src/thread/pthread/SDL_systhread.c | 2 ++ src/thread/vita/SDL_systhread.c | 2 ++ src/thread/windows/SDL_systhread.c | 3 +++ 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 0d02bcd312..639090c498 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -335,11 +335,6 @@ void SDL_RunThread(SDL_Thread *thread) // Perform any system-dependent setup - this function may not fail SDL_SYS_SetupThread(thread->name); - // Get the thread id - thread->threadid = SDL_GetCurrentThreadID(); - - SDL_SignalSemaphore(thread->ready_sem); // the thread is officially ready to run! - // Run the function *statusloc = userfunc(userdata); @@ -396,13 +391,6 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props, } } - thread->ready_sem = SDL_CreateSemaphore(0); - if (!thread->ready_sem) { - SDL_free(thread->name); - SDL_free(thread); - return NULL; - } - thread->userfunc = fn; thread->userdata = userdata; thread->stacksize = stacksize; @@ -413,16 +401,11 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props, if (!SDL_SYS_CreateThread(thread, pfnBeginThread, pfnEndThread)) { // Oops, failed. Gotta free everything SDL_SetObjectValid(thread, SDL_OBJECT_TYPE_THREAD, false); - SDL_DestroySemaphore(thread->ready_sem); SDL_free(thread->name); SDL_free(thread); return NULL; } - SDL_WaitSemaphore(thread->ready_sem); - SDL_DestroySemaphore(thread->ready_sem); - thread->ready_sem = NULL; - // Everything is running now return thread; } diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 47efd59f0e..4f35e13515 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -56,7 +56,6 @@ struct SDL_Thread SDL_error errbuf; char *name; size_t stacksize; // 0 for default, >0 for user-specified stack size. - SDL_Semaphore *ready_sem; // signals when the thread is set up and about to start running. int(SDLCALL *userfunc)(void *); void *userdata; void *data; diff --git a/src/thread/dos/SDL_systhread.c b/src/thread/dos/SDL_systhread.c index b118d0832a..88cf12010c 100644 --- a/src/thread/dos/SDL_systhread.c +++ b/src/thread/dos/SDL_systhread.c @@ -51,6 +51,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, } thread->handle = tid; + thread->threadid = (SDL_ThreadID) tid; + return true; } diff --git a/src/thread/n3ds/SDL_systhread.c b/src/thread/n3ds/SDL_systhread.c index a9a18ab8f7..5c1f0a1fa0 100644 --- a/src/thread/n3ds/SDL_systhread.c +++ b/src/thread/n3ds/SDL_systhread.c @@ -72,6 +72,10 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, return SDL_SetError("Couldn't create thread"); } + u32 thread_ID = 0; + svcGetThreadId(&thread_ID, threadGetHandle(thread->handle)); + thread->threadid = (SDL_ThreadID) thread_ID; + return true; } diff --git a/src/thread/ps2/SDL_systhread.c b/src/thread/ps2/SDL_systhread.c index 96c9dcc8e5..6d038915c6 100644 --- a/src/thread/ps2/SDL_systhread.c +++ b/src/thread/ps2/SDL_systhread.c @@ -95,6 +95,9 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, if (StartThread(thread->handle, thread) < 0) { return SDL_SetError("StartThread() failed"); } + + thread->threadid = (SDL_ThreadID) thread->handle; + return true; } diff --git a/src/thread/psp/SDL_systhread.c b/src/thread/psp/SDL_systhread.c index 545165846d..f61dcea790 100644 --- a/src/thread/psp/SDL_systhread.c +++ b/src/thread/psp/SDL_systhread.c @@ -66,6 +66,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, return SDL_SetError("sceKernelCreateThread() failed"); } + thread->threadid = (SDL_ThreadID) thread->handle; + sceKernelStartThread(thread->handle, 4, &thread); return true; } diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index fd16b2d8eb..eb13d02490 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -116,6 +116,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, return SDL_SetError("Not enough resources to create thread"); } + thread->threadid = (SDL_ThreadID) thread->handle; // the SDL thread ID is just the pthread_t. + return true; } diff --git a/src/thread/vita/SDL_systhread.c b/src/thread/vita/SDL_systhread.c index 79ac8b5ffb..32946522a1 100644 --- a/src/thread/vita/SDL_systhread.c +++ b/src/thread/vita/SDL_systhread.c @@ -86,6 +86,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, return SDL_SetError("sceKernelCreateThread() failed"); } + thread->threadid = (SDL_ThreadID) thread->handle; + sceKernelStartThread(thread->handle, 4, &thread); return true; } diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index 530f44929a..1244c34464 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -77,15 +77,18 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread, thread->handle = (SYS_ThreadHandle)((size_t)pfnBeginThread(NULL, (unsigned int)thread->stacksize, RunThreadViaBeginThreadEx, thread, flags, &threadid)); + thread->threadid = (SDL_ThreadID) threadid; } else { DWORD threadid = 0; thread->handle = CreateThread(NULL, thread->stacksize, RunThreadViaCreateThread, thread, flags, &threadid); + thread->threadid = (SDL_ThreadID) threadid; } if (!thread->handle) { return SDL_SetError("Not enough resources to create thread"); } + return true; } From 93a5d33386ba867034d4ec09169325f8f5df3ce0 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Tue, 5 May 2026 13:04:07 +0200 Subject: [PATCH 219/407] [N-Gage] Rename variable to avoid warning that the declaration of free' shadows global declaration. --- src/core/ngage/SDL_ngage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ngage/SDL_ngage.cpp b/src/core/ngage/SDL_ngage.cpp index 518d43fd92..dcd1daca62 100644 --- a/src/core/ngage/SDL_ngage.cpp +++ b/src/core/ngage/SDL_ngage.cpp @@ -53,8 +53,8 @@ void NGAGE_DebugPrintf(const char *fmt, ...) TInt NGAGE_GetFreeHeapMemory() { - TInt free = 0; - return User::Available(free); + TInt heap_available = 0; + return User::Available(heap_available); } #ifdef __cplusplus From f6f4664ed1c75663e71ab4e39f6de0909fcb5106 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 5 May 2026 08:53:01 -0700 Subject: [PATCH 220/407] Fixed rare cursor corruption on Windows If the cursor was created with a temporary surface that was pointing at external memory, then when the cursor is used it might be referencing memory that had already been freed. --- src/video/windows/SDL_windowsmouse.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index 2cd4e726f3..3e7772b451 100644 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -148,9 +148,23 @@ static SDL_Cursor *WIN_CreateAnimatedCursorAndData(SDL_CursorFrameInfo *frames, data->hot_y = hot_y; data->num_frames = frame_count; for (int i = 0; i < frame_count; ++i) { - data->frames[i].surface = frames[i].surface; + SDL_Surface *surface = frames[i].surface; + if (surface->flags & SDL_SURFACE_PREALLOCATED) { + surface = SDL_DuplicateSurface(surface); + if (!surface) { + while (i > 0) { + --i; + SDL_DestroySurface(data->frames[i].surface); + } + SDL_free(data); + SDL_free(cursor); + return NULL; + } + } else { + ++surface->refcount; + } + data->frames[i].surface = surface; data->frames[i].duration = frames[i].duration; - ++frames[i].surface->refcount; } cursor->internal = data; return cursor; From b8545fce54ba9d0c24836ff9ab5d5b0737d04f92 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 5 May 2026 12:51:45 -0400 Subject: [PATCH 221/407] x11: Disable the X Synchronization Extension by default Under the right conditions, this extension can result is smoother resizing when rendering with OpenGL, however, it is known to cause problems in certain cases, such as when handling presentation externally. Gate it behind a hint, and disable it by default. Developers can selectively enable it when they verify that they meet the criteria for using it, and that it behaves correctly in their apps/games. --- include/SDL3/SDL_hints.h | 25 +++++++++++++++++++++++++ src/video/x11/SDL_x11window.c | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 2f01f09881..00c185b3c6 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -4128,6 +4128,31 @@ extern "C" { */ #define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" +/** + * A variable controlling whether the X Synchronization Extension is enabled. + * + * If set, this can result in smoother window resizing when rendering using + * OpenGL, however, there are some conditions: + * + * - It is only activated on windows created with the `SDL_WINDOW_OPENGL` flag + * (windows using an SDL OpenGL renderer have this automatically set). + * - When activated, presentation must be done with `SDL_GL_SwapWindow()` + * (`SDL_RenderPresent()` calls this internally for OpenGL renderers as well). + * + * Enabling this and presenting via an external mechanism will result in sync + * requests not being acked, and hangs and other odd window behavior may result. + * + * The variable can be set to the following values: + * + * - "0": The X Synchronization Extension is disabled. (default) + * - "1": The X Synchronization Extension is enabled. + * + * This hint should be set before creating a window. + * + * \since This hint is available since SDL 3.4.10. + */ +#define SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT "SDL_VIDEO_X11_ENABLE_XSYNC_EXT" + /** * A variable controlling whether SDL should call XSelectInput() to enable * input events on X11 windows wrapped by SDL windows. diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 4a68287cc2..b1f982a32e 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -585,7 +585,8 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties } const bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, false); - const bool use_resize_sync = !!(window->flags & SDL_WINDOW_OPENGL); // Doesn't work well with Vulkan + const bool use_resize_sync = SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT, false) && + (window->flags & SDL_WINDOW_OPENGL) != 0; // Doesn't work well with Vulkan SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; From c7df6fe847b0cf0164567f1e9c9fa08b8a03e0f7 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Tue, 5 May 2026 17:47:49 +0000 Subject: [PATCH 222/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_hints.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 00c185b3c6..2e1991d4b4 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -4134,13 +4134,15 @@ extern "C" { * If set, this can result in smoother window resizing when rendering using * OpenGL, however, there are some conditions: * - * - It is only activated on windows created with the `SDL_WINDOW_OPENGL` flag - * (windows using an SDL OpenGL renderer have this automatically set). - * - When activated, presentation must be done with `SDL_GL_SwapWindow()` - * (`SDL_RenderPresent()` calls this internally for OpenGL renderers as well). + * - It is only activated on windows created with the `SDL_WINDOW_OPENGL` flag + * (windows using an SDL OpenGL renderer have this automatically set). + * - When activated, presentation must be done with `SDL_GL_SwapWindow()` + * (`SDL_RenderPresent()` calls this internally for OpenGL renderers as + * well). * * Enabling this and presenting via an external mechanism will result in sync - * requests not being acked, and hangs and other odd window behavior may result. + * requests not being acked, and hangs and other odd window behavior may + * result. * * The variable can be set to the following values: * From fee8c94b5c7211dd04349470a6ff333f07ac0d99 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Tue, 5 May 2026 12:55:16 -0700 Subject: [PATCH 223/407] GPU: D3D12 stencil plane transition (#15519) --- src/gpu/d3d12/SDL_gpu_d3d12.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 75a4c99a76..3a1d651fdd 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -1838,6 +1838,16 @@ static inline Uint32 D3D12_INTERNAL_CalcSubresource( return mipLevel + (layer * numLevels); } +static inline Uint32 D3D12_INTERNAL_CalcSubresourceWithPlane( + Uint32 mipLevel, + Uint32 layer, + Uint32 planeSlice, + Uint32 numLevels, + Uint32 arraySize) +{ + return mipLevel + (layer * numLevels) + (planeSlice * numLevels * arraySize); +} + static void D3D12_INTERNAL_ResourceBarrier( D3D12CommandBuffer *commandBuffer, D3D12_RESOURCE_STATES sourceState, @@ -1894,6 +1904,27 @@ static void D3D12_INTERNAL_TextureSubresourceBarrier( textureSubresource->parent->resource, textureSubresource->index, needsUAVBarrier); + + // D3D12 stores planar values on a separate subresource. + // Since depth-stencil is our only supported planar format, + // just force an extra transition if we're using a stencil format. + if (IsStencilFormat(textureSubresource->parent->container->header.info.format)) { + Uint32 planeSubresourceIndex = D3D12_INTERNAL_CalcSubresourceWithPlane( + textureSubresource->level, + textureSubresource->layer, + 1, + textureSubresource->parent->container->header.info.num_levels, + textureSubresource->parent->container->header.info.layer_count_or_depth + ); + + D3D12_INTERNAL_ResourceBarrier( + commandBuffer, + sourceState, + destinationState, + textureSubresource->parent->resource, + planeSubresourceIndex, + needsUAVBarrier); + } } static D3D12_RESOURCE_STATES D3D12_INTERNAL_DefaultTextureResourceState( From 8effeecb8d0f1ac98b633843103733a30a4b6cef Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 5 May 2026 21:48:20 +0200 Subject: [PATCH 224/407] cmake/sdlcpu: detect mips PlayStation Portable uses MIPS32 --- cmake/sdlcpu.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/sdlcpu.cmake b/cmake/sdlcpu.cmake index a27e7329c4..fa7d4aa820 100644 --- a/cmake/sdlcpu.cmake +++ b/cmake/sdlcpu.cmake @@ -1,6 +1,6 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS) - set(known_archs EMSCRIPTEN ARM32 ARM64 ARM64EC LOONGARCH64 POWERPC32 POWERPC64 RISCV32 RISCV64 X86 X64) + set(known_archs EMSCRIPTEN ARM32 ARM64 ARM64EC LOONGARCH64 MIPS32 MIPS64 POWERPC32 POWERPC64 RISCV32 RISCV64 X86 X64) if(APPLE AND CMAKE_OSX_ARCHITECTURES) foreach(known_arch IN LISTS known_archs) @@ -37,6 +37,8 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS) set(arch_check_ARM64EC "defined(_M_ARM64EC)") set(arch_check_EMSCRIPTEN "defined(__EMSCRIPTEN__)") set(arch_check_LOONGARCH64 "defined(__loongarch64)") + set(arch_check_MIPS32 "(defined(__mips__) && !defined(__mips64))") + set(arch_check_MIPS64 "(defined(__mips__) && defined(__mips64))") set(arch_check_POWERPC32 "(defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)") set(arch_check_POWERPC64 "defined(__PPC64__) || defined(__powerpc64__)") set(arch_check_RISCV32 "defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32") From 1ac0ae92247285714f50d07007bbb71d2c6d266d Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 5 May 2026 18:26:51 -0400 Subject: [PATCH 225/407] wayland: Unconditionally send an exposure event on window shown status Some compositors send the frame callback as part of the initial configuration sequence, so the window may already be past the "waiting for frame" state. Ensure that the exposure event is always sent. --- src/video/wayland/SDL_waylandwindow.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 5f8bd98400..82f0e55ea2 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -2351,9 +2351,7 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) data->showing_window = false; // Send an exposure event to signal that the client should draw. - if (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME) { - SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); - } + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); } static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup) From 37089cf0a8b82776cc69fc54e1204601244ea83b Mon Sep 17 00:00:00 2001 From: misscelan <45209859+misscelan@users.noreply.github.com> Date: Wed, 6 May 2026 16:39:23 +0200 Subject: [PATCH 226/407] Update for N-Gage - Audio is now double buffered (#15516) [N-Gage] Audio is now double buffered to avoid stuttering and glitches. Some audio platform specific variables were exposed through SDL_Hints. Same method was used to display FPS. N-gage functions to obtain the current buffer and screen pitch were added to the render. Adds hints: SDL_AUDIO_NGAGE_LATENCY SDL_AUDIO_NGAGE_SCHEDULER_TICK SDL_AUDIO_NGAGE_PROCESS_TICK SDL_AUDIO_NGAGE_PROCESS_PRIORITY SDL_RENDER_SHOW_FPS Adds functions to get current buffer address and pitch: void *NGAGE_GetBackbufferAddress(void); int NGAGE_GetBackbufferPitch(void); --------- Co-authored-by: Michael Fitzmayer Co-authored-by: Eddy Jansson --- src/audio/ngage/SDL_ngageaudio.c | 42 ++- src/audio/ngage/SDL_ngageaudio.cpp | 397 +++++++++++++----------- src/audio/ngage/SDL_ngageaudio.h | 20 +- src/audio/ngage/SDL_ngageaudio.hpp | 37 ++- src/render/ngage/SDL_render_ngage.cpp | 35 ++- src/render/ngage/SDL_render_ngage_c.h | 6 + src/render/ngage/SDL_render_ngage_c.hpp | 1 + 7 files changed, 323 insertions(+), 215 deletions(-) diff --git a/src/audio/ngage/SDL_ngageaudio.c b/src/audio/ngage/SDL_ngageaudio.c index 5b964d84f7..6e2ced16ac 100644 --- a/src/audio/ngage/SDL_ngageaudio.c +++ b/src/audio/ngage/SDL_ngageaudio.c @@ -42,18 +42,20 @@ static bool NGAGEAUDIO_OpenDevice(SDL_AudioDevice *device) } device->hidden = phdata; - phdata->buffer = SDL_calloc(1, device->buffer_size); - if (!phdata->buffer) { - SDL_OutOfMemory(); + phdata->buffer[0] = SDL_calloc(1, device->buffer_size); + phdata->buffer[1] = SDL_calloc(1, device->buffer_size); + if (!phdata->buffer[0] || !phdata->buffer[1]) + { + SDL_Log("Error: Failed to allocate audio buffers"); + SDL_free(phdata->buffer[0]); + SDL_free(phdata->buffer[1]); SDL_free(phdata); return false; } - devptr = device; - // Since the phone can change the sample rate during a phone call, - // we set the sample rate to 8KHz to be safe. Even though it - // might be possible to adjust the sample rate dynamically, it's - // not supported by the current implementation. + phdata->fill_index = 0; + + devptr = device; device->spec.format = SDL_AUDIO_S16LE; device->spec.channels = 1; @@ -64,6 +66,13 @@ static bool NGAGEAUDIO_OpenDevice(SDL_AudioDevice *device) return true; } +/********************************************* + +NGAGEAUDIO_GetDeviceBuf - + +Return the buffer that is currently being filled by SDL + +**********************************************/ static Uint8 *NGAGEAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden; @@ -71,19 +80,24 @@ static Uint8 *NGAGEAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) *buffer_size = 0; return 0; } - + *buffer_size = device->buffer_size; - return phdata->buffer; + + return phdata->buffer[phdata->fill_index]; } + + static void NGAGEAUDIO_CloseDevice(SDL_AudioDevice *device) { if (device->hidden) { - SDL_free(device->hidden->buffer); - SDL_free(device->hidden); - } + SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden; - return; + SDL_free(phdata->buffer[0]); + SDL_free(phdata->buffer[1]); + SDL_free(phdata); + device->hidden = NULL; + } } static bool NGAGEAUDIO_Init(SDL_AudioDriverImpl *impl) diff --git a/src/audio/ngage/SDL_ngageaudio.cpp b/src/audio/ngage/SDL_ngageaudio.cpp index aff7ff0b16..687b2c597c 100644 --- a/src/audio/ngage/SDL_ngageaudio.cpp +++ b/src/audio/ngage/SDL_ngageaudio.cpp @@ -98,89 +98,12 @@ void CAudio::Start() } } -// Feeds more processed data to the audio stream. -void CAudio::Feed() -{ - // If a WriteL is already in progress, or we aren't even playing; - // do nothing! - if ((iState != EStateWriting) && (iState != EStatePlaying)) { - return; - } - // Figure out the number of samples that really have been played - // through the output. - TTimeIntervalMicroSeconds pos = iStream->Position(); - - TInt played = 8 * (pos.Int64() / TInt64(1000)).GetTInt(); // 8kHz. - - played += iBaseSamplesPlayed; - - // Determine the difference between the number of samples written to - // CMdaAudioOutputStream and the number of samples it has played. - // The difference is the amount of data in the buffers. - if (played < 0) { - played = 0; - } - - TInt buffered = iSamplesWritten - played; - if (buffered < 0) { - buffered = 0; - } - - if (iState == EStateWriting) { - return; - } - - // The trick for low latency: Do not let the buffers fill up beyond the - // latency desired! We write as many samples as the difference between - // the latency target (in samples) and the amount of data buffered. - TInt samplesToWrite = iLatencySamples - buffered; - - // Do not write very small blocks. This should improve efficiency, since - // writes to the streaming API are likely to be expensive. - if (samplesToWrite < iMinWrite) { - // Not enough data to write, set up a timer to fire after a while. - // Try againwhen it expired. - if (iTimerActive) { - return; - } - iTimerActive = ETrue; - SetActive(); - iTimer.After(iStatus, (1000 * iLatency) / 8); - return; - } - - // Do not write more than the set number of samples at once. - int numSamples = samplesToWrite; - if (numSamples > iMaxWrite) { - numSamples = iMaxWrite; - } - - SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); - if (device) { - SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden; - - iBufDes.Set(phdata->buffer, 2 * numSamples, 2 * numSamples); - iStream->WriteL(iBufDes); - iState = EStateWriting; - - // Keep track of the number of samples written (for latency calculations). - iSamplesWritten += numSamples; - } else { - // Output device not ready yet. Let's go for another round. - if (iTimerActive) { - return; - } - iTimerActive = ETrue; - SetActive(); - iTimer.After(iStatus, (1000 * iLatency) / 8); - } -} void CAudio::RunL() { iTimerActive = EFalse; - Feed(); + } void CAudio::DoCancel() @@ -194,9 +117,21 @@ void CAudio::StartThread() TInt heapMinSize = 8192; // 8 KB initial heap size. TInt heapMaxSize = 1024 * 1024; // 1 MB maximum heap size. + TInt err = iProcess.Create(_L("ProcessThread"), ProcessThreadCB, KDefaultStackSize * 2, heapMinSize, heapMaxSize, this); - if (err == KErrNone) { - iProcess.SetPriority(EPriorityLess); + if (err == KErrNone) + { + TThreadPriority prio = EPriorityLess; + + const char *prioHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_PRIORITY); + if (prioHint) { + // Symbian priorities: 10 (MuchLess), 20 (Less), 30 (Normal), 40 (More) + prio = (TThreadPriority)SDL_atoi(prioHint); + RThread().SetPriority(prio); + } + + + iProcess.SetPriority(prio); iProcess.Resume(); } else { SDL_Log("Error: Failed to create audio processing thread: %d", err); @@ -212,138 +147,240 @@ void CAudio::StopThread() } } +/*************************************************** +* ProcessThreadCB - +* +* This thread calls the SDL mixer when the buffer is ready and self->iState == EStatePlaying (basically other than initial stated, when not writing) +* +* It only mixes, never calls WriteL +****************************************************/ + TInt CAudio::ProcessThreadCB(TAny *aPtr) { + CTrapCleanup *cleanup = CTrapCleanup::New(); + if (!cleanup) + return KErrNoMemory; + CAudio *self = static_cast(aPtr); SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); - while (self->iStreamStarted) { - if (device) { - SDL_PlaybackAudioThreadIterate(device); - } else { - device = NGAGE_GetAudioDeviceAddr(); - } - User::After(100000); // 100ms. + + TInt processTick = 40000; // Default 40ms + const char *tickHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_TICK); + if (tickHint) + { + processTick = SDL_atoi(tickHint) * 1000; } + + while (self->iStreamStarted) + { + if (self->iState == EStatePlaying && !self->iBufferReady) + { + /* Ask SDL to mix audio into buffer[fill_index]*/ + SDL_PlaybackAudioThreadIterate(device); + + /* Signal AudioThreadCB to write it*/ + self->iBufferReady = ETrue; + } + else + { + /*if we are not ready to obtain the mix data we sleep a bit this thread*/ + User::After(processTick); + } + } + + delete cleanup; return KErrNone; } -void CAudio::MaoscOpenComplete(TInt aError) -{ - if (aError == KErrNone) { - iStream->SetVolume(1); - iStreamStarted = ETrue; - StartThread(); - - } else { - SDL_Log("Error: Failed to open audio stream: %d", aError); - } -} - -void CAudio::MaoscBufferCopied(TInt aError, const TDesC8 & /*aBuffer*/) -{ - if (aError == KErrNone) { - iState = EStatePlaying; - Feed(); - } else if (aError == KErrAbort) { - // The stream has been stopped. - iState = EStateDone; - } else { - SDL_Log("Error: Failed to copy audio buffer: %d", aError); - } -} - -void CAudio::MaoscPlayComplete(TInt aError) -{ - // If we finish due to an underflow, we'll need to restart playback. - // Normally KErrUnderlow is raised at stream end, but in our case the API - // should never see the stream end -- we are continuously feeding it more - // data! Many underflow errors mean that the latency target is too low. - if (aError == KErrUnderflow) { - // The number of samples played gets reset to zero when we restart - // playback after underflow. - iBaseSamplesPlayed = iSamplesWritten; - - iStream->Stop(); - Cancel(); - - iStream->SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate8000Hz, TMdaAudioDataSettings::EChannelsMono); - - iState = EStatePlaying; - Feed(); - return; - - } else if (aError != KErrNone) { - // Handle error. - } - - // We shouldn't get here. - SDL_Log("%s: %d", SDL_FUNCTION, aError); -} - static TBool gAudioRunning; - -TBool AudioIsReady() -{ - return gAudioRunning; -} +/*************************************************** +* AudioThreadCB - +* +* This thread owns the scheduler and calls WriteL, wich queues the assigned sound buffer to be played +****************************************************/ TInt AudioThreadCB(TAny *aParams) { CTrapCleanup *cleanup = CTrapCleanup::New(); - if (!cleanup) { - return KErrNoMemory; - } - CActiveScheduler *scheduler = new CActiveScheduler(); - if (!scheduler) { - delete cleanup; - return KErrNoMemory; - } - CActiveScheduler::Install(scheduler); + + TRAPD(err, { + TInt latency = *(TInt *)aParams; + CAudio *audio = CAudio::NewL(latency); + CleanupStack::PushL(audio); - TRAPD(err, - { - TInt latency = *(TInt *)aParams; - CAudio *audio = CAudio::NewL(latency); - CleanupStack::PushL(audio); + audio->iBufferReady = EFalse; - gAudioRunning = ETrue; - audio->Start(); - TBool once = EFalse; + gAudioRunning = ETrue; + audio->Start(); + - while (gAudioRunning) { - // Allow active scheduler to process any events. - TInt error; - CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); + TInt processTick = 5000; // Default 5ms + const char *tickHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_TICK); + if (tickHint) { + processTick = SDL_atoi(tickHint) * 1000; + } - if (!once) { - SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); - if (device) { - // Stream ready; start feeding audio data. - // After feeding it once, the callbacks will take over. - audio->iState = CAudio::EStatePlaying; - audio->Feed(); - once = ETrue; - } - } - User::After(100000); // 100ms. - } + while (gAudioRunning) + { + TInt error; + CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); + + /*there is some mix data sound ready*/ + if (audio->iBufferReady) + { + audio->iBufferReady = EFalse; - CleanupStack::PopAndDestroy(audio); - }); + SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); + + if (device && device->hidden) + { + SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden; + audio->iState = EStateWriting; + /*sends the chuck mixed to the queue*/ + audio->iBufDes.Set(phdata->buffer[phdata->fill_index], device->buffer_size, device->buffer_size); + TRAPD(werr, audio->iStream->WriteL(audio->iBufDes)); + + if (werr != KErrNone) + { + /*asks ProcessThreadCB to bring another mix chunk*/ + audio->iState = EStatePlaying; + } + else + { + /*swap buffers so while this buffer is being played we can get the mix of the next one if we can*/ + phdata->fill_index = 1 - phdata->fill_index; + } + } + } + + /*sleep a bit this thread not to hog the CPU*/ + User::After(processTick); + } + + CleanupStack::PopAndDestroy(audio); + }); delete scheduler; delete cleanup; return err; } +/*************************************************** +* MaoscOpenComplete - +* +* Opens the audiostream +* +* *******************************************************/ + +void CAudio::MaoscOpenComplete(TInt aError) +{ + if (aError == KErrNone) + { + /*setting the volume to max, users can change the volume later of their channels individually in code*/ + iStream->SetVolume(iStream->MaxVolume()); + iStreamStarted = ETrue; + + /* Wait until SDL has set devptr and hidden data*/ + SDL_AudioDevice *device = NULL; + while (!device || !device->hidden) { + User::After(10000); // 10ms poll + device = NGAGE_GetAudioDeviceAddr(); + } + + /* Now start the ProcessThreadCB thread*/ + StartThread(); + + /* Kickstart: device is guaranteed valid now*/ + this->iState = EStatePlaying; + + + } + else + { + SDL_Log("Error: Failed to open audio stream: %d", aError); + } +} + +/*************************************************** + * MaoscOpenComplete - + * + * This signals the mixed data has been finally copied to the designated audio buffer + * + * *******************************************************/ + +void CAudio::MaoscBufferCopied(TInt aError, const TDesC8 & /*aBuffer*/) +{ + if (aError == KErrNone) + { + iState = EStatePlaying; + } + else if (aError == KErrAbort) + { + /* The stream has been stopped.*/ + iState = EStateDone; + } + else + { + SDL_Log("Error: Failed to copy audio buffer: %d", aError); + } +} + +/*************************************************** + * MaoscPlayComplete - + * + * The result after playing the mixed chunk + * + * *******************************************************/ + +void CAudio::MaoscPlayComplete(TInt aError) +{ + + /* If we finish due to an underflow, we'll need to restart playback. + Normally KErrUnderlow is raised at stream end, but in our case the API + should never see the stream end -- we are continuously feeding it more + data! Many underflow errors mean that the latency target is too low.*/ + if (aError == KErrUnderflow) + { + /* Restart the stream hardware */ + iStream->Stop(); + TInt ignoredError; + TRAP(ignoredError, iStream->SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate8000Hz, TMdaAudioDataSettings::EChannelsMono)); + + /* This wakes up ProcessThreadCB so it can call SDL_PlaybackAudioThreadIterate*/ + iState = EStatePlaying; + + return; + } else if (aError != KErrNone) { + + } + + /* We shouldn't get here.*/ + SDL_Log("%s: %d", SDL_FUNCTION, aError); +} + + + +TBool AudioIsReady() +{ + return gAudioRunning; +} + + + RThread audioThread; void InitAudio(TInt *aLatency) { + // Check if the user has provided a custom latency value via a hint + const char *hint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_LATENCY); + if (hint) { + *aLatency = (TInt)SDL_atoi(hint); + } + _LIT(KAudioThreadName, "AudioThread"); TInt err = audioThread.Create(KAudioThreadName, AudioThreadCB, KDefaultStackSize, 0, aLatency); diff --git a/src/audio/ngage/SDL_ngageaudio.h b/src/audio/ngage/SDL_ngageaudio.h index ee3afedb73..d7b4a952ba 100644 --- a/src/audio/ngage/SDL_ngageaudio.h +++ b/src/audio/ngage/SDL_ngageaudio.h @@ -23,9 +23,27 @@ #ifndef SDL_ngageaudio_h #define SDL_ngageaudio_h +#ifndef SDL_HINT_AUDIO_NGAGE_LATENCY +#define SDL_HINT_AUDIO_NGAGE_LATENCY "SDL_AUDIO_NGAGE_LATENCY" +#endif + +#ifndef SDL_HINT_AUDIO_NGAGE_SCHEDULER_TICK +#define SDL_HINT_AUDIO_NGAGE_SCHEDULER_TICK "SDL_AUDIO_NGAGE_SCHEDULER_TICK" +#endif + +#ifndef SDL_HINT_AUDIO_NGAGE_PROCESS_TICK +#define SDL_HINT_AUDIO_NGAGE_PROCESS_TICK "SDL_AUDIO_NGAGE_PROCESS_TICK" +#endif + +#ifndef SDL_HINT_AUDIO_NGAGE_PROCESS_PRIORITY +#define SDL_HINT_AUDIO_NGAGE_PROCESS_PRIORITY "SDL_AUDIO_NGAGE_PROCESS_PRIORITY" +#endif typedef struct SDL_PrivateAudioData { - Uint8 *buffer; + Uint8 *buffer[2]; + int fill_index; /* Which buffer SDL is currently filling */ + int play_index; /* Which buffer the hardware is currently using*/ + int buffer_size; } SDL_PrivateAudioData; diff --git a/src/audio/ngage/SDL_ngageaudio.hpp b/src/audio/ngage/SDL_ngageaudio.hpp index 68e714a83f..4988b5031a 100644 --- a/src/audio/ngage/SDL_ngageaudio.hpp +++ b/src/audio/ngage/SDL_ngageaudio.hpp @@ -42,6 +42,16 @@ TBool AudioIsReady(); void InitAudio(TInt *aLatency); void DeinitAudio(); +enum TAudioState +{ + EStateNone = 0, + EStateOpening, + EStatePlaying, + EStateWriting, + EStateDone +}; + + class CAudio : public CActive, public MMdaAudioOutputStreamCallback { public: @@ -50,49 +60,42 @@ class CAudio : public CActive, public MMdaAudioOutputStreamCallback void ConstructL(TInt aLatency); void Start(); - void Feed(); + void RunL(); void DoCancel(); static TInt ProcessThreadCB(TAny * /*aPtr*/); - // From MMdaAudioOutputStreamCallback void MaoscOpenComplete(TInt aError); void MaoscBufferCopied(TInt aError, const TDesC8 &aBuffer); void MaoscPlayComplete(TInt aError); - enum - { - EStateNone = 0, - EStateOpening, - EStatePlaying, - EStateWriting, - EStateDone - } iState; + TAudioState iState; + CMdaAudioOutputStream *iStream; /*CMdaAudioOutputStream handler*/ + TPtr8 iBufDes; /* Descriptor for the buffer.*/ + TBool iStreamStarted; /* have we initialized the audio stream?*/ + RThread iProcess; /* thread handler */ + TBool iBufferReady; /* Signal AudioThreadCB the buffer is ready*/ private: CAudio(); void StartThread(); void StopThread(); - CMdaAudioOutputStream *iStream; + TMdaAudioDataSettings iStreamSettings; - TBool iStreamStarted; - - TPtr8 iBufDes; // Descriptor for the buffer. + TInt iLatency; // Latency target in ms TInt iLatencySamples; // Latency target in samples. TInt iMinWrite; // Min number of samples to write per turn. TInt iMaxWrite; // Max number of samples to write per turn. - TInt iBaseSamplesPlayed; // amples played before last restart. - TInt iSamplesWritten; // Number of samples written so far. + RTimer iTimer; TBool iTimerCreated; TBool iTimerActive; - RThread iProcess; }; #endif // SDL_ngageaudio_hpp \ No newline at end of file diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index cd312406af..1207df7ed0 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -149,6 +149,23 @@ void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target) } } +static void SDLCALL NGAGE_ShowFPSChanged(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + CRenderer *renderer = (CRenderer *)userdata; + renderer->SetShowFPS(SDL_GetStringBoolean(newValue, false)); +} + + +void *NGAGE_GetBackbufferAddress(void) +{ + return gRenderer->GetCurrentBitmap()->DataAddress(); +} + +int NGAGE_GetBackbufferPitch(void) +{ + return CFbsBitmap::ScanLineLength(NGAGE_SCREEN_WIDTH, EColor4K) / 2; +} + #ifdef __cplusplus } #endif @@ -166,6 +183,8 @@ CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSessio CRenderer::~CRenderer() { + SDL_RemoveHintCallback(SDL_HINT_RENDER_NGAGE_SHOW_FPS, NGAGE_ShowFPSChanged, this); + delete iRenderer; iRenderer = 0; @@ -266,6 +285,8 @@ void CRenderer::ConstructL() } iDirectScreen->ScreenDevice()->SetAutoUpdate(ETrue); } + + SDL_AddHintCallback(SDL_HINT_RENDER_NGAGE_SHOW_FPS, NGAGE_ShowFPSChanged, this); } void CRenderer::Restart(RDirectScreenAccess::TTerminationReasons aReason) @@ -336,6 +357,8 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec return false; } + + NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; if (!phdata || !phdata->bitmap) { return false; @@ -346,7 +369,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec int sw = srcrect->w; int sh = srcrect->h; - + // Fast path: render target texture with no color mod. // BitBlt directly from its bitmap — DataAddress() is unreliable // for bitmaps that have been drawn into via a CFbsBitGc. @@ -359,7 +382,8 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec SDL_GetTextureBlendMode(texture, &blend); bool no_color_key = (blend != SDL_BLENDMODE_BLEND); - if (phdata->gc && no_color_mod && no_scale && no_color_key) { + if (phdata->gc && no_color_mod && no_scale && no_color_key) + { CFbsBitGc *gc = GetCurrentGc(); if (gc) { TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(sw, sh)); @@ -369,6 +393,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec return true; } + // Fast path: color-key with no color mod and no scale. // Blit directly from the source bitmap into the destination, skipping transparent pixels. if (no_color_mod && no_scale && !no_color_key && phdata->has_color_key) { @@ -414,6 +439,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec return false; } } + TSize scratch_size = iScratchBitmap->SizeInPixels(); if (scratch_size.iWidth < sw || scratch_size.iHeight < sh) { iScratchBitmap->Reset(); @@ -438,6 +464,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec void *source = iPixelBufferA; void *dest = iPixelBufferB; + if (!no_color_mod) { ApplyColorMod(dest, source, src_pitch, sw, sh, texture->color); void *tmp = source; @@ -934,13 +961,15 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent) timestamp = SDL_GetPerformanceCounter(); SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), true); + /* + commented out so it works with hints if (aWsEvent.Key()->iScanCode == EStdKeyHash) { if (iShowFPS) { iShowFPS = EFalse; } else { iShowFPS = ETrue; } - } + }*/ break; case EEventKeyUp: /* Key events */ diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index 76a3619989..20e816caab 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -25,6 +25,10 @@ #define NGAGE_SCREEN_WIDTH 176 #define NGAGE_SCREEN_HEIGHT 208 +#ifndef SDL_HINT_RENDER_NGAGE_SHOW_FPS +#define SDL_HINT_RENDER_NGAGE_SHOW_FPS "SDL_RENDER_NGAGE_SHOW_FPS" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -108,6 +112,8 @@ void NGAGE_SetDrawColor(const Uint32 color); void NGAGE_PumpEventsInternal(void); void NGAGE_SuspendScreenSaverInternal(bool suspend); void NGAGE_SetRenderTargetInternal(NGAGE_TextureData *target); +void *NGAGE_GetBackbufferAddress(void); +int NGAGE_GetBackbufferPitch(void); #ifdef __cplusplus } diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 97e4ff272a..201dafff38 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -46,6 +46,7 @@ class CRenderer : public MDirectScreenAccess void SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight); void UpdateFPS(); void SuspendScreenSaver(TBool aSuspend); + void SetShowFPS(TBool aShow) { iShowFPS = aShow; } // Render target management. void SetRenderTarget(NGAGE_TextureData *aTarget); From b9da2b8d97b2b82e567b402589b6ce6bab4b5e49 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Tue, 5 May 2026 18:59:28 +0200 Subject: [PATCH 227/407] [N-Gage] Add Gouraud-shaded triangle rasteriser Implement DrawGeometry using a software scanline rasteriser that fills triangles directly into the EColor4K framebuffer. Vertices are sorted by Y, split into upper/lower halves and filled with per-scanline edge interpolation. Colour is stepped incrementally across each span (one division per span edge rather than per pixel) to avoid the cost of emulated integer division on the ARM920T. --- src/render/ngage/SDL_render_ngage.c | 40 ++++++ src/render/ngage/SDL_render_ngage.cpp | 176 ++++++++++++++++++++++++ src/render/ngage/SDL_render_ngage_c.h | 1 + src/render/ngage/SDL_render_ngage_c.hpp | 1 + 4 files changed, 218 insertions(+) diff --git a/src/render/ngage/SDL_render_ngage.c b/src/render/ngage/SDL_render_ngage.c index bee541d280..175550d251 100644 --- a/src/render/ngage/SDL_render_ngage.c +++ b/src/render/ngage/SDL_render_ngage.c @@ -306,6 +306,35 @@ static bool NGAGE_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SD static bool NGAGE_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices, float scale_x, float scale_y) { + int count = indices ? num_indices : num_vertices; + NGAGE_Vertex *verts = (NGAGE_Vertex *)SDL_AllocateRenderVertices(renderer, count * sizeof(NGAGE_Vertex), 0, &cmd->data.draw.first); + if (!verts) { + return false; + } + cmd->data.draw.count = count; + + for (int i = 0; i < count; i++) { + int src_idx = i; + if (indices) { + if (size_indices == 4) { + src_idx = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + src_idx = ((const Uint16 *)indices)[i]; + } else { + src_idx = ((const Uint8 *)indices)[i]; + } + } + const float *pos = (const float *)(((const Uint8 *)xy) + src_idx * xy_stride); + const SDL_FColor *c = (const SDL_FColor *)(((const Uint8 *)color) + src_idx * color_stride); + + verts[i].x = (int)(pos[0] * scale_x); + verts[i].y = (int)(pos[1] * scale_y); + verts[i].color.r = (Uint8)(c->r * 255.0f); + verts[i].color.g = (Uint8)(c->g * 255.0f); + verts[i].color.b = (Uint8)(c->b * 255.0f); + verts[i].color.a = (Uint8)(c->a * 255.0f); + } + return true; } @@ -438,6 +467,17 @@ static bool NGAGE_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd case SDL_RENDERCMD_GEOMETRY: { + NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first); + const int count = cmd->data.draw.count; + + if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { + for (int i = 0; i < count; i++) { + verts[i].x += phdata->viewport->x; + verts[i].y += phdata->viewport->y; + } + } + + NGAGE_DrawGeometry(verts, count); break; } } diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 1207df7ed0..5e8760b929 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -110,6 +110,11 @@ void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count) gRenderer->DrawPoints(verts, count); } +void NGAGE_DrawGeometry(NGAGE_Vertex *verts, const int count) +{ + gRenderer->DrawGeometry(verts, count); +} + void NGAGE_FillRects(NGAGE_Vertex *verts, const int count) { gRenderer->FillRects(verts, count); @@ -728,6 +733,177 @@ void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount) } } +// Gouraud-shaded triangle scanline fill directly into an EColor4K (XRGB4444) framebuffer. +// Colors are interpolated per-scanline endpoint and per-pixel. +static void FillTriangle(TUint16 *aPixels, TInt aStride, + TInt aBmpW, TInt aBmpH, + TInt aX0, TInt aY0, TInt aR0, TInt aG0, TInt aB0, + TInt aX1, TInt aY1, TInt aR1, TInt aG1, TInt aB1, + TInt aX2, TInt aY2, TInt aR2, TInt aG2, TInt aB2) +{ + // Sort vertices by Y ascending (bubble sort on 3 elements). + // Swap positions and colors together. +#define SWAP3(ax, ay, ar, ag, ab, bx, by, br, bg, bb) \ + do { \ + TInt _t; \ + _t = ax; \ + ax = bx; \ + bx = _t; \ + _t = ay; \ + ay = by; \ + by = _t; \ + _t = ar; \ + ar = br; \ + br = _t; \ + _t = ag; \ + ag = bg; \ + bg = _t; \ + _t = ab; \ + ab = bb; \ + bb = _t; \ + } while (0) + + if (aY0 > aY1) { + SWAP3(aX0, aY0, aR0, aG0, aB0, aX1, aY1, aR1, aG1, aB1); + } + if (aY1 > aY2) { + SWAP3(aX1, aY1, aR1, aG1, aB1, aX2, aY2, aR2, aG2, aB2); + } + if (aY0 > aY1) { + SWAP3(aX0, aY0, aR0, aG0, aB0, aX1, aY1, aR1, aG1, aB1); + } +#undef SWAP3 + + TInt totalHeight = aY2 - aY0; + if (totalHeight == 0) { + return; + } + + // Walk upper half [y0..y1] and lower half [y1..y2]. + for (TInt part = 0; part < 2; ++part) { + TInt segHeight = (part == 0) ? (aY1 - aY0) : (aY2 - aY1); + if (segHeight == 0) { + continue; + } + TInt yStart = (part == 0) ? aY0 : aY1; + TInt yEnd = (part == 0) ? aY1 : aY2; + + for (TInt y = yStart; y <= yEnd; ++y) { + if (y < 0 || y >= aBmpH) { + continue; + } + + // 16.16 interpolation factors for long edge (v0->v2) and short edge. + TInt tLong = ((y - aY0) << 16) / totalHeight; + TInt tShort = ((y - yStart) << 16) / segHeight; + + // Interpolate X along both edges. + TInt xLong = aX0 + (((aX2 - aX0) * tLong) >> 16); + TInt xShort = (part == 0) + ? aX0 + (((aX1 - aX0) * tShort) >> 16) + : aX1 + (((aX2 - aX1) * tShort) >> 16); + + // Interpolate color along both edges (values 0-255). + TInt rLong = aR0 + (((aR2 - aR0) * tLong) >> 16); + TInt gLong = aG0 + (((aG2 - aG0) * tLong) >> 16); + TInt bLong = aB0 + (((aB2 - aB0) * tLong) >> 16); + TInt rShort, gShort, bShort; + if (part == 0) { + rShort = aR0 + (((aR1 - aR0) * tShort) >> 16); + gShort = aG0 + (((aG1 - aG0) * tShort) >> 16); + bShort = aB0 + (((aB1 - aB0) * tShort) >> 16); + } else { + rShort = aR1 + (((aR2 - aR1) * tShort) >> 16); + gShort = aG1 + (((aG2 - aG1) * tShort) >> 16); + bShort = aB1 + (((aB2 - aB1) * tShort) >> 16); + } + + // Determine left/right endpoints and their colors. + TInt xLeft, xRight; + TInt rLeft, gLeft, bLeft; + TInt rRight, gRight, bRight; + if (xLong < xShort) { + xLeft = xLong; + xRight = xShort; + rLeft = rLong; + gLeft = gLong; + bLeft = bLong; + rRight = rShort; + gRight = gShort; + bRight = bShort; + } else { + xLeft = xShort; + xRight = xLong; + rLeft = rShort; + gLeft = gShort; + bLeft = bShort; + rRight = rLong; + gRight = gLong; + bRight = bLong; + } + + // Clamp X to bitmap width. + if (xLeft < 0) { + xLeft = 0; + } + if (xRight >= aBmpW) { + xRight = aBmpW - 1; + } + + TInt spanWidth = xRight - xLeft; + TUint16 *row = aPixels + y * aStride; + + // Compute per-pixel color deltas once per span (one division each) + // then step incrementally; avoids a division per pixel. + if (spanWidth > 0) { + TInt dr = ((rRight - rLeft) << 16) / spanWidth; + TInt dg = ((gRight - gLeft) << 16) / spanWidth; + TInt db = ((bRight - bLeft) << 16) / spanWidth; + TInt r = rLeft << 16; + TInt g = gLeft << 16; + TInt b = bLeft << 16; + for (TInt x = xLeft; x <= xRight; ++x) { + // Pack to XRGB4444. + row[x] = (TUint16)((((r >> 16) >> 4) << 8) | (((g >> 16) >> 4) << 4) | ((b >> 16) >> 4)); + r += dr; + g += dg; + b += db; + } + } else { + row[xLeft] = (TUint16)(((rLeft >> 4) << 8) | ((gLeft >> 4) << 4) | (bLeft >> 4)); + } + } + } +} + +void CRenderer::DrawGeometry(NGAGE_Vertex *aVerts, const TInt aCount) +{ + if (aCount < 3) { + return; + } + + CFbsBitmap *bmp = GetCurrentBitmap(); + if (bmp) { + TUint16 *pixels = reinterpret_cast(bmp->DataAddress()); + if (pixels) { + TSize bmpSize = bmp->SizeInPixels(); + TInt stride = CFbsBitmap::ScanLineLength(bmpSize.iWidth, EColor4K) / 2; + + for (TInt i = 0; i + 2 < aCount; i += 3) { + FillTriangle(pixels, stride, + bmpSize.iWidth, bmpSize.iHeight, + aVerts[i].x, aVerts[i].y, + aVerts[i].color.r, aVerts[i].color.g, aVerts[i].color.b, + aVerts[i + 1].x, aVerts[i + 1].y, + aVerts[i + 1].color.r, aVerts[i + 1].color.g, aVerts[i + 1].color.b, + aVerts[i + 2].x, aVerts[i + 2].y, + aVerts[i + 2].color.r, aVerts[i + 2].color.g, aVerts[i + 2].color.b); + } + return; + } + } +} + void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount) { CFbsBitGc *gc = GetCurrentGc(); diff --git a/src/render/ngage/SDL_render_ngage_c.h b/src/render/ngage/SDL_render_ngage_c.h index 20e816caab..b98b465d85 100644 --- a/src/render/ngage/SDL_render_ngage_c.h +++ b/src/render/ngage/SDL_render_ngage_c.h @@ -103,6 +103,7 @@ bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int void NGAGE_DestroyTextureData(NGAGE_TextureData *data); void *NGAGE_GetBitmapDataAddress(NGAGE_TextureData *data); int NGAGE_GetBitmapScanLineLength(NGAGE_TextureData *data); +void NGAGE_DrawGeometry(NGAGE_Vertex *verts, const int count); void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count); void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count); void NGAGE_FillRects(NGAGE_Vertex *verts, const int count); diff --git a/src/render/ngage/SDL_render_ngage_c.hpp b/src/render/ngage/SDL_render_ngage_c.hpp index 201dafff38..b03220045e 100644 --- a/src/render/ngage/SDL_render_ngage_c.hpp +++ b/src/render/ngage/SDL_render_ngage_c.hpp @@ -40,6 +40,7 @@ class CRenderer : public MDirectScreenAccess bool CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight, const TInt aAccess); void DrawLines(NGAGE_Vertex *aVerts, const TInt aCount); void DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount); + void DrawGeometry(NGAGE_Vertex *aVerts, const TInt aCount); void FillRects(NGAGE_Vertex *aVerts, const TInt aCount); void Flip(); void SetDrawColor(TUint32 iColor); From 77cd3872c42d71c59c85ccaa08994cb5e0c9eecc Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 6 May 2026 17:27:12 +0200 Subject: [PATCH 228/407] [N-Gage] Add missing include, clean-up. --- src/render/ngage/SDL_render_ngage.cpp | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/render/ngage/SDL_render_ngage.cpp b/src/render/ngage/SDL_render_ngage.cpp index 5e8760b929..d9cefc1a82 100644 --- a/src/render/ngage/SDL_render_ngage.cpp +++ b/src/render/ngage/SDL_render_ngage.cpp @@ -22,6 +22,7 @@ extern "C" { #endif +#include "../../SDL_hints_c.h" #include "../../events/SDL_keyboard_c.h" #include "../SDL_sysrender.h" #include "SDL_internal.h" @@ -160,7 +161,6 @@ static void SDLCALL NGAGE_ShowFPSChanged(void *userdata, const char *name, const renderer->SetShowFPS(SDL_GetStringBoolean(newValue, false)); } - void *NGAGE_GetBackbufferAddress(void) { return gRenderer->GetCurrentBitmap()->DataAddress(); @@ -362,8 +362,6 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec return false; } - - NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; if (!phdata || !phdata->bitmap) { return false; @@ -374,7 +372,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec int sw = srcrect->w; int sh = srcrect->h; - + // Fast path: render target texture with no color mod. // BitBlt directly from its bitmap — DataAddress() is unreliable // for bitmaps that have been drawn into via a CFbsBitGc. @@ -387,8 +385,7 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec SDL_GetTextureBlendMode(texture, &blend); bool no_color_key = (blend != SDL_BLENDMODE_BLEND); - if (phdata->gc && no_color_mod && no_scale && no_color_key) - { + if (phdata->gc && no_color_mod && no_scale && no_color_key) { CFbsBitGc *gc = GetCurrentGc(); if (gc) { TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(sw, sh)); @@ -398,7 +395,6 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec return true; } - // Fast path: color-key with no color mod and no scale. // Blit directly from the source bitmap into the destination, skipping transparent pixels. if (no_color_mod && no_scale && !no_color_key && phdata->has_color_key) { @@ -469,7 +465,6 @@ bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rec void *source = iPixelBufferA; void *dest = iPixelBufferB; - if (!no_color_mod) { ApplyColorMod(dest, source, src_pitch, sw, sh, texture->color); void *tmp = source; @@ -1137,16 +1132,6 @@ void CRenderer::HandleEvent(const TWsEvent &aWsEvent) timestamp = SDL_GetPerformanceCounter(); SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), true); - /* - commented out so it works with hints - if (aWsEvent.Key()->iScanCode == EStdKeyHash) { - if (iShowFPS) { - iShowFPS = EFalse; - } else { - iShowFPS = ETrue; - } - }*/ - break; case EEventKeyUp: /* Key events */ timestamp = SDL_GetPerformanceCounter(); From 702f9d94cd878751add81bf7035bc3144caa950d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 6 May 2026 09:12:03 -0700 Subject: [PATCH 229/407] Use SDL_HasWindows() --- src/video/uikit/SDL_uikitevents.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index fef6683dbf..4f9de24af2 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -47,9 +47,7 @@ static BOOL UIKit_EventPumpEnabled = YES; bool wants_observation = (UIKit_EventPumpEnabled || SDL_HasMainCallbacks()); if (!wants_observation) { // Make sure no windows have active animation callbacks - int num_windows = 0; - SDL_free(SDL_GetWindows(&num_windows)); - if (num_windows > 0) { + if (SDL_HasWindows()) { wants_observation = true; } } From e3393e630417c9d74c9eebc3bfab0f6bd9e345b7 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 6 May 2026 11:30:15 -0400 Subject: [PATCH 230/407] wayland: Queue the surface frame callback after the initial commit Some compositors may dispatch this too early, during the initial empty commit, when subsurfaces are attached to a toplevel window, but a buffer has yet to be committed to the parent surface. Don't set the frame callback until the initial empty commit is done, so it will be called when the actual parent surface frame is committed. --- src/video/wayland/SDL_waylandwindow.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 82f0e55ea2..075bae63e1 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -2299,7 +2299,7 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) wl_surface_commit(data->surface); } - // Make sure the window can't be resized to 0 or it can be spuriously closed by the window manager. + // Make sure the window can't be resized to 0, or it can be spuriously closed by the window manager. data->system_limits.min_width = SDL_max(data->system_limits.min_width, 1); data->system_limits.min_height = SDL_max(data->system_limits.min_height, 1); @@ -2342,6 +2342,13 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) } } + // No frame callback on an external surface, as it may already have one attached. + if (!(window->flags & SDL_WINDOW_EXTERNAL)) { + // Fire a callback when the compositor wants a new frame. + data->surface_frame_callback = wl_surface_frame(data->surface); + wl_callback_add_listener(data->surface_frame_callback, &surface_frame_listener, data); + } + data->show_hide_sync_required = true; struct wl_callback *cb = wl_display_sync(_this->internal->display); wl_callback_add_listener(cb, &show_hide_sync_listener, (void *)((uintptr_t)window->id)); @@ -2408,6 +2415,11 @@ void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) wind->shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_HIDDEN; + if (wind->surface_frame_callback) { + wl_callback_destroy(wind->surface_frame_callback); + wind->surface_frame_callback = NULL; + } + if (wind->server_decoration) { zxdg_toplevel_decoration_v1_destroy(wind->server_decoration); wind->server_decoration = NULL; @@ -2986,13 +2998,6 @@ bool Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper wl_callback_add_listener(data->gles_swap_frame_callback, &gles_swap_frame_listener, data); } - // No frame callback on external surfaces as it may already have one attached. - if (!external_surface) { - // Fire a callback when the compositor wants a new frame to set the surface damage region. - data->surface_frame_callback = wl_surface_frame(data->surface); - wl_callback_add_listener(data->surface_frame_callback, &surface_frame_listener, data); - } - if (window->flags & SDL_WINDOW_TRANSPARENT) { if (_this->gl_config.alpha_size == 0) { _this->gl_config.alpha_size = 8; @@ -3584,10 +3589,6 @@ void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) WAYLAND_wl_event_queue_destroy(wind->gles_swap_frame_event_queue); } - if (wind->surface_frame_callback) { - wl_callback_destroy(wind->surface_frame_callback); - } - if (!(window->flags & SDL_WINDOW_EXTERNAL)) { wl_surface_destroy(wind->surface); } else { From 51925aa92e812ec6fc3afd8c39e6c3dc4112eda9 Mon Sep 17 00:00:00 2001 From: Michael Fitzmayer Date: Wed, 6 May 2026 18:31:37 +0200 Subject: [PATCH 231/407] [N-Gage] Resolve hang on repeated app launch. CAudio::~CAudio() waited on MaoscBufferCopied(KErrAbort) to set EStateDone, but that callback can never fire once the active scheduler loop has exited, deadlocking every close. - StopThread() before iStream->Stop() in ~CAudio() - Force iState = EStateDone instead of waiting on a dead callback - Add 5s timeout to AudioIsReady() poll in E32Main() - Fix CleanupStack LIFO pop order (mainApp before gRenderer) --- src/audio/ngage/SDL_ngageaudio.cpp | 119 ++++++++++------------------ src/main/ngage/SDL_sysmain_main.cpp | 13 ++- 2 files changed, 54 insertions(+), 78 deletions(-) diff --git a/src/audio/ngage/SDL_ngageaudio.cpp b/src/audio/ngage/SDL_ngageaudio.cpp index 687b2c597c..246ea2dd42 100644 --- a/src/audio/ngage/SDL_ngageaudio.cpp +++ b/src/audio/ngage/SDL_ngageaudio.cpp @@ -75,13 +75,17 @@ void CAudio::ConstructL(TInt aLatency) CAudio::~CAudio() { if (iStream) { + // Stop the processing thread before stopping the stream. + StopThread(); + iStream->Stop(); - while (iState != EStateDone) { - User::After(100000); // 100ms. - } + // MaoscBufferCopied(KErrAbort) can't fire here because the active + // scheduler is no longer pumping; force the state to avoid deadlock. + iState = EStateDone; delete iStream; + iStream = NULL; } } @@ -98,12 +102,9 @@ void CAudio::Start() } } - - void CAudio::RunL() { iTimerActive = EFalse; - } void CAudio::DoCancel() @@ -117,10 +118,8 @@ void CAudio::StartThread() TInt heapMinSize = 8192; // 8 KB initial heap size. TInt heapMaxSize = 1024 * 1024; // 1 MB maximum heap size. - TInt err = iProcess.Create(_L("ProcessThread"), ProcessThreadCB, KDefaultStackSize * 2, heapMinSize, heapMaxSize, this); - if (err == KErrNone) - { + if (err == KErrNone) { TThreadPriority prio = EPriorityLess; const char *prioHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_PRIORITY); @@ -130,7 +129,6 @@ void CAudio::StartThread() RThread().SetPriority(prio); } - iProcess.SetPriority(prio); iProcess.Resume(); } else { @@ -148,42 +146,36 @@ void CAudio::StopThread() } /*************************************************** -* ProcessThreadCB - -* -* This thread calls the SDL mixer when the buffer is ready and self->iState == EStatePlaying (basically other than initial stated, when not writing) -* -* It only mixes, never calls WriteL -****************************************************/ + * ProcessThreadCB - + * + * This thread calls the SDL mixer when the buffer is ready and self->iState == EStatePlaying (basically other than initial stated, when not writing) + * + * It only mixes, never calls WriteL + ****************************************************/ TInt CAudio::ProcessThreadCB(TAny *aPtr) { CTrapCleanup *cleanup = CTrapCleanup::New(); if (!cleanup) return KErrNoMemory; - + CAudio *self = static_cast(aPtr); SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); - TInt processTick = 40000; // Default 40ms const char *tickHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_TICK); - if (tickHint) - { + if (tickHint) { processTick = SDL_atoi(tickHint) * 1000; } - while (self->iStreamStarted) - { - if (self->iState == EStatePlaying && !self->iBufferReady) - { - /* Ask SDL to mix audio into buffer[fill_index]*/ + while (self->iStreamStarted) { + if (self->iState == EStatePlaying && !self->iBufferReady) { + /* Ask SDL to mix audio into buffer[fill_index]*/ SDL_PlaybackAudioThreadIterate(device); - /* Signal AudioThreadCB to write it*/ + /* Signal AudioThreadCB to write it*/ self->iBufferReady = ETrue; - } - else - { + } else { /*if we are not ready to obtain the mix data we sleep a bit this thread*/ User::After(processTick); } @@ -195,17 +187,17 @@ TInt CAudio::ProcessThreadCB(TAny *aPtr) static TBool gAudioRunning; /*************************************************** -* AudioThreadCB - -* -* This thread owns the scheduler and calls WriteL, wich queues the assigned sound buffer to be played -****************************************************/ + * AudioThreadCB - + * + * This thread owns the scheduler and calls WriteL, wich queues the assigned sound buffer to be played + ****************************************************/ TInt AudioThreadCB(TAny *aParams) { CTrapCleanup *cleanup = CTrapCleanup::New(); CActiveScheduler *scheduler = new CActiveScheduler(); CActiveScheduler::Install(scheduler); - + TRAPD(err, { TInt latency = *(TInt *)aParams; CAudio *audio = CAudio::NewL(latency); @@ -215,7 +207,6 @@ TInt AudioThreadCB(TAny *aParams) gAudioRunning = ETrue; audio->Start(); - TInt processTick = 5000; // Default 5ms const char *tickHint = SDL_GetHint(SDL_HINT_AUDIO_NGAGE_PROCESS_TICK); @@ -223,34 +214,27 @@ TInt AudioThreadCB(TAny *aParams) processTick = SDL_atoi(tickHint) * 1000; } - - while (gAudioRunning) - { + while (gAudioRunning) { TInt error; CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); - + /*there is some mix data sound ready*/ - if (audio->iBufferReady) - { + if (audio->iBufferReady) { audio->iBufferReady = EFalse; SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr(); - if (device && device->hidden) - { + if (device && device->hidden) { SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden; audio->iState = EStateWriting; /*sends the chuck mixed to the queue*/ audio->iBufDes.Set(phdata->buffer[phdata->fill_index], device->buffer_size, device->buffer_size); TRAPD(werr, audio->iStream->WriteL(audio->iBufDes)); - if (werr != KErrNone) - { + if (werr != KErrNone) { /*asks ProcessThreadCB to bring another mix chunk*/ audio->iState = EStatePlaying; - } - else - { + } else { /*swap buffers so while this buffer is being played we can get the mix of the next one if we can*/ phdata->fill_index = 1 - phdata->fill_index; } @@ -270,16 +254,15 @@ TInt AudioThreadCB(TAny *aParams) } /*************************************************** -* MaoscOpenComplete - -* -* Opens the audiostream -* -* *******************************************************/ + * MaoscOpenComplete - + * + * Opens the audiostream + * + * *******************************************************/ void CAudio::MaoscOpenComplete(TInt aError) { - if (aError == KErrNone) - { + if (aError == KErrNone) { /*setting the volume to max, users can change the volume later of their channels individually in code*/ iStream->SetVolume(iStream->MaxVolume()); iStreamStarted = ETrue; @@ -296,11 +279,8 @@ void CAudio::MaoscOpenComplete(TInt aError) /* Kickstart: device is guaranteed valid now*/ this->iState = EStatePlaying; - - } - else - { + } else { SDL_Log("Error: Failed to open audio stream: %d", aError); } } @@ -314,17 +294,12 @@ void CAudio::MaoscOpenComplete(TInt aError) void CAudio::MaoscBufferCopied(TInt aError, const TDesC8 & /*aBuffer*/) { - if (aError == KErrNone) - { + if (aError == KErrNone) { iState = EStatePlaying; - } - else if (aError == KErrAbort) - { + } else if (aError == KErrAbort) { /* The stream has been stopped.*/ iState = EStateDone; - } - else - { + } else { SDL_Log("Error: Failed to copy audio buffer: %d", aError); } } @@ -338,13 +313,12 @@ void CAudio::MaoscBufferCopied(TInt aError, const TDesC8 & /*aBuffer*/) void CAudio::MaoscPlayComplete(TInt aError) { - + /* If we finish due to an underflow, we'll need to restart playback. Normally KErrUnderlow is raised at stream end, but in our case the API should never see the stream end -- we are continuously feeding it more data! Many underflow errors mean that the latency target is too low.*/ - if (aError == KErrUnderflow) - { + if (aError == KErrUnderflow) { /* Restart the stream hardware */ iStream->Stop(); TInt ignoredError; @@ -355,22 +329,17 @@ void CAudio::MaoscPlayComplete(TInt aError) return; } else if (aError != KErrNone) { - } /* We shouldn't get here.*/ SDL_Log("%s: %d", SDL_FUNCTION, aError); } - - TBool AudioIsReady() { return gAudioRunning; } - - RThread audioThread; void InitAudio(TInt *aLatency) diff --git a/src/main/ngage/SDL_sysmain_main.cpp b/src/main/ngage/SDL_sysmain_main.cpp index 7fe7a9bf31..4e81c6d123 100644 --- a/src/main/ngage/SDL_sysmain_main.cpp +++ b/src/main/ngage/SDL_sysmain_main.cpp @@ -87,9 +87,15 @@ GLDEF_C TInt E32Main() TInt targetLatency = 225; InitAudio(&targetLatency); - // Wait until audio is ready. - while (!AudioIsReady()) { + // Wait until audio is ready (timeout after ~5 seconds). + TInt audioWaitMs = 0; + while (!AudioIsReady() && audioWaitMs < 5000) { User::After(100000); // 100ms. + audioWaitMs += 100; + } + if (!AudioIsReady()) { + SDL_Log("Error: Audio failed to initialise within timeout"); + User::Leave(KErrTimedOut); } // Create and start the rendering backend. @@ -104,8 +110,8 @@ GLDEF_C TInt E32Main() // Start the active scheduler to handle events. CActiveScheduler::Start(); - CleanupStack::PopAndDestroy(gRenderer); CleanupStack::PopAndDestroy(mainApp); + CleanupStack::PopAndDestroy(gRenderer); User::SwitchHeap(oldHeap); @@ -154,6 +160,7 @@ static bool callbacks_initialized = false; static void ShutdownApp(SDL_AppResult result) { + callbacks_initialized = false; DeinitAudio(); SDL_AppQuit(NULL, result); SDL_Quit(); From 56e0d052f18938e8d9c6cfe11d87d118afc1990d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 6 May 2026 12:30:46 -0400 Subject: [PATCH 232/407] opengles2: Rework render targets. Now this keeps one FBO for each SDL_TEXTUREACCESS_TARGET texture, and doesn't reuse it. We check if the FBO is "complete" once, at creation time, and setting a render target merely has to bind the right FBO and never look back. This simplifies the code and removes a guaranteed pipeline stall when setting a new render target. Fixes #15524. --- src/render/opengles2/SDL_render_gles2.c | 81 ++++++++----------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 8f4dc4eb56..a37f2b1b74 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -54,15 +54,6 @@ * Context structures * *************************************************************************************************/ -typedef struct GLES2_FBOList GLES2_FBOList; - -struct GLES2_FBOList -{ - Uint32 w, h; - GLuint FBO; - GLES2_FBOList *next; -}; - typedef struct { GLuint texture; @@ -71,6 +62,7 @@ typedef struct typedef struct { GLuint texture; + GLuint fbo; // framebuffer object; this is zero unless this texture is a render target. bool texture_external; GLenum texture_type; GLenum pixel_format; @@ -90,7 +82,6 @@ typedef struct SDL_ScaleMode texture_scale_mode; SDL_TextureAddressMode texture_address_mode_u; SDL_TextureAddressMode texture_address_mode_v; - GLES2_FBOList *fbo; } GLES2_TextureData; typedef enum @@ -193,7 +184,6 @@ typedef struct GLES2_RenderData #define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; #include "SDL_gles2funcs.h" #undef SDL_PROC - GLES2_FBOList *framebuffers; GLuint window_framebuffer; GLuint shader_id_cache[GLES2_SHADER_COUNT]; @@ -301,23 +291,6 @@ static bool GLES2_LoadFunctions(GLES2_RenderData *data) return true; } -static GLES2_FBOList *GLES2_GetFBO(GLES2_RenderData *data, Uint32 w, Uint32 h) -{ - GLES2_FBOList *result = data->framebuffers; - while ((result) && ((result->w != w) || (result->h != h))) { - result = result->next; - } - if (!result) { - result = (GLES2_FBOList *)SDL_malloc(sizeof(GLES2_FBOList)); - result->w = w; - result->h = h; - data->glGenFramebuffers(1, &result->FBO); - result->next = data->framebuffers; - data->framebuffers = result; - } - return result; -} - static bool GLES2_ActivateRenderer(SDL_Renderer *renderer) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->internal; @@ -1685,14 +1658,6 @@ static void GLES2_DestroyRenderer(SDL_Renderer *renderer) } if (data->context) { - while (data->framebuffers) { - GLES2_FBOList *nextnode = data->framebuffers->next; - data->glDeleteFramebuffers(1, &data->framebuffers->FBO); - GL_CheckError("", renderer); - SDL_free(data->framebuffers); - data->framebuffers = nextnode; - } - #if USE_VERTEX_BUFFER_OBJECTS data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); GL_CheckError("", renderer); @@ -1956,6 +1921,11 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD if (texture->format != SDL_PIXELFORMAT_EXTERNAL_OES) { renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); if (!GL_CheckError("glTexImage2D()", renderer)) { + if (!data->texture_external) { + renderdata->glDeleteTextures(1, &data->texture); + } + SDL_free(data->pixel_data); + SDL_free(data); return false; } } @@ -1965,9 +1935,20 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER, data->texture_type); if (texture->access == SDL_TEXTUREACCESS_TARGET) { - data->fbo = GLES2_GetFBO((GLES2_RenderData *)renderer->internal, texture->w, texture->h); - } else { - data->fbo = NULL; + renderdata->glGenFramebuffers(1, &data->fbo); + renderdata->glBindFramebuffer(GL_FRAMEBUFFER, data->fbo); + renderdata->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, data->texture_type, data->texture, 0); + const GLenum status = renderdata->glCheckFramebufferStatus(GL_FRAMEBUFFER); + renderdata->glBindFramebuffer(GL_FRAMEBUFFER, renderer->target ? ((GLES2_TextureData *)renderer->target->internal)->fbo : renderdata->window_framebuffer); // rebind previous fbo. + if (status != GL_FRAMEBUFFER_COMPLETE) { + renderdata->glDeleteFramebuffers(1, &data->fbo); + if (!data->texture_external) { + renderdata->glDeleteTextures(1, &data->texture); + } + SDL_free(data->pixel_data); + SDL_free(data); + return SDL_SetError("Texture framebuffer was incomplete"); + } } return GL_CheckError("", renderer); @@ -2206,24 +2187,8 @@ static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) static bool GLES2_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->internal; - GLES2_TextureData *texturedata = NULL; - GLenum status; - data->drawstate.viewport_dirty = true; - - if (!texture) { - data->glBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer); - } else { - texturedata = (GLES2_TextureData *)texture->internal; - data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO); - // TODO: check if texture pixel format allows this operation - data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0); - // Check FBO status - status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - return SDL_SetError("glFramebufferTexture2D() failed"); - } - } + data->glBindFramebuffer(GL_FRAMEBUFFER, texture ? ((GLES2_TextureData *)texture->internal)->fbo : data->window_framebuffer); return true; } @@ -2244,6 +2209,9 @@ static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) // Destroy the texture if (tdata) { + if (tdata->fbo) { + data->glDeleteFramebuffers(1, &tdata->fbo); + } if (tdata->texture && !tdata->texture_external) { data->glDeleteTextures(1, &tdata->texture); } @@ -2433,7 +2401,6 @@ static bool GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); #endif - data->framebuffers = NULL; data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer); data->window_framebuffer = (GLuint)window_framebuffer; From f8c364ae7432bc8efee0914734d3afb18458f394 Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Wed, 6 May 2026 15:14:09 -0700 Subject: [PATCH 233/407] Ensure Android hidapi does not drop the report byte (#15527) --- src/hidapi/android/hid.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp index c839906cda..15a3162387 100644 --- a/src/hidapi/android/hid.cpp +++ b/src/hidapi/android/hid.cpp @@ -725,9 +725,27 @@ public: } } - size_t uBytesToCopy = m_reportResponse.size() > nDataLen ? nDataLen : m_reportResponse.size(); - SDL_memcpy( pData, m_reportResponse.data(), uBytesToCopy ); - m_reportResponse.clear(); + size_t uBytesToCopy = 0; + + if ( m_reportResponse.size() > 0 ) + { + // Make sure we preserve the report value if it isn't already in the report. + bool bHasReportAlready = ( *pData == *m_reportResponse.data() ); + + // Make sure we only copy as much as will fit, deducting one byte for the report if we need to leave it intact. + size_t nSafeDataLen = nDataLen - ( bHasReportAlready ? 0 : 1 ); + uBytesToCopy = m_reportResponse.size() < nSafeDataLen ? m_reportResponse.size() : nSafeDataLen; + + SDL_memcpy( pData + ( bHasReportAlready ? 0 : 1 ), m_reportResponse.data(), uBytesToCopy ); + m_reportResponse.clear(); + + if ( !bHasReportAlready ) + { + // Add the report byte back on to return the real length. + uBytesToCopy++; + } + } + LOGV( "=== Got %zu bytes", uBytesToCopy ); return (int)uBytesToCopy; From 386f198622083f8b91753f3bcce75c631c3701b5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 6 May 2026 18:12:01 -0700 Subject: [PATCH 234/407] Don't report 10% battery for Xbox controllers using XInput --- src/joystick/windows/SDL_rawinputjoystick.c | 32 +++++++++++--------- src/joystick/windows/SDL_xinputjoystick.c | 33 ++++++++++++--------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index c8cd9cd3a7..e67d9fd3e7 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -1976,20 +1976,24 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) state = SDL_POWERSTATE_ON_BATTERY; break; } - switch (battery_info->BatteryLevel) { - case BATTERY_LEVEL_EMPTY: - percent = 10; - break; - case BATTERY_LEVEL_LOW: - percent = 40; - break; - case BATTERY_LEVEL_MEDIUM: - percent = 70; - break; - default: - case BATTERY_LEVEL_FULL: - percent = 100; - break; + if (state == SDL_POWERSTATE_ON_BATTERY || SDL_POWERSTATE_CHARGING) { + switch (battery_info->BatteryLevel) { + case BATTERY_LEVEL_EMPTY: + percent = 10; + break; + case BATTERY_LEVEL_LOW: + percent = 40; + break; + case BATTERY_LEVEL_MEDIUM: + percent = 70; + break; + default: + case BATTERY_LEVEL_FULL: + percent = 100; + break; + } + } else { + percent = -1; } SDL_SendJoystickPowerInfo(joystick, state, percent); } diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 8f26bcd7db..d7a132e1d1 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -300,20 +300,24 @@ static void UpdateXInputJoystickBatteryInformation(SDL_Joystick *joystick, XINPU state = SDL_POWERSTATE_ON_BATTERY; break; } - switch (pBatteryInformation->BatteryLevel) { - case BATTERY_LEVEL_EMPTY: - percent = 10; - break; - case BATTERY_LEVEL_LOW: - percent = 40; - break; - case BATTERY_LEVEL_MEDIUM: - percent = 70; - break; - default: - case BATTERY_LEVEL_FULL: - percent = 100; - break; + if (state == SDL_POWERSTATE_ON_BATTERY || state == SDL_POWERSTATE_CHARGING) { + switch (pBatteryInformation->BatteryLevel) { + case BATTERY_LEVEL_EMPTY: + percent = 10; + break; + case BATTERY_LEVEL_LOW: + percent = 40; + break; + case BATTERY_LEVEL_MEDIUM: + percent = 70; + break; + default: + case BATTERY_LEVEL_FULL: + percent = 100; + break; + } + } else { + percent = -1; } SDL_SendJoystickPowerInfo(joystick, state, percent); } @@ -391,6 +395,7 @@ void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick) return; } + // FIXME: This does end up making a device ioctl() to query data, we shouldn't do this every update. SDL_zero(XBatteryInformation); if (XINPUTGETBATTERYINFORMATION) { result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation); From 5d63a4cad29ba50d04b8136fe8a5a1b87eee7707 Mon Sep 17 00:00:00 2001 From: Torbjorn Laedre <271210+tlaedre@users.noreply.github.com> Date: Fri, 10 Apr 2026 15:56:06 +0200 Subject: [PATCH 235/407] Change 3D texture memory barrier sub-resource range to be maintenance9 compatible. --- src/gpu/vulkan/SDL_gpu_vulkan.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 259fbecb06..4e975a5aa5 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -2739,10 +2739,17 @@ static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; memoryBarrier.image = textureSubresource->parent->image; memoryBarrier.subresourceRange.aspectMask = textureSubresource->parent->aspectFlags; - memoryBarrier.subresourceRange.baseArrayLayer = textureSubresource->layer; - memoryBarrier.subresourceRange.layerCount = 1; memoryBarrier.subresourceRange.baseMipLevel = textureSubresource->level; memoryBarrier.subresourceRange.levelCount = 1; + memoryBarrier.subresourceRange.baseArrayLayer = textureSubresource->layer; + memoryBarrier.subresourceRange.layerCount = 1; + + // VK_KHR_maintenance9 adds the ability to independently transition arbitrary subsets of slices in a 3D texture, + // we need to extend the barrier layer count in order to preserve intended behaviour when that extension is enabled. + // See https://docs.vulkan.org/features/latest/features/proposals/VK_KHR_maintenance9.html#_barriers_with_2d_array_compatible_3d_images + if (textureSubresource->parent->container->header.info.type == SDL_GPU_TEXTURETYPE_3D) { + memoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + } if (sourceUsageMode == VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED) { srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; @@ -6004,12 +6011,6 @@ static void VULKAN_INTERNAL_CycleActiveTexture( renderer, &container->header.info); - VULKAN_INTERNAL_TextureTransitionToDefaultUsage( - renderer, - commandBuffer, - VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, - texture); - if (!texture) { return; } @@ -6027,6 +6028,13 @@ static void VULKAN_INTERNAL_CycleActiveTexture( container->textureCount += 1; container->activeTexture = texture; + + // Transition texture after storing it as the memory barrier might need to read the texture's container info + VULKAN_INTERNAL_TextureTransitionToDefaultUsage( + renderer, + commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, + texture); } static VulkanBuffer *VULKAN_INTERNAL_PrepareBufferForWrite( From ab19d09939f7c3365508f3894ae63d9faa16c529 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 6 May 2026 19:42:39 -0700 Subject: [PATCH 236/407] Fixed build --- src/joystick/windows/SDL_rawinputjoystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index e67d9fd3e7..7a69775e26 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -1976,7 +1976,7 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) state = SDL_POWERSTATE_ON_BATTERY; break; } - if (state == SDL_POWERSTATE_ON_BATTERY || SDL_POWERSTATE_CHARGING) { + if (state == SDL_POWERSTATE_ON_BATTERY || state == SDL_POWERSTATE_CHARGING) { switch (battery_info->BatteryLevel) { case BATTERY_LEVEL_EMPTY: percent = 10; From 2949a0d6d51a591e49c189769d2b09ba24db8efe Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 7 May 2026 13:10:47 +0200 Subject: [PATCH 237/407] Enable text editing events in checkkeys --- test/checkkeys.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/checkkeys.c b/test/checkkeys.c index aaaff1462f..9c2e28ec93 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -467,6 +467,9 @@ int main(int argc, char *argv[]) /* Disable mouse emulation */ SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); + /* Enable text editing events and tell SDL that we'll handle rendering compositions. */ + SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, "composition"); + /* Initialize SDL */ if (!SDLTest_CommonInit(state)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError()); From c8feb297465d6702f293d0941b8e6d3554653a26 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 7 May 2026 09:58:56 -0700 Subject: [PATCH 238/407] GPU: Clarify VK_KHR_maintenance9 comment --- src/gpu/vulkan/SDL_gpu_vulkan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 4e975a5aa5..b366f7211f 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -2744,8 +2744,10 @@ static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( memoryBarrier.subresourceRange.baseArrayLayer = textureSubresource->layer; memoryBarrier.subresourceRange.layerCount = 1; - // VK_KHR_maintenance9 adds the ability to independently transition arbitrary subsets of slices in a 3D texture, - // we need to extend the barrier layer count in order to preserve intended behaviour when that extension is enabled. + // VK_KHR_maintenance9 adds the ability to independently transition arbitrary subsets of slices in a 3D texture + // but otherwise it is not necessarily supported by the driver. + // As a workaround we have to transition the whole texture instead of just the subresource. + // If VK_KHR_maintenance9 becomes widely supported, this can be removed. // See https://docs.vulkan.org/features/latest/features/proposals/VK_KHR_maintenance9.html#_barriers_with_2d_array_compatible_3d_images if (textureSubresource->parent->container->header.info.type == SDL_GPU_TEXTURETYPE_3D) { memoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; From ba3577f5846d3aa6fd074c4decc18eac747b514e Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 6 May 2026 12:41:53 -0400 Subject: [PATCH 239/407] wayland: Ensure window dimensions are greater than zero after adjusting for aspect Resizing to zero can cause a bad viewport size error. --- src/video/wayland/SDL_waylandwindow.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 075bae63e1..c4385b31c6 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -1107,9 +1107,9 @@ static void handle_xdg_toplevel_configure(void *data, const float aspect = (float)wind->requested.logical_width / (float)wind->requested.logical_height; if (window->min_aspect != 0.f && aspect < window->min_aspect) { - wind->requested.logical_height = SDL_lroundf((float)wind->requested.logical_width / window->min_aspect); + wind->requested.logical_height = SDL_max(SDL_lroundf((float)wind->requested.logical_width / window->min_aspect), 1); } else if (window->max_aspect != 0.f && aspect > window->max_aspect) { - wind->requested.logical_width = SDL_lroundf((float)wind->requested.logical_height * window->max_aspect); + wind->requested.logical_width = SDL_max(SDL_lroundf((float)wind->requested.logical_height * window->max_aspect), 1); } } else { if (window->max_w > 0) { @@ -1126,9 +1126,9 @@ static void handle_xdg_toplevel_configure(void *data, const float aspect = (float)wind->requested.pixel_width / (float)wind->requested.pixel_height; if (window->min_aspect != 0.f && aspect < window->min_aspect) { - wind->requested.pixel_height = SDL_lroundf((float)wind->requested.pixel_width / window->min_aspect); + wind->requested.pixel_height = SDL_max(SDL_lroundf((float)wind->requested.pixel_width / window->min_aspect), 1); } else if (window->max_aspect != 0.f && aspect > window->max_aspect) { - wind->requested.pixel_width = SDL_lroundf((float)wind->requested.pixel_height * window->max_aspect); + wind->requested.pixel_width = SDL_max(SDL_lroundf((float)wind->requested.pixel_height * window->max_aspect), 1); } wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width); @@ -1594,9 +1594,9 @@ static void decoration_frame_configure(struct libdecor_frame *frame, const float aspect = (float)wind->requested.logical_width / (float)wind->requested.logical_height; if (window->min_aspect != 0.f && aspect < window->min_aspect) { - wind->requested.logical_height = SDL_lroundf((float)wind->requested.logical_width / window->min_aspect); + wind->requested.logical_height = SDL_max(SDL_lroundf((float)wind->requested.logical_width / window->min_aspect), 1); } else if (window->max_aspect != 0.f && aspect > window->max_aspect) { - wind->requested.logical_width = SDL_lroundf((float)wind->requested.logical_height * window->max_aspect); + wind->requested.logical_width = SDL_max(SDL_lroundf((float)wind->requested.logical_height * window->max_aspect), 1); } } else { if (window->max_w > 0) { @@ -1613,9 +1613,9 @@ static void decoration_frame_configure(struct libdecor_frame *frame, const float aspect = (float)wind->requested.pixel_width / (float)wind->requested.pixel_height; if (window->min_aspect != 0.f && aspect < window->min_aspect) { - wind->requested.pixel_height = SDL_lroundf((float)wind->requested.pixel_width / window->min_aspect); + wind->requested.pixel_height = SDL_max(SDL_lroundf((float)wind->requested.pixel_width / window->min_aspect), 1); } else if (window->max_aspect != 0.f && aspect > window->max_aspect) { - wind->requested.pixel_width = SDL_lroundf((float)wind->requested.pixel_height * window->max_aspect); + wind->requested.pixel_width = SDL_max(SDL_lroundf((float)wind->requested.pixel_height * window->max_aspect), 1); } wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width); From 04d8a654d8d95a59fa04df9833deab8c6ea50b80 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Thu, 7 May 2026 12:27:06 -0400 Subject: [PATCH 240/407] wayland: Ensure the viewport size is always non-zero A viewport size of zero is a protocol error, so guard against it when adjusting the aspect ratio. --- src/video/wayland/SDL_waylandwindow.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index c4385b31c6..10d4524fa2 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -397,26 +397,26 @@ static void ConfigureWindowGeometry(SDL_Window *window) if (data->viewport && data->waylandData->subcompositor && !data->is_fullscreen) { if (window->min_w) { - window_width = viewport_width = SDL_max(viewport_width, window->min_w); + viewport_width = SDL_max(viewport_width, window->min_w); } if (window->min_h) { - window_height = viewport_height = SDL_max(viewport_height, window->min_h); + viewport_height = SDL_max(viewport_height, window->min_h); } if (window->max_w) { - window_width = viewport_width = SDL_min(viewport_width, window->max_w); + viewport_width = SDL_min(viewport_width, window->max_w); } if (window->max_h) { - window_height = viewport_height = SDL_min(viewport_height, window->max_h); + viewport_height = SDL_min(viewport_height, window->max_h); } float aspect = (float)viewport_width / (float)viewport_height; if (window->min_aspect != 0.f && aspect < window->min_aspect) { - viewport_height = SDL_lroundf((float)viewport_width / window->min_aspect); + viewport_height = SDL_max(SDL_lroundf((float)viewport_width / window->min_aspect), 1); } else if (window->max_aspect != 0.f && aspect > window->max_aspect) { - viewport_width = SDL_lroundf((float)viewport_height * window->max_aspect); + viewport_width = SDL_max(SDL_lroundf((float)viewport_height * window->max_aspect), 1); } - // At this point, the viewport matches the window dimensions, but the viewport might be clamped to window dimensions beyond here. + // At this point, the viewport matches the virtual window dimensions, but the viewport might be clamped to the output window dimensions beyond here. window_width = viewport_width; window_height = viewport_height; @@ -446,6 +446,9 @@ static void ConfigureWindowGeometry(SDL_Window *window) } } } + + viewport_width = SDL_max(viewport_width, 1); + viewport_height = SDL_max(viewport_height, 1); } else { window_width = viewport_width; window_height = viewport_height; From d08ef12b127dcd69ffdf8498193a42acc4a8c9b6 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Thu, 7 May 2026 16:34:32 -0700 Subject: [PATCH 241/407] GPU: Allow depth texture arrays (#15534) --- src/gpu/SDL_gpu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index 3419b5ca21..c9dd9cbe7b 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -1363,10 +1363,6 @@ SDL_GPUTexture *SDL_CreateGPUTexture( } else { if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) { // Array Texture Validation - if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) { - SDL_assert_release(!"For array textures: usage must not contain DEPTH_STENCIL_TARGET"); - failed = true; - } if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) { SDL_assert_release(!"For array textures: sample_count must be SDL_GPU_SAMPLECOUNT_1"); failed = true; From 8efa8014df6d63af8d72fbc9cfc2236feb642dea Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 8 May 2026 00:37:31 +0000 Subject: [PATCH 242/407] Sync SDL3 wiki -> header [ci skip] --- docs/README-android.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README-android.md b/docs/README-android.md index 297088fe67..61e289fee8 100644 --- a/docs/README-android.md +++ b/docs/README-android.md @@ -254,7 +254,7 @@ e.g. */ return false; case SDL_EVENT_LOW_MEMORY: - /* You will get this when your app is paused and iOS wants more memory. + /* You will get this when your app is paused and Android wants more memory. Release as much memory as possible. */ return false; From cbe3fbe9f367340dcd924de29c225c9f4ffea1f5 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Thu, 7 May 2026 19:20:21 -0700 Subject: [PATCH 243/407] GPU: Validate that 2D textures don't have layers (#15535) --- src/gpu/SDL_gpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index c9dd9cbe7b..01e1eb5e9c 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -1277,6 +1277,11 @@ SDL_GPUTexture *SDL_CreateGPUTexture( SDL_assert_release(!"For any texture: num_levels must be >= 1"); failed = true; } + if (createinfo->type == SDL_GPU_TEXTURETYPE_2D && createinfo->layer_count_or_depth != 1) + { + SDL_assert_release(!"2D textures must have a layer count of 1"); + failed = true; + } if ((createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) && (createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER)) { SDL_assert_release(!"For any texture: usage cannot contain both GRAPHICS_STORAGE_READ and SAMPLER"); failed = true; From e497077cbf6a974640be79c814c1c662ba18c889 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Sat, 9 May 2026 23:58:32 +0000 Subject: [PATCH 244/407] Sync SDL3 wiki -> header [ci skip] --- docs/README-ps2.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/README-ps2.md b/docs/README-ps2.md index 6d3e79a571..89916d5912 100644 --- a/docs/README-ps2.md +++ b/docs/README-ps2.md @@ -45,11 +45,17 @@ Remember to do a clean compilation every time you enable or disable the `SDL_PS2 ## Getting PS2 Dev [Installing PS2 Dev](https://github.com/ps2dev/ps2dev) -## Running on PCSX2 Emulator +## Running on Emulators [PCSX2](https://github.com/PCSX2/pcsx2) [More PCSX2 information](https://pcsx2.net/) +[Iris](https://github.com/allkern/iris) + +[More Iris information](https://allkern.dev/iris) + +[Play!](https://github.com/jpd002/Play-) + ## To Do - PS2 Screen Keyboard - Dialogs From f48525aa703e0e11134347b38571661d6ca829fd Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 10 May 2026 13:55:45 -0400 Subject: [PATCH 245/407] x11: Store the mouse button serial for emulated pointer events as well Otherwise, filtered emulated button events, such as for mouse wheels, can slip through the core event handler. --- src/video/x11/SDL_x11xinput2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index c099589591..56ccee53e5 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -605,6 +605,9 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) bool pointer_emulated = false; #endif + // Store the button serial to filter out redundant core button events. + videodata->xinput_last_button_serial = xev->serial; + if (pen) { if (xev->deviceid != xev->sourceid) { // Discard events from "Master" devices to avoid duplicates. @@ -622,9 +625,6 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); int x_ticks = 0, y_ticks = 0; - // Store the button serial to filter out redundant core button events. - videodata->xinput_last_button_serial = xev->serial; - if (xev->deviceid != videodata->xinput_master_pointer_device) { // Ignore slave button events on non-focused windows, or focus can be incorrectly set while a grab is active. if (SDL_GetMouseFocus() != windowdata->window) { From f6a1eb9ba96e054aa22c2fa51d291bcfb24dcac4 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sun, 10 May 2026 22:34:19 +0200 Subject: [PATCH 246/407] ci: bump actions, switch away from ilammy/msvc-dev-cmd --- .github/actions/setup-djgpp-toolchain/action.yml | 4 ++-- .github/workflows/generic.yml | 4 ++-- .github/workflows/release.yml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/setup-djgpp-toolchain/action.yml b/.github/actions/setup-djgpp-toolchain/action.yml index 636c669b04..efe2d80ae6 100644 --- a/.github/actions/setup-djgpp-toolchain/action.yml +++ b/.github/actions/setup-djgpp-toolchain/action.yml @@ -32,7 +32,7 @@ runs: echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT} - name: 'Restore cached ${{ steps.calc.outputs.archive }}' id: cache-restore - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} @@ -43,7 +43,7 @@ runs: Invoke-WebRequest "${{ steps.calc.outputs.url }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" - name: 'Cache ${{ steps.calc.outputs.archive }}' if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 10f241c023..2ac0e30743 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -81,7 +81,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: ilammy/msvc-dev-cmd@v1 + - uses: TheMrMilchmann/setup-msvc-dev@v4 if: ${{ matrix.platform.platform == 'msvc' }} with: arch: ${{ matrix.platform.msvc-vcvars-arch }} @@ -323,7 +323,7 @@ jobs: - name: 'Build (cross-platform-actions, BSD)' id: cpactions if: ${{ matrix.platform.cpactions }} - uses: cross-platform-actions/action@v0.32.0 + uses: cross-platform-actions/action@v1 with: operating_system: '${{ matrix.platform.cpactions-os }}' architecture: '${{ matrix.platform.cpactions-arch }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba43ece625..6929f152d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -391,7 +391,7 @@ jobs: - name: Set up ninja uses: ./.github/actions/setup-ninja - name: 'Configure vcvars x86' - uses: ilammy/msvc-dev-cmd@v1 + uses: TheMrMilchmann/setup-msvc-dev@v4 with: arch: x64_x86 - name: 'CMake (configure + build + tests) x86' @@ -411,7 +411,7 @@ jobs: cmake --build build_x86 --config Release --verbose ctest --test-dir build_x86 --no-tests=error -C Release --output-on-failure - name: 'Configure vcvars x64' - uses: ilammy/msvc-dev-cmd@v1 + uses: TheMrMilchmann/setup-msvc-dev@v4 with: arch: x64 - name: 'CMake (configure + build + tests) x64' @@ -431,7 +431,7 @@ jobs: cmake --build build_x64 --config Release --verbose ctest --test-dir build_x64 --no-tests=error -C Release --output-on-failure - name: 'Configure vcvars arm64' - uses: ilammy/msvc-dev-cmd@v1 + uses: TheMrMilchmann/setup-msvc-dev@v4 with: arch: x64_arm64 - name: 'CMake (configure + build) arm64' From c94b1435c7c573a626aea8ebec71b8f54471ae02 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 11 May 2026 09:43:39 +0100 Subject: [PATCH 247/407] Add joystickSetSensorsEnabled to proguard-rules.pro --- android-project/app/proguard-rules.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/android-project/app/proguard-rules.pro b/android-project/app/proguard-rules.pro index 0fb7ae09ac..66ecc43f14 100644 --- a/android-project/app/proguard-rules.pro +++ b/android-project/app/proguard-rules.pro @@ -68,6 +68,7 @@ } -keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager { + void joystickSetSensorsEnabled(int, boolean); void pollInputDevices(); void joystickSetLED(int, int, int, int); void pollHapticDevices(); From 7439a94ed244434e3c27df415c8362dd9626daff Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 9 May 2026 11:36:23 -0500 Subject: [PATCH 248/407] atomic: Implement loads on MSVC without RMW operations This fixes faults when loading from read-only memory and avoids cache line bouncing across cores which reduces performance. --- src/atomic/SDL_atomic.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index ee036fee8d..f14bd106dc 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -297,9 +297,15 @@ int SDL_GetAtomicInt(SDL_AtomicInt *a) { #ifdef HAVE_ATOMIC_LOAD_N return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); -#elif defined(HAVE_MSC_ATOMICS) - SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value)); - return _InterlockedOr((long *)&a->value, 0); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_ARM64) || defined(_M_ARM64EC)) + SDL_COMPILE_TIME_ASSERT(atomic_get_int, sizeof(__int32) == sizeof(a->value)); + return (int)__ldar32((unsigned __int32 *)&a->value); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_X64) || defined(_M_IX86)) + SDL_COMPILE_TIME_ASSERT(atomic_get_int, sizeof(int) == sizeof(a->value)); + SDL_CompilerBarrier(); + int value = *(volatile int *)&a->value; + SDL_CompilerBarrier(); + return value; #elif defined(HAVE_GCC_ATOMICS) return __sync_or_and_fetch(&a->value, 0); #elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics. @@ -319,9 +325,15 @@ Uint32 SDL_GetAtomicU32(SDL_AtomicU32 *a) { #ifdef HAVE_ATOMIC_LOAD_N return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); -#elif defined(HAVE_MSC_ATOMICS) - SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value)); - return (Uint32)_InterlockedOr((long *)&a->value, 0); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_ARM64) || defined(_M_ARM64EC)) + SDL_COMPILE_TIME_ASSERT(atomic_get_u32, sizeof(__int32) == sizeof(a->value)); + return __ldar32((unsigned __int32 *)&a->value); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_X64) || defined(_M_IX86)) + SDL_COMPILE_TIME_ASSERT(atomic_get_u32, sizeof(Uint32) == sizeof(a->value)); + SDL_CompilerBarrier(); + Uint32 value = *(volatile Uint32 *)&a->value; + SDL_CompilerBarrier(); + return value; #elif defined(HAVE_GCC_ATOMICS) return __sync_or_and_fetch(&a->value, 0); #elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics. @@ -342,8 +354,14 @@ void *SDL_GetAtomicPointer(void **a) { #ifdef HAVE_ATOMIC_LOAD_N return __atomic_load_n(a, __ATOMIC_SEQ_CST); -#elif defined(HAVE_MSC_ATOMICS) - return _InterlockedCompareExchangePointer(a, NULL, NULL); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_ARM64) || defined(_M_ARM64EC)) + SDL_COMPILE_TIME_ASSERT(atomic_get_ptr, sizeof(__int64) == sizeof(*a)); + return (void *)__ldar64((unsigned __int64 *)a); +#elif defined(HAVE_MSC_ATOMICS) && (defined(_M_X64) || defined(_M_IX86)) + SDL_CompilerBarrier(); + void *value = *(void * volatile *)a; + SDL_CompilerBarrier(); + return value; #elif defined(HAVE_GCC_ATOMICS) return __sync_val_compare_and_swap(a, (void *)0, (void *)0); #elif defined(SDL_PLATFORM_SOLARIS) From 287e2573cd0c4eb6fb16a4bcc407ee7d2e62bf38 Mon Sep 17 00:00:00 2001 From: Nintorch <92302738+Nintorch@users.noreply.github.com> Date: Sat, 9 May 2026 16:01:06 +0500 Subject: [PATCH 249/407] Ignore `Keychron K10 Pro` and `Huion Tablet_GS1331` --- src/joystick/SDL_joystick.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 904509c191..114f1b8cb7 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -447,12 +447,14 @@ static Uint32 initial_blacklist_devices[] = { MAKE_VIDPID(0x0e6f, 0x018a), // PDP REALMz Wireless Controller for Switch, USB charging MAKE_VIDPID(0x1532, 0x0266), // Razer Huntsman V2 Analog, non-functional DInput device MAKE_VIDPID(0x1532, 0x0282), // Razer Huntsman Mini Analog, non-functional DInput device - MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) + MAKE_VIDPID(0x256c, 0x006d), // Huion Tablet_GS1331, Huion Tablet_GS1331 Touch Strip + MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller MAKE_VIDPID(0x31e3, 0x1310), // Wooting 60HE (ARM) MAKE_VIDPID(0x3297, 0x1969), // Moonlander MK1 Keyboard MAKE_VIDPID(0x3434, 0x0121), // Keychron Q3 System Control MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control + MAKE_VIDPID(0x3434, 0x02a0), // Keychron K10 Pro System Control MAKE_VIDPID(0x3434, 0x0353), // Keychron V5 System Control MAKE_VIDPID(0x3434, 0xd030), // Keychron Link }; From 7ec70d39c46117a0791f315164d577902167af3d Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Mon, 11 May 2026 11:16:14 -0700 Subject: [PATCH 250/407] *Only* preserve report byte for feature reports. Oops. --- src/hidapi/android/hid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp index 15a3162387..3f4f53cdd3 100644 --- a/src/hidapi/android/hid.cpp +++ b/src/hidapi/android/hid.cpp @@ -727,7 +727,7 @@ public: size_t uBytesToCopy = 0; - if ( m_reportResponse.size() > 0 ) + if ( bFeature && m_reportResponse.size() > 0 ) { // Make sure we preserve the report value if it isn't already in the report. bool bHasReportAlready = ( *pData == *m_reportResponse.data() ); From 76f8705c1243640c7933f05fddf75f3e16fd7dff Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Mon, 11 May 2026 11:42:11 -0700 Subject: [PATCH 251/407] GPU: Fix segfault when copying to Vulkan swapchain (#15543) --- src/gpu/vulkan/SDL_gpu_vulkan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index b366f7211f..56074c96ad 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -2500,6 +2500,11 @@ static void VULKAN_INTERNAL_TrackTextureTransfer( VulkanCommandBuffer *commandBuffer, VulkanTexture *texture) { + // Textures not managed by our allocator (i.e. the swapchain) don't need to be refcounted. + if (texture->usedRegion == NULL) { + return; + } + TRACK_RESOURCE( texture, VulkanTexture *, From fd3cfb97c1a1d6ccccc67b2000dee71c9f1bab7d Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Mon, 11 May 2026 12:47:30 -0700 Subject: [PATCH 252/407] Ensure Android gamepad mappings don't lose the first button. --- src/joystick/SDL_gamepad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 71419ed3cd..319ccc1c73 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -750,7 +750,7 @@ static GamepadMapping_t *SDL_CreateMappingForAndroidGamepad(SDL_GUID guid) return NULL; } - SDL_strlcpy(mapping_string, "*,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "*,", sizeof(mapping_string)); if (button_mask & (1 << SDL_GAMEPAD_BUTTON_SOUTH)) { SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); From e4a327709dcf7d5a623aa5c0403cccfe09e6c0c4 Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Mon, 11 May 2026 15:19:57 -0700 Subject: [PATCH 253/407] Correctly support OG Steam Controller when connected via USB on Android (#15561) --- .../src/main/java/org/libsdl/app/HIDDeviceUSB.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java index f9e9389802..8ec1cd1bc8 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java @@ -132,8 +132,10 @@ class HIDDeviceUSB implements HIDDevice { } } - // Make sure the required endpoints were present - if (mInputEndpoint == null || mOutputEndpoint == null) { + // Make sure the required endpoints were present. The original Steam Controller and the wireless dongle for it do NOT + // actually have -- or require -- output endpoints, so we need to accept only an input one for them or else we'll fall + // back to the Android system gamepad functionality (and lose our paddles et al). + if (mInputEndpoint == null) { Log.w(TAG, "Missing required endpoint on USB device " + getDeviceName()); close(); return false; @@ -185,6 +187,11 @@ class HIDDeviceUSB implements HIDDevice { } return length; } else { + if (mOutputEndpoint == null) + { + Log.e(TAG, "Tried to write an output report to an interface with no output endpoint!"); + return -1; + } int res = mConnection.bulkTransfer(mOutputEndpoint, report, report.length, 1000); if (res != report.length) { Log.w(TAG, "writeOutputReport() returned " + res + " on device " + getDeviceName()); From bb4eedd67d9d673925a10f49cd30fd5351f14074 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 11 May 2026 16:47:26 -0700 Subject: [PATCH 254/407] Fixed a crash if we get a HID device with no path This can happen on Linux if udev_device_get_devnode() fails. --- src/joystick/hidapi/SDL_hidapijoystick.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 4e8dda32f5..81587b0a33 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -896,14 +896,19 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf for (curr = SDL_HIDAPI_devices, last = NULL; curr; last = curr, curr = curr->next) { } + char *path = SDL_strdup(info->path); + if (!path) { + SDL_OutOfMemory(); + return NULL; + } + device = (SDL_HIDAPI_Device *)SDL_calloc(1, sizeof(*device)); if (!device) { + SDL_free(path); return NULL; } SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, true); - if (info->path) { - device->path = SDL_strdup(info->path); - } + device->path = path; device->seen = true; device->vendor_id = info->vendor_id; device->product_id = info->product_id; @@ -1133,6 +1138,11 @@ static void HIDAPI_UpdateDeviceList(void) devs = SDL_hid_enumerate(0, 0); if (devs) { for (info = devs; info; info = info->next) { + if (!info->path) { + // We can't open this, ignore it + continue; + } + device = HIDAPI_GetJoystickByInfo(info->path, info->vendor_id, info->product_id); if (device) { device->seen = true; From 4940345a2e624fe8aca2eda5ceaf3fb0b90392c9 Mon Sep 17 00:00:00 2001 From: "Al. Lopez" <67606569+AL2009man@users.noreply.github.com> Date: Tue, 12 May 2026 00:45:10 -0400 Subject: [PATCH 255/407] added additional examples of paddle/misc buttons for Steam Controller (#15544) --- include/SDL3/SDL_gamepad.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index 113452535b..9c88a770ae 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -167,11 +167,11 @@ typedef enum SDL_GamepadButton SDL_GAMEPAD_BUTTON_DPAD_DOWN, SDL_GAMEPAD_BUTTON_DPAD_LEFT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, - SDL_GAMEPAD_BUTTON_MISC1, /**< Additional button (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button, Google Stadia capture button) */ - SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, /**< Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1, DualSense Edge RB button, Right Joy-Con SR button) */ - SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /**< Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3, DualSense Edge LB button, Left Joy-Con SL button) */ - SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /**< Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2, DualSense Edge right Fn button, Right Joy-Con SL button) */ - SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /**< Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4, DualSense Edge left Fn button, Left Joy-Con SR button) */ + SDL_GAMEPAD_BUTTON_MISC1, /**< Additional button (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Steam Controller QAM button, Amazon Luna microphone button, Google Stadia capture button) */ + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, /**< Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1, DualSense Edge RB button, Right Joy-Con SR button, Steam Controller R4 button) */ + SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /**< Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3, DualSense Edge LB button, Left Joy-Con SL button, Steam Controller L4 button) */ + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /**< Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2, DualSense Edge right Fn button, Right Joy-Con SL button, Steam Controller R5 button) */ + SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /**< Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4, DualSense Edge left Fn button, Left Joy-Con SR button, Steam Controller L5 button) */ SDL_GAMEPAD_BUTTON_TOUCHPAD, /**< PS4/PS5 touchpad button */ SDL_GAMEPAD_BUTTON_MISC2, /**< Additional button */ SDL_GAMEPAD_BUTTON_MISC3, /**< Additional button (e.g. Nintendo GameCube left trigger click) */ From f30ec9940af42c08466a36e42fe6d5847f7c124f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 11 May 2026 22:10:20 -0700 Subject: [PATCH 256/407] Removed Wooting 60HE (ARM) from the controller blacklist Fixes https://github.com/libsdl-org/SDL/issues/15555 --- src/joystick/SDL_joystick.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 114f1b8cb7..1d3c32f3e5 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -450,7 +450,6 @@ static Uint32 initial_blacklist_devices[] = { MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) MAKE_VIDPID(0x256c, 0x006d), // Huion Tablet_GS1331, Huion Tablet_GS1331 Touch Strip MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller - MAKE_VIDPID(0x31e3, 0x1310), // Wooting 60HE (ARM) MAKE_VIDPID(0x3297, 0x1969), // Moonlander MK1 Keyboard MAKE_VIDPID(0x3434, 0x0121), // Keychron Q3 System Control MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control From 5cf16e452264a6f2f8895ec046cadad41ada6123 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 12 May 2026 16:48:06 -0700 Subject: [PATCH 257/407] Added curved window mode on visionOS 26 (#15298) --- Xcode/SDL/SDL.xcodeproj/project.pbxproj | 92 ++- include/SDL3/SDL_events.h | 3 +- include/SDL3/SDL_video.h | 11 + src/events/SDL_events.c | 1 + src/render/SDL_render.c | 5 + src/render/metal/SDL_render_metal.m | 121 +++- .../uikit/SDL_CurvedContentHosting.swift | 410 +++++++++++++ src/video/uikit/SDL_CurvedContentView.swift | 350 +++++++++++ src/video/uikit/SDL_CurvedUIShader.swift | 544 ++++++++++++++++++ src/video/uikit/SDL_RealityKitHelper.swift | 396 +++++++++++++ src/video/uikit/SDL_UIKitBridge-objc.h | 50 ++ src/video/uikit/SDL_UIKitBridge-swift.h | 39 ++ src/video/uikit/SDL_UIKitBridge.m | 187 ++++++ src/video/uikit/SDL_uikitevents.m | 30 +- src/video/uikit/SDL_uikitmetalview.h | 35 +- src/video/uikit/SDL_uikitmetalview.m | 33 +- src/video/uikit/SDL_uikitview.m | 30 +- src/video/uikit/SDL_uikitviewcontroller.h | 4 + src/video/uikit/SDL_uikitviewcontroller.m | 26 + src/video/uikit/SDL_uikitviewcontroller.swift | 33 ++ src/video/uikit/SDL_uikitwindow.h | 6 + src/video/uikit/SDL_uikitwindow.m | 21 +- 22 files changed, 2328 insertions(+), 99 deletions(-) create mode 100644 src/video/uikit/SDL_CurvedContentHosting.swift create mode 100644 src/video/uikit/SDL_CurvedContentView.swift create mode 100644 src/video/uikit/SDL_CurvedUIShader.swift create mode 100644 src/video/uikit/SDL_RealityKitHelper.swift create mode 100644 src/video/uikit/SDL_UIKitBridge-objc.h create mode 100644 src/video/uikit/SDL_UIKitBridge-swift.h create mode 100644 src/video/uikit/SDL_UIKitBridge.m create mode 100644 src/video/uikit/SDL_uikitviewcontroller.swift diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 3704aa73ee..33664dcc30 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -50,13 +50,14 @@ 0000AEB9AE90228CA2D60000 /* SDL_asyncio.c in Sources */ = {isa = PBXBuildFile; fileRef = 00003928A612EC33D42C0000 /* SDL_asyncio.c */; }; 0000D5B526B85DE7AB1C0000 /* SDL_cocoapen.m in Sources */ = {isa = PBXBuildFile; fileRef = 0000CCA310B73A7B59910000 /* SDL_cocoapen.m */; }; 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; platformFilters = (macos, ); }; - 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; platformFilters = (ios, maccatalyst, macos, ); }; + 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; platformFilters = (ios, maccatalyst, macos, xros, ); }; 00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; platformFilters = (macos, ); }; - 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); settings = {ATTRIBUTES = (Required, ); }; }; + 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; platformFilters = (ios, maccatalyst, macos, tvos, xros, ); settings = {ATTRIBUTES = (Required, ); }; }; 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; platformFilters = (macos, ); }; 02D6A1C228A84B8F00A7F002 /* SDL_hidapi_sinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 02D6A1C128A84B8F00A7F001 /* SDL_hidapi_sinput.c */; }; 1485C3312BBA4AF30063985B /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1485C32F2BBA4A0C0063985B /* UniformTypeIdentifiers.framework */; platformFilters = (maccatalyst, macos, ); settings = {ATTRIBUTES = (Weak, ); }; }; - 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); settings = {ATTRIBUTES = (Weak, ); }; }; + 3AFD09EA2F9766BA00208BA9 /* SDL_CurvedUIShader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AFD09E92F9766BA00208BA9 /* SDL_CurvedUIShader.swift */; platformFilters = (xros, ); }; + 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; platformFilters = (ios, maccatalyst, macos, tvos, xros, ); settings = {ATTRIBUTES = (Weak, ); }; }; 557D0CFB254586D7003913E3 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABD23E28B6200529352 /* GameController.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 5616CA4C252BB2A6005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; 5616CA4D252BB2A6005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; @@ -82,8 +83,8 @@ A1626A522617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; - A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); settings = {ATTRIBUTES = (Required, ); }; }; - A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); }; + A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; platformFilters = (ios, maccatalyst, macos, tvos, xros, ); settings = {ATTRIBUTES = (Required, ); }; }; + A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; platformFilters = (ios, maccatalyst, macos, tvos, xros, ); }; A75FDB5823E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDBC523EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; @@ -368,8 +369,6 @@ E4F257972C81903800FCEAFC /* SDL_sysgpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F257862C81903800FCEAFC /* SDL_sysgpu.h */; }; E4F257982C81903800FCEAFC /* SDL_gpu_openxr.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F257882C81903800FCEAFC /* SDL_gpu_openxr.c */; }; E4F257992C81903800FCEAFC /* SDL_openxrdyn.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F257892C81903800FCEAFC /* SDL_openxrdyn.c */; }; - E4F2579A2C81903800FCEAFC /* SDL_gpu_openxr_c.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F2578A2C81903800FCEAFC /* SDL_gpu_openxr_c.h */; }; - E4F2579B2C81903800FCEAFC /* SDL_openxr_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F2578C2C81903800FCEAFC /* SDL_openxr_internal.h */; }; E4F7981A2AD8D84800669F54 /* SDL_core_unsupported.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F798192AD8D84800669F54 /* SDL_core_unsupported.c */; }; E4F7981C2AD8D85500669F54 /* SDL_dynapi_unsupported.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F7981B2AD8D85500669F54 /* SDL_dynapi_unsupported.h */; }; E4F7981E2AD8D86A00669F54 /* SDL_render_unsupported.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */; }; @@ -434,6 +433,13 @@ F3990E062A788303000D8759 /* SDL_hidapi_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = F3990E032A788303000D8759 /* SDL_hidapi_ios.h */; }; F3990E072A78833C000D8759 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; F3A4909E2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A8371C2F69C80100AD32B6 /* SDL_RealityKitHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A837162F69C80100AD32B6 /* SDL_RealityKitHelper.swift */; platformFilters = (xros, ); }; + F3A895712F7D8AAA00B9E5C2 /* SDL_CurvedContentHosting.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A8956D2F7D8AAA00B9E5C2 /* SDL_CurvedContentHosting.swift */; platformFilters = (xros, ); }; + F3A895722F7D8AAA00B9E5C2 /* SDL_CurvedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A8956E2F7D8AAA00B9E5C2 /* SDL_CurvedContentView.swift */; platformFilters = (xros, ); }; + F3A895792F7DC14400B9E5C2 /* SDL_UIKitBridge-objc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3A895772F7DC14400B9E5C2 /* SDL_UIKitBridge-objc.h */; platformFilters = (xros, ); }; + F3A8957A2F7DC14400B9E5C2 /* SDL_UIKitBridge-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = F3A895782F7DC14400B9E5C2 /* SDL_UIKitBridge-swift.h */; platformFilters = (xros, ); }; + F3A8957B2F7DC14400B9E5C2 /* SDL_UIKitBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = F3A895762F7DC14400B9E5C2 /* SDL_UIKitBridge.m */; platformFilters = (xros, ); }; + F3A8957D2F7DC15500B9E5C2 /* SDL_uikitviewcontroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A8957C2F7DC15500B9E5C2 /* SDL_uikitviewcontroller.swift */; platformFilters = (xros, ); }; F3A9AE982C8A13C100AAC390 /* SDL_gpu_util.h in Headers */ = {isa = PBXBuildFile; fileRef = F3A9AE922C8A13C100AAC390 /* SDL_gpu_util.h */; }; F3A9AE992C8A13C100AAC390 /* SDL_render_gpu.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A9AE932C8A13C100AAC390 /* SDL_render_gpu.c */; }; F3A9AE9A2C8A13C100AAC390 /* SDL_shaders_gpu.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A9AE942C8A13C100AAC390 /* SDL_shaders_gpu.c */; }; @@ -559,7 +565,7 @@ F3FBB10A2DDF93AB0000F9A0 /* SDL_hidapi_gamesir.c in Sources */ = {isa = PBXBuildFile; fileRef = F3FBB1092DDF93AB0000F9A0 /* SDL_hidapi_gamesir.c */; }; F3FD042E2C9B755700824C4C /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F3FD042C2C9B755700824C4C /* SDL_hidapi_nintendo.h */; }; F3FD042F2C9B755700824C4C /* SDL_hidapi_steam_hori.c in Sources */ = {isa = PBXBuildFile; fileRef = F3FD042D2C9B755700824C4C /* SDL_hidapi_steam_hori.c */; }; - FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); settings = {ATTRIBUTES = (Required, ); }; }; + FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; platformFilters = (ios, maccatalyst, macos, tvos, xros, ); settings = {ATTRIBUTES = (Required, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -617,6 +623,7 @@ 00D0D08310675DD9004B05EF /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 02D6A1C128A84B8F00A7F001 /* SDL_hidapi_sinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_sinput.c; sourceTree = ""; }; 1485C32F2BBA4A0C0063985B /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; }; + 3AFD09E92F9766BA00208BA9 /* SDL_CurvedUIShader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDL_CurvedUIShader.swift; sourceTree = ""; }; 5616CA49252BB2A5005D5928 /* SDL_url.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_url.c; sourceTree = ""; }; 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysurl.h; sourceTree = ""; }; 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_sysurl.m; sourceTree = ""; }; @@ -970,7 +977,6 @@ F338A1192D1B37E4007CDFDF /* SDL_tray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_tray.c; sourceTree = ""; }; F3395BA72D9A5971007246C8 /* SDL_hidapi_8bitdo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_8bitdo.c; sourceTree = ""; }; F3395BA72D9A5971007246C9 /* SDL_hidapi_flydigi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_flydigi.c; sourceTree = ""; }; - F3FBB1092DDF93AB0000F9A0 /* SDL_hidapi_gamesir.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_gamesir.c; sourceTree = ""; }; F344003C2D4022E1003F26D7 /* INSTALL.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = INSTALL.md; sourceTree = ""; }; F362B9152B3349E200D30B94 /* controller_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controller_list.h; sourceTree = ""; }; F362B9162B3349E200D30B94 /* SDL_gamepad_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamepad_c.h; sourceTree = ""; }; @@ -1026,6 +1032,13 @@ F3990E022A788303000D8759 /* SDL_hidapi_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_mac.h; sourceTree = ""; }; F3990E032A788303000D8759 /* SDL_hidapi_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_ios.h; sourceTree = ""; }; F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_ps5.c; sourceTree = ""; }; + F3A837162F69C80100AD32B6 /* SDL_RealityKitHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDL_RealityKitHelper.swift; sourceTree = ""; }; + F3A8956D2F7D8AAA00B9E5C2 /* SDL_CurvedContentHosting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDL_CurvedContentHosting.swift; sourceTree = ""; }; + F3A8956E2F7D8AAA00B9E5C2 /* SDL_CurvedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDL_CurvedContentView.swift; sourceTree = ""; }; + F3A895762F7DC14400B9E5C2 /* SDL_UIKitBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDL_UIKitBridge.m; sourceTree = ""; }; + F3A895772F7DC14400B9E5C2 /* SDL_UIKitBridge-objc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SDL_UIKitBridge-objc.h"; sourceTree = ""; }; + F3A895782F7DC14400B9E5C2 /* SDL_UIKitBridge-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SDL_UIKitBridge-swift.h"; sourceTree = ""; }; + F3A8957C2F7DC15500B9E5C2 /* SDL_uikitviewcontroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDL_uikitviewcontroller.swift; sourceTree = ""; }; F3A9AE922C8A13C100AAC390 /* SDL_gpu_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gpu_util.h; sourceTree = ""; }; F3A9AE932C8A13C100AAC390 /* SDL_render_gpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_gpu.c; sourceTree = ""; }; F3A9AE942C8A13C100AAC390 /* SDL_shaders_gpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_shaders_gpu.c; sourceTree = ""; }; @@ -1149,6 +1162,7 @@ F3FA5A1A2B59ACE000FEAD97 /* yuv_rgb_lsx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv_rgb_lsx.c; sourceTree = ""; }; F3FA5A1B2B59ACE000FEAD97 /* yuv_rgb_lsx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_lsx.h; sourceTree = ""; }; F3FA5A1C2B59ACE000FEAD97 /* yuv_rgb_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_common.h; sourceTree = ""; }; + F3FBB1092DDF93AB0000F9A0 /* SDL_hidapi_gamesir.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_gamesir.c; sourceTree = ""; }; F3FD042C2C9B755700824C4C /* SDL_hidapi_nintendo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_nintendo.h; sourceTree = ""; }; F3FD042D2C9B755700824C4C /* SDL_hidapi_steam_hori.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_steam_hori.c; sourceTree = ""; }; F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = ""; }; @@ -1738,8 +1752,15 @@ A7D8A61823E2513D00DCD162 /* uikit */ = { isa = PBXGroup; children = ( + F3A8956D2F7D8AAA00B9E5C2 /* SDL_CurvedContentHosting.swift */, + F3A8956E2F7D8AAA00B9E5C2 /* SDL_CurvedContentView.swift */, + 3AFD09E92F9766BA00208BA9 /* SDL_CurvedUIShader.swift */, + F3A837162F69C80100AD32B6 /* SDL_RealityKitHelper.swift */, A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */, A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */, + F3A895762F7DC14400B9E5C2 /* SDL_UIKitBridge.m */, + F3A895772F7DC14400B9E5C2 /* SDL_UIKitBridge-objc.h */, + F3A895782F7DC14400B9E5C2 /* SDL_UIKitBridge-swift.h */, A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */, A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */, A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */, @@ -1754,18 +1775,19 @@ A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */, A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */, A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */, + 000063D3D80F97ADC7770000 /* SDL_uikitpen.h */, + 000053D344416737F6050000 /* SDL_uikitpen.m */, A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */, A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */, A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */, A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */, A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */, A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */, + F3A8957C2F7DC15500B9E5C2 /* SDL_uikitviewcontroller.swift */, A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */, A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */, A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */, A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */, - 000063D3D80F97ADC7770000 /* SDL_uikitpen.h */, - 000053D344416737F6050000 /* SDL_uikitpen.m */, ); path = uikit; sourceTree = ""; @@ -2365,17 +2387,6 @@ path = vulkan; sourceTree = ""; }; - E4F2578B2C81903800FCEAFC /* xr */ = { - isa = PBXGroup; - children = ( - E4F257882C81903800FCEAFC /* SDL_gpu_openxr.c */, - E4F257892C81903800FCEAFC /* SDL_openxrdyn.c */, - E4F2578A2C81903800FCEAFC /* SDL_gpu_openxr_c.h */, - E4F2578C2C81903800FCEAFC /* SDL_openxr_internal.h */, - ); - path = xr; - sourceTree = ""; - }; E4F257872C81903800FCEAFC /* gpu */ = { isa = PBXGroup; children = ( @@ -2388,6 +2399,17 @@ path = gpu; sourceTree = ""; }; + E4F2578B2C81903800FCEAFC /* xr */ = { + isa = PBXGroup; + children = ( + E4F257882C81903800FCEAFC /* SDL_gpu_openxr.c */, + E4F257892C81903800FCEAFC /* SDL_openxrdyn.c */, + E4F2578A2C81903800FCEAFC /* SDL_gpu_openxr_c.h */, + E4F2578C2C81903800FCEAFC /* SDL_openxr_internal.h */, + ); + path = xr; + sourceTree = ""; + }; F338A1142D1B3735007CDFDF /* tray */ = { isa = PBXGroup; children = ( @@ -2561,6 +2583,8 @@ F3EFA5ED2D5AB97300BCF22F /* SDL_stb_c.h in Headers */, F3EFA5EE2D5AB97300BCF22F /* stb_image.h in Headers */, F3EFA5EF2D5AB97300BCF22F /* SDL_surface_c.h in Headers */, + F3A895792F7DC14400B9E5C2 /* SDL_UIKitBridge-objc.h in Headers */, + F3A8957A2F7DC14400B9E5C2 /* SDL_UIKitBridge-swift.h in Headers */, A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */, @@ -2843,6 +2867,9 @@ attributes = { LastUpgradeCheck = 1130; TargetAttributes = { + BECDF5FE0761BA81005FE872 = { + LastSwiftMigration = 2630; + }; F3676F582A7885080091160D = { CreatedOnToolsVersion = 14.3.1; }; @@ -2931,6 +2958,7 @@ buildActionMask = 2147483647; files = ( A7D8B9E323E2514400DCD162 /* SDL_drawline.c in Sources */, + F3A8957B2F7DC14400B9E5C2 /* SDL_UIKitBridge.m in Sources */, A7D8AE7C23E2514100DCD162 /* SDL_yuv.c in Sources */, A7D8B62F23E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, A7D8B41C23E2514300DCD162 /* SDL_systls.c in Sources */, @@ -3059,6 +3087,7 @@ F3B439512C935C2400792030 /* SDL_dummyprocess.c in Sources */, A7D8B76423E2514300DCD162 /* SDL_mixer.c in Sources */, A7D8BB5723E2514500DCD162 /* SDL_events.c in Sources */, + F3A8957D2F7DC15500B9E5C2 /* SDL_uikitviewcontroller.swift in Sources */, A7D8ADE623E2514100DCD162 /* SDL_blit_0.c in Sources */, 89E5801E2D03602200DAF6D3 /* SDL_hidapi_lg4ff.c in Sources */, A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */, @@ -3086,6 +3115,7 @@ A7D8B56323E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, A7D8B4DC23E2514300DCD162 /* SDL_joystick.c in Sources */, A7D8BA4923E2514400DCD162 /* SDL_render_gles2.c in Sources */, + F3A8371C2F69C80100AD32B6 /* SDL_RealityKitHelper.swift in Sources */, A7D8AC2D23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54B23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2323E2514100DCD162 /* SDL_blit_auto.c in Sources */, @@ -3141,6 +3171,8 @@ A7D8A94B23E2514000DCD162 /* SDL.c in Sources */, A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, + F3A895712F7D8AAA00B9E5C2 /* SDL_CurvedContentHosting.swift in Sources */, + F3A895722F7D8AAA00B9E5C2 /* SDL_CurvedContentView.swift in Sources */, 566E26D8246274CC00718109 /* SDL_locale.c in Sources */, 63134A262A7902FD0021E9A6 /* SDL_pen.c in Sources */, 000040E76FDC6AE48CBF0000 /* SDL_hashtable.c in Sources */, @@ -3153,6 +3185,7 @@ 00002B20A48E055EB0350000 /* SDL_camera_coremedia.m in Sources */, 000080903BC03006F24E0000 /* SDL_filesystem.c in Sources */, F3FBB1082DDF93AB0000F99F /* SDL_hidapi_flydigi.c in Sources */, + 3AFD09EA2F9766BA00208BA9 /* SDL_CurvedUIShader.swift in Sources */, F3FBB10A2DDF93AB0000F9A0 /* SDL_hidapi_gamesir.c in Sources */, 0000481D255AF155B42C0000 /* SDL_sysfsops.c in Sources */, 0000494CC93F3E624D3C0000 /* SDL_systime.c in Sources */, @@ -3239,13 +3272,18 @@ isa = XCBuildConfiguration; baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../../src/dynapi/SDL_dynapi.exports"; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; OTHER_LDFLAGS = "-liconv"; SUPPORTS_MACCATALYST = YES; + "SWIFT_OBJC_BRIDGING_HEADER[sdk=xr*]" = "../../src/video/uikit/SDL_UIKitBridge-swift.h"; + SWIFT_VERSION = 6.0; + XROS_DEPLOYMENT_TARGET = 26.0; }; name = Release; }; @@ -3305,13 +3343,19 @@ isa = XCBuildConfiguration; baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../../src/dynapi/SDL_dynapi.exports"; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; OTHER_LDFLAGS = "-liconv"; SUPPORTS_MACCATALYST = YES; + "SWIFT_OBJC_BRIDGING_HEADER[sdk=xr*]" = "../../src/video/uikit/SDL_UIKitBridge-swift.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 6.0; + XROS_DEPLOYMENT_TARGET = 26.0; }; name = Debug; }; diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index fa923b0d1e..5b60e3df9b 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -163,8 +163,9 @@ typedef enum SDL_EventType associated with the window. Otherwise, the handle has already been destroyed and all resources associated with it are invalid */ SDL_EVENT_WINDOW_HDR_STATE_CHANGED, /**< Window HDR properties have changed */ + SDL_EVENT_WINDOW_CURVATURE_CHANGED, /**< Window curvature has changed to data1 (on visionOS) */ SDL_EVENT_WINDOW_FIRST = SDL_EVENT_WINDOW_SHOWN, - SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_HDR_STATE_CHANGED, + SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_CURVATURE_CHANGED, /* Keyboard events */ SDL_EVENT_KEY_DOWN = 0x300, /**< Key pressed */ diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 6117eceaf9..57fa31f001 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -1384,6 +1384,11 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren * popup windows and have the behaviors and guidelines outlined in * SDL_CreatePopupWindow(). * + * These are additional supported properties with visionOS: + * + * - `SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT`: the curvature of the window on visionOS. Curved windows have square corners and additional controls for more immersive gaming. + * This can be -1 (disabled), which is the default, 0 (no curve), or set to a specific curvature radius in millimeters. A common value for a gaming monitor is 1000. + * * If this window is being created to be used with an SDL_Renderer, you should * not add a graphics API specific property * (`SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN`, etc), as SDL will handle that @@ -1446,6 +1451,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop #define SDL_PROP_WINDOW_CREATE_X11_WINDOW_NUMBER "SDL.window.create.x11.window" #define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.create.emscripten.canvas_id" #define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.create.emscripten.keyboard_element" +#define SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT "SDL.window.create.curvature" /** * Get the numeric ID of a window. @@ -1624,6 +1630,10 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window) * - `SDL_PROP_WINDOW_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING`: the keyboard * element that associates keyboard events to this window * + * On visionOS: + * + * - `SDL_PROP_WINDOW_CURVATURE_FLOAT`: the curvature of the window in curved mode on visionOS. This value is updated dynamically when changed via the screen ornaments. This can be 0 (no curve), or a specific curvature radius in millimeters. A common value for a gaming monitor is 1000. + * * \param window the window to query. * \returns a valid property ID on success or 0 on failure; call * SDL_GetError() for more information. @@ -1673,6 +1683,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetWindowProperties(SDL_Window #define SDL_PROP_WINDOW_X11_WINDOW_NUMBER "SDL.window.x11.window" #define SDL_PROP_WINDOW_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.emscripten.canvas_id" #define SDL_PROP_WINDOW_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.emscripten.keyboard_element" +#define SDL_PROP_WINDOW_CURVATURE_FLOAT "SDL.window.curvature" /** * Get the window flags. diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index c909a2a583..315a8b6d90 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -565,6 +565,7 @@ int SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen) SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN); SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED); SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_HDR_STATE_CHANGED); + SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_CURVATURE_CHANGED); #undef SDL_WINDOWEVENT_CASE #define PRINT_KEYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " which=%u)", event->kdevice.timestamp, (uint)event->kdevice.which) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 5f80fae6d6..9894d44678 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -177,7 +177,12 @@ bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat forma void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props) { +#ifdef SDL_PLATFORM_VISIONOS + // The RealityKit texture always renders in linear colorspace + renderer->output_colorspace = SDL_COLORSPACE_SRGB_LINEAR; +#else renderer->output_colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB); +#endif } bool SDL_RenderingLinearSpace(SDL_Renderer *renderer) diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index d5187b6113..66b1331c07 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -35,6 +35,9 @@ #endif #ifdef SDL_VIDEO_DRIVER_UIKIT #import +#ifdef SDL_PLATFORM_VISIONOS +#import "../../video/uikit/SDL_UIKitBridge-objc.h" +#endif #endif // Regenerate these with build-metal-shaders.sh @@ -139,6 +142,9 @@ typedef struct METAL_ShaderPipelines @property(nonatomic, assign) METAL_ShaderPipelines *activepipelines; @property(nonatomic, assign) METAL_ShaderPipelines *allpipelines; @property(nonatomic, assign) int pipelinescount; +#ifdef SDL_PLATFORM_VISIONOS +@property(nonatomic, retain) id mtlrealitykittexture; +#endif @end @implementation SDL3METAL_RenderData @@ -453,16 +459,25 @@ static bool METAL_ActivateRenderCommandEncoder(SDL_Renderer *renderer, MTLLoadAc SDL3METAL_TextureData *texdata = (__bridge SDL3METAL_TextureData *)renderer->target->internal; mtltexture = texdata.mtltexture; } else { - if (data.mtlbackbuffer == nil) { - /* The backbuffer's contents aren't guaranteed to persist after - * presenting, so we can leave it undefined when loading it. */ - data.mtlbackbuffer = [data.mtllayer nextDrawable]; - if (load == MTLLoadActionLoad) { - load = MTLLoadActionDontCare; +#ifdef SDL_PLATFORM_VISIONOS + if (renderer->window && SDL_UIKit_IsCurvedWindow(renderer->window)) { + data.mtlrealitykittexture = SDL_UIKit_GetCurvedDisplayTexture(renderer->window, [data.mtlcmdqueue commandBuffer], (int)data.mtllayer.drawableSize.width, (int)data.mtllayer.drawableSize.height, data.mtllayer.pixelFormat); + mtltexture = data.mtlrealitykittexture; + } else +#endif + { + // Standard rendering path: use CAMetalLayer drawable + if (data.mtlbackbuffer == nil) { + // The backbuffer's contents aren't guaranteed to persist after + // presenting, so we can leave it undefined when loading it. + data.mtlbackbuffer = [data.mtllayer nextDrawable]; + if (load == MTLLoadActionLoad) { + load = MTLLoadActionDontCare; + } + } + if (data.mtlbackbuffer != nil) { + mtltexture = data.mtlbackbuffer.texture; } - } - if (data.mtlbackbuffer != nil) { - mtltexture = data.mtlbackbuffer.texture; } } @@ -1922,12 +1937,57 @@ static bool METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd } } +#ifdef SDL_PLATFORM_VISIONOS +static id METAL_CopyToStagingTexture(SDL_Renderer *renderer, id texture, SDL_Rect *rect) +{ + SDL3METAL_RenderData *data = (__bridge SDL3METAL_RenderData *)renderer->internal; + MTLTextureDescriptor *desc; + id stagingtex; + id blitcmd; + + desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:texture.pixelFormat + width:rect->w + height:rect->h + mipmapped:NO]; + if (desc == nil) { + SDL_OutOfMemory(); + return nil; + } + + stagingtex = [data.mtldevice newTextureWithDescriptor:desc]; + if (stagingtex == nil) { + SDL_OutOfMemory(); + return nil; + } + + blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; + + [blitcmd copyFromTexture:texture + sourceSlice:0 + sourceLevel:0 + sourceOrigin:MTLOriginMake(rect->x, rect->y, 0) + sourceSize:MTLSizeMake(rect->w, rect->h, 1) + toTexture:stagingtex + destinationSlice:0 + destinationLevel:0 + destinationOrigin:MTLOriginMake(0, 0, 0)]; + + [blitcmd endEncoding]; + + rect->x = 0; + rect->y = 0; + + return stagingtex; +} +#endif // SDL_PLATFORM_VISIONOS + static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect) { @autoreleasepool { SDL3METAL_RenderData *data = (__bridge SDL3METAL_RenderData *)renderer->internal; id mtltexture; MTLRegion mtlregion; + SDL_Rect read_rect = *rect; Uint32 format; SDL_Surface *surface; @@ -1951,6 +2011,15 @@ static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec } #endif +#ifdef SDL_PLATFORM_VISIONOS + if (!renderer->target && data.mtlrealitykittexture) { + mtltexture = METAL_CopyToStagingTexture(renderer, mtltexture, &read_rect); + if (mtltexture == nil) { + return NULL; + } + } +#endif + /* Commit the current command buffer and wait until it's completed, to make * sure the GPU has finished rendering to it by the time we read it. */ [data.mtlcmdbuffer commit]; @@ -1958,7 +2027,7 @@ static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec data.mtlcmdencoder = nil; data.mtlcmdbuffer = nil; - mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h); + mtlregion = MTLRegionMake2D(read_rect.x, read_rect.y, read_rect.w, read_rect.h); switch (mtltexture.pixelFormat) { case MTLPixelFormatBGRA8Unorm: @@ -1991,9 +2060,16 @@ static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec SDL_SetError("Unknown framebuffer pixel format"); return NULL; } - surface = SDL_CreateSurface(rect->w, rect->h, format); + surface = SDL_CreateSurface(read_rect.w, read_rect.h, format); if (surface) { [mtltexture getBytes:surface->pixels bytesPerRow:surface->pitch fromRegion:mtlregion mipmapLevel:0]; + if (SDL_RenderingLinearSpace(renderer) && + (!SDL_ISPIXELFORMAT_10BIT(format) && !SDL_ISPIXELFORMAT_FLOAT(format))) { + if (!SDL_ConvertPixelsAndColorspace(surface->w, surface->h, format, SDL_COLORSPACE_SRGB_LINEAR, 0, surface->pixels, surface->pitch, format, SDL_COLORSPACE_SRGB, 0, surface->pixels, surface->pitch)) { + SDL_DestroySurface(surface); + return NULL; + } + } } return surface; } @@ -2022,8 +2098,22 @@ static bool METAL_RenderPresent(SDL_Renderer *renderer) // If we don't have a drawable to present, don't try to present it. // But we'll still try to commit the command buffer in case it was already enqueued. if (ready) { - SDL_assert(data.mtlbackbuffer != nil); - [data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer]; +#ifdef SDL_PLATFORM_VISIONOS + if (data.mtlrealitykittexture) { + // Generate mipmaps + id blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; + + [blitcmd generateMipmapsForTexture:data.mtlrealitykittexture]; + [blitcmd endEncoding]; + + data.mtlrealitykittexture = nil; + } + else +#endif + { + SDL_assert(data.mtlbackbuffer != nil); + [data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer]; + } } [data.mtlcmdbuffer commit]; @@ -2057,6 +2147,11 @@ static void METAL_DestroyRenderer(SDL_Renderer *renderer) [data.mtlcmdencoder endEncoding]; } + if (data.mtlcmdbuffer != nil) { + [data.mtlcmdbuffer commit]; + [data.mtlcmdbuffer waitUntilCompleted]; + } + DestroyAllPipelines(data.allpipelines, data.pipelinescount); /* Release the metal view instead of destroying it, diff --git a/src/video/uikit/SDL_CurvedContentHosting.swift b/src/video/uikit/SDL_CurvedContentHosting.swift new file mode 100644 index 0000000000..d88b43680e --- /dev/null +++ b/src/video/uikit/SDL_CurvedContentHosting.swift @@ -0,0 +1,410 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ +import SwiftUI +import RealityKit +import Metal + +// Icons used by buttons below + +// Flat button +/* SVG: + + + + */ +struct FlatButtonIcon : Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + let width = rect.size.width + let height = rect.size.height + var strokePath = Path() + strokePath.move(to: CGPoint(x: 0.16667*width, y: 0.5*height)) + strokePath.addLine(to: CGPoint(x: 0.83333*width, y: 0.5*height)) + path.addPath(strokePath.strokedPath(StrokeStyle(lineWidth: 0.08333*width, lineCap: .round, lineJoin: .round, miterLimit: 4))) + return path + } +} + +// Curved button +/* SVG: + + + + */ +struct CurvedButtonIcon : Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + let width = rect.size.width + let height = rect.size.height + var strokePath = Path() + strokePath.move(to: CGPoint(x: 0.16625*width, y: 0.475*height)) + strokePath.addCurve(to: CGPoint(x: 0.83375*width, y: 0.475*height), control1: CGPoint(x: 0.38875*width, y: 0.39667*height), control2: CGPoint(x: 0.61125*width, y: 0.39667*height)) + path.addPath(strokePath.strokedPath(StrokeStyle(lineWidth: 0.08333*width, lineCap: .round, lineJoin: .round, miterLimit: 4))) + return path + } +} + +// Curviest button +/* SVG: + + + + */ +struct CurviestButtonIcon : Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + let width = rect.size.width + let height = rect.size.height + var strokePath = Path() + strokePath.move(to: CGPoint(x: 0.16625*width, y: 0.4625*height)) + strokePath.addCurve(to: CGPoint(x: 0.8325*width, y: 0.4625*height), control1: CGPoint(x: 0.38833*width, y: 0.2875*height), control2: CGPoint(x: 0.61042*width, y: 0.2875*height)) + path.addPath(strokePath.strokedPath(StrokeStyle(lineWidth: 0.08333*width, lineCap: .round, lineJoin: .round, miterLimit: 4))) + return path + } +} + +/// UIHostingController subclass that hides the visionOS glass background. +internal class SDL_ClearHostingController: UIHostingController { + override var preferredContainerBackgroundStyle: UIContainerBackgroundStyle { + return .hidden + } +} + +/// ObjC-accessible wrapper that manages presenting SDL curved content +/// via a UIHostingController +@MainActor +@objc(SDL_CurvedContentHosting) +internal class SDL_CurvedContentHosting: NSObject { + private let settings = SDL_CurvedContentSettings() + + private let helper = SDL_RealityKitHelper() + + private var hostingController: SDL_ClearHostingController? + + @objc public override init() { + //NSLog("SDL_CurvedContentHosting init") + super.init() + } + + /// Present the curved content view full-screen from the given view controller. + /// Uses two-phase presentation: first bootstraps the RealityView as a hidden + /// child VC, then presents modally (without animation) once content is ready. + /// Modal presentation is required on visionOS to get an independent depth budget + /// that doesn't clip curved mesh content extending forward from the window. + @objc public func present(from viewController: UIViewController) { + let contentView = SDL_CurvedContentView(helper: helper, settings: settings, onContentReady: { [weak self] in + guard let self, let hc = self.hostingController else { return } + + hc.willMove(toParent: nil) + hc.view.removeFromSuperview() + hc.removeFromParent() + hc.view.layer.opacity = 1 + + //NSLog("SDL_CurvedContentHosting: RealityView content ready - presenting modally") + viewController.present(hc, animated: false) { [weak self] in + self?.updateOrnaments() + } + }) + + // Spin up an async task to present / dismiss ornaments when there are updates to the scene state. + let settings = self.settings + let sceneStateObservations = Observations { [weak settings] in + guard let settings else { return nil as (SDL_CurvedContentSettings.SceneState, SDL_CurvedContentSettings.InputType, Bool, Bool)? } + return (settings.sceneState, settings.inputType, settings.isSnapped, settings.settingsExpanded) + } + Task { [weak self] in + for await _ in sceneStateObservations { + guard let self else { return } + self.updateOrnaments() + } + } + + let hc = SDL_ClearHostingController(rootView: contentView) + hc.modalPresentationStyle = .fullScreen + hc.view.backgroundColor = .clear + hostingController = hc + + hc.view.layer.opacity = 0 + viewController.addChild(hc) + hc.view.frame = viewController.view.bounds + viewController.view.addSubview(hc.view) + hc.didMove(toParent: viewController) + + //NSLog("SDL_CurvedContentHosting: Bootstrapping RealityView as hidden child") + } + + private func updateOrnaments() { + guard let hostingController else { return } + let settings = self.settings + let sceneState = settings.sceneState + UIView.animate(withDuration: 0.0) { + if sceneState == .interactive { + var sceneAnchor: UnitPoint + var contentAlignment: Alignment + if settings.isSnapped { + if settings.settingsExpanded { + sceneAnchor = .bottom + contentAlignment = .center + } else { + sceneAnchor = .bottom + contentAlignment = .top + } + } else { + if settings.settingsExpanded { + sceneAnchor = .leading + contentAlignment = .center + } else { + sceneAnchor = .leading + contentAlignment = .trailing + } + } + hostingController.ornaments = [ + UIHostingOrnament(sceneAnchor: sceneAnchor, contentAlignment: contentAlignment) { + SDL_SettingsPanelView(settings: settings) + } + ] + } else { + hostingController.ornaments = [] + } + } + } + + /// Get the display texture for this frame. + @objc public func getDisplayTexture(_ commandBuffer: MTLCommandBuffer, width: Int, height: Int, pixelFormat: MTLPixelFormat) -> MTLTexture? { + return helper.getDisplayTexture(commandBuffer, width: width, height: height, pixelFormat: pixelFormat) + } +} + +// MARK: - Settings Panel + +@Observable +internal class SDL_CurvedContentSettings { + /// State of the app user interface, determined by the content view's state. + enum SceneState { + /// A state which allows the user to configure the scene. Ornaments should be visible. + case interactive + + /// A state which hides all UI except for the game itself. Ornaments should not be visible. + case cinematic + } + + enum InputType { + case eyes + case pointer + } + + var inputType: InputType = .eyes + var showHover: Bool = true + var isDimmed: Bool = false + var curvatureRadius: Float = SDL_VisionOS_GetCurvature() + var sceneState: SceneState = .interactive + var isSnapped: Bool = false + var settingsExpanded: Bool = false +} + +struct SDL_SettingsPanelView: View { + let settings: SDL_CurvedContentSettings + @State private var curvatureSlider: Float = 0.0 + + static let minimumCurvatureRadius: Float = 800.0 + static let maximumCurvatureRadius: Float = 4500.0 + + static let curvatureSteps: [Float] = [ + 0, + 4000, + 3000, + 2300, + 1800, + 1500, + 1000, + 800 + ] + + static let curvatureStepsSliderValue: [Float] = curvatureSteps.map { + if $0 <= 0.01 { + return 0 // flat + } + return 1.0 - ($0 - minimumCurvatureRadius) / (maximumCurvatureRadius - minimumCurvatureRadius) + } + + private var curvatureLabel: String { + if settings.curvatureRadius > 0 { + return "\(Int(settings.curvatureRadius))R" + } else { + return "" + } + } + + var body: some View { + if settings.settingsExpanded { + expandedPanel + } else { + collapsedBar + } + } + + // MARK: Collapsed + + private var collapsedBar: some View { + Button(action: { withAnimation { settings.settingsExpanded = true } }) { + if settings.isSnapped { + HStack(spacing: 12) { + Image(systemName: settings.showHover ? "eye" : "eye.slash") + + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) + + Divider().frame(height: 8) + + if settings.curvatureRadius == 0 { + FlatButtonIcon() + .frame(width: 24, height: 24) + } else if settings.curvatureRadius > 1000.0 { + CurvedButtonIcon() + .frame(width: 24, height: 24) + } else { + CurviestButtonIcon() + .frame(width: 24, height: 24) + } + } + .padding(.horizontal, 16) + .padding(.vertical, 16) + } else { + VStack(spacing: 12) { + Image(systemName: settings.showHover ? "eye" : "eye.slash") + + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) + + Divider().frame(height: 8) + + if settings.curvatureRadius == 0 { + FlatButtonIcon() + .frame(width: 24, height: 24) + } else if settings.curvatureRadius > 1000.0 { + CurvedButtonIcon() + .frame(width: 24, height: 24) + } else { + CurviestButtonIcon() + .frame(width: 24, height: 24) + } + } + .padding(.horizontal, 16) + .padding(.vertical, 16) + } + } + .buttonStyle(.plain) + .glassBackgroundEffect() + } + + // MARK: Expanded + + private var expandedPanel: some View { + VStack(spacing: 16) { + // Input type and dim controls + @Bindable var settings = self.settings + + Text("").font(.title).padding(8) + + HStack() { + Spacer() + Image(systemName: "eye.slash") + + Toggle(isOn: $settings.showHover) { + } + .labelsHidden() + .tint(.secondary) + + Image(systemName: "eye") + Spacer() + + Spacer() + Image(systemName: "sun.max") + + Toggle(isOn: $settings.isDimmed) { + } + .labelsHidden() + .tint(.secondary) + + Image(systemName: "moon.fill") + Spacer() + } + + // Curvature slider + VStack(spacing: 4) { + Text("\(curvatureLabel)") + .font(.caption) + + HStack() { + FlatButtonIcon() + .frame(width: 24, height: 24) + + Slider(value: $curvatureSlider, in: 0...1) { + } currentValueLabel: { + Text("\(curvatureLabel)") + } ticks: { + SliderTickContentForEach(Self.curvatureStepsSliderValue, id: \.self) { value in + SliderTick(value) + } + } + .onAppear { + let curvature = settings.curvatureRadius + if curvature > 0 { + curvatureSlider = 1.0 - (curvature - Self.minimumCurvatureRadius) + / (Self.maximumCurvatureRadius - Self.minimumCurvatureRadius) + } else { + curvatureSlider = 0.0 + } + } + .onChange(of: curvatureSlider) { + let clamped = max(0.0, min(1.0, curvatureSlider)) + if clamped == 0 { + settings.curvatureRadius = 0 + } else { + let radius = roundf(curvatureSlider * Self.minimumCurvatureRadius + + (1.0 - curvatureSlider) * Self.maximumCurvatureRadius) + settings.curvatureRadius = radius + } + SDL_VisionOS_SendCurvatureChanged(settings.curvatureRadius) + } + + CurviestButtonIcon() + .frame(width: 24, height: 24) + } + } + } + .padding(20) + .frame(width: 340) + .overlay(alignment: .topLeading) { + // X button + Button(action: { withAnimation { settings.settingsExpanded = false } }) { + Image(systemName: "xmark") + .font(.system(size: 15, weight: .bold, design: .rounded)) + .padding(8) + .contentShape(Circle()) + } + .buttonStyle(.bordered) + .buttonBorderShape(.circle) + .padding(20) + } + .glassBackgroundEffect() + } +} diff --git a/src/video/uikit/SDL_CurvedContentView.swift b/src/video/uikit/SDL_CurvedContentView.swift new file mode 100644 index 0000000000..36317e71db --- /dev/null +++ b/src/video/uikit/SDL_CurvedContentView.swift @@ -0,0 +1,350 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ +import SwiftUI +import RealityKit +import GameController + +/// SwiftUI view that presents SDL content on a curved RealityKit mesh +/// inside a UIHostingController +internal struct SDL_CurvedContentView: View { + /// Helper object used to manage the mesh and texture of the curved UI. + let helper: SDL_RealityKitHelper + + /// Settings object provided by the caller which determines the UI state. + let settings: SDL_CurvedContentSettings + + /// Information about the window snap status + @Environment(\.surfaceSnappingInfo) private var snappedStatus + + /// Closure which is called when the content is ready to present. + let onContentReady: @MainActor () -> Void + + /// RealityKit entity which is created on appear, to be populated by the curved UI content. + @State private var curvedUIEntity: ModelEntity! = nil + + /// Curved UI material which is created on appear. Holds the compiled shader and material parameters. + @State private var curvedUIMaterial: CurvedUIMaterial! = nil + + /// Converts SwiftUI points to meters (RealityKit coordinates) + /// + /// - Note: This conversion varies depending on the physical distance between the window and the user. + @PhysicalMetric(from: .meters) private var pointsPerMeter: Float = 1 + + /// Inverse of ``pointsPerMeter``. + var metersPerPoint: Float { 1.0 / pointsPerMeter } + + /// The cursor color which should be passed to `curvedUIMaterial` + @State private var cursorColor: UIColor = .lightGray + + /// The cursor color on interact (pinch/drag/click) which should be passed to `curvedUIMaterial` + @State private var cursorColorOnInteract: UIColor = .systemCyan + + /// Whether to show the cursor overlay on the mesh surface. + private var showCursor: Bool { + return !mouseInputEnabled && settings.showHover + } + + /// Whether mouse input is enabled. When this is the case, the collision shape for indirect input should be disabled. + private var mouseInputEnabled: Bool { + return settings.inputType == .pointer + } + + private var shouldPopulateCollisionShape: Bool { + return curvedUIEntity != nil && helper.collisionShape != nil && !mouseInputEnabled + } + + /// Value use to animate the screen radius + @State private var animatedScreenRadius: Float = 1010 + + let SDL_EVENT_FINGER_DOWN: UInt32 = 0x700 + let SDL_EVENT_FINGER_UP: UInt32 = 0x701 + let SDL_EVENT_FINGER_MOTION: UInt32 = 0x702 + let SDL_EVENT_FINGER_CANCELED: UInt32 = 0x703 + private(set) static var last_fingerID: UInt64 = 0 + private(set) static var fingers: [SpatialEventCollection.Event.ID: UInt64] = [:] + + private func sendTouchEvent(event: SpatialEventCollection.Event, proxy: GeometryProxy3D) { + var fingerID: UInt64 + var eventType: UInt32 + if let value = Self.fingers[event.id] { + fingerID = value + if event.phase == SpatialEventCollection.Event.Phase.active { + eventType = SDL_EVENT_FINGER_MOTION + } else if event.phase == SpatialEventCollection.Event.Phase.ended { + eventType = SDL_EVENT_FINGER_UP + Self.fingers.removeValue(forKey: event.id) + } else { + eventType = SDL_EVENT_FINGER_CANCELED + Self.fingers.removeValue(forKey: event.id) + } + } else if event.phase == SpatialEventCollection.Event.Phase.active { + Self.last_fingerID += 1 + fingerID = Self.last_fingerID + Self.fingers[event.id] = fingerID + eventType = SDL_EVENT_FINGER_DOWN + } else { + return + } + + let loc = Point3D(x: event.location3D.x - proxy.size.width / 2, + y: event.location3D.y - proxy.size.height / 2, + z: event.location3D.z - proxy.size.depth / 2) + let meshPos = SIMD3(Float(loc.x) * metersPerPoint, + Float(loc.y) * metersPerPoint, + Float(loc.z) * metersPerPoint) + let uv = helper.meshGeometry.normalizedUV(fromMeshPosition: meshPos) + + SDL_VisionOS_SendTouch(event.timestamp, fingerID, eventType, uv.x, uv.y) + } + + var body: some View { + GeometryReader3D { proxy in + realityContent(proxy) + .glassBackgroundEffect(displayMode: .never) + } + } + + private func realityContent(_ proxy: GeometryProxy3D) -> some View { + RealityView { content in + //NSLog("SDL_CurvedContentView: RealityView setup") + + let frameInMeters: BoundingBox = content.convert(proxy.frame(in: .local), from: .local, to: .scene) + helper.updateMeshSize(width: frameInMeters.extents.x, height: frameInMeters.extents.y) + + // Compile curved UI shader (may take a while) + let material = try! await CurvedUIMaterial() + self.curvedUIMaterial = material + + // Create RealityKit Entity to host the curved UI content + let mesh = try! await MeshResource(from: helper.lowLevelMesh) + let entity = ModelEntity(mesh: mesh, materials: [material.shaderGraphMaterial]) + + // Add InputTargetComponent to the mesh to accept input. + entity.components.set(InputTargetComponent(allowedInputTypes: .all)) + + // Add HoverEffectComponent to visualize the gaze target + let shaderInputs = HoverEffectComponent.ShaderHoverEffectInputs.default + let hoverEffect = HoverEffectComponent.HoverEffect.shader(shaderInputs) + let hoverEffectComponent = HoverEffectComponent(hoverEffect) + entity.components.set(hoverEffectComponent) + + // Increase the responsiveness of the hover effect + RenderRefreshSystem.registerSystem() + entity.components.set(RenderRefreshComponent( + componentToRefresh: hoverEffectComponent + )) + + self.curvedUIEntity = entity + content.add(entity) + + // Call the user-provided contentReady closure. + onContentReady() + } update: { content in + let frameInMeters: BoundingBox = content.convert(proxy.frame(in: .local), from: .local, to: .scene) + helper.updateMeshSize(width: frameInMeters.extents.x, height: frameInMeters.extents.y) + + let frame = proxy.frame(in: .local) + SDL_VisionOS_SendSizeChanged(Int(frame.size.width), Int(frame.size.height)) + } + .overlay { + if mouseInputEnabled { + // This enables mouse motion events, but blocks hover location + Color.white + .opacity(0.001) + .pointerStyle(.shape(Circle(), size: .zero)) + } + } + .gesture( + SpatialEventGesture() + .onChanged { events in + guard curvedUIMaterial != nil else { return } + + if !mouseInputEnabled { + curvedUIMaterial.isInteracting = true + + for event in events { + if event.kind != .pointer { + sendTouchEvent(event: event, proxy: proxy) + } else { + settings.inputType = .pointer + settings.sceneState = .cinematic + } + } + } + } + .onEnded { events in + guard curvedUIMaterial != nil else { return } + + if !mouseInputEnabled { + for event in events { + if event.kind != .pointer { + sendTouchEvent(event: event, proxy: proxy) + } + } + } else { + for event in events { + if event.kind != .pointer { + settings.inputType = .eyes + settings.sceneState = .interactive + } + } + } + + curvedUIMaterial.isInteracting = false + } + ) + .onChange(of: sceneActivationOrObject(showCursor), initial: true) { + curvedUIMaterial?.showCursor = showCursor + } + .onChange(of: sceneActivationOrObject(cursorColor), initial: true) { + curvedUIMaterial?.cursorColor = cursorColor + } + .onChange(of: sceneActivationOrObject(cursorColorOnInteract), initial: true) { + curvedUIMaterial?.cursorColorOnInteract = cursorColorOnInteract + } + .onChange(of: sceneActivationOrObject(helper.meshGeometry), initial: true) { + guard curvedUIMaterial != nil else { return } + let geometry = helper.meshGeometry + curvedUIMaterial.cursorSize = geometry.height * 0.01 + } + .onChange(of: sceneActivationOrObject(helper.textureResource), initial: true) { + if let textureResource = helper.textureResource { + curvedUIMaterial?.gameTexture = textureResource + } + } + .onChange(of: sceneActivationOrObject(curvedUIMaterial), initial: true) { + // Update the materials array of the entity with the updated material parameters. + if let curvedUIMaterial, let curvedUIEntity { + curvedUIEntity.model!.materials = [curvedUIMaterial.shaderGraphMaterial] + } + } + .onChange(of: settings.inputType, initial: true) { oldInputType, inputType in + if inputType == .pointer { + SDL_VisionOS_SendPointerMode(true) + } else { + SDL_VisionOS_SendPointerMode(false) + } + } + .onChange(of: settings.curvatureRadius, initial: true) { oldRadius, curvatureRadius in + if oldRadius != curvatureRadius { + withAnimation(.smooth) { + if curvatureRadius > 0 { + animatedScreenRadius = curvatureRadius / 1000 + } else { + animatedScreenRadius = AnimatedCurveRadiusModifier.assumedFlatThreshold + 0.01 + } + } + } else { + if curvatureRadius > 0 { + animatedScreenRadius = curvatureRadius / 1000 + } else { + animatedScreenRadius = AnimatedCurveRadiusModifier.assumedFlatThreshold + 0.01 + } + } + } + .modifier(AnimatedCurveRadiusModifier(helper: helper, curveRadius: animatedScreenRadius)) + .onChange(of: sceneActivationOrObject(shouldPopulateCollisionShape ? helper.collisionShape : nil)) { + guard let curvedUIEntity else { return } + if let shape = helper.collisionShape, shouldPopulateCollisionShape { + curvedUIEntity.components.set(CollisionComponent(shapes: [shape])) + } else { + curvedUIEntity.components.set(CollisionComponent(shapes: [])) + } + } + .onChange(of: snappedStatus) { + settings.isSnapped = snappedStatus.isSnapped + helper.updateSnappedStatus(snapped: snappedStatus.isSnapped) + } + .preferredSurroundingsEffect(settings.isDimmed ? .dark : nil) + .frame(depth: 0) + .ignoresSafeArea() + .persistentSystemOverlays(settings.sceneState == .cinematic ? .hidden : .automatic) + .handlesGameControllerEvents(matching: .gamepad) + } +} + +// MARK: Animating the curve radius + +@Animatable +private struct AnimatedCurveRadiusModifier: @MainActor ViewModifier { + /// Curvature radius beyond which we assume it is flat. + static let assumedFlatThreshold: Float = 30.0 + + /// Helper object to modify + let helper: SDL_RealityKitHelper + + /// Curve radius > `assumedFlatThreshold` meters is assumed to be flat. + var curveRadius: Float + + func body(content: Content) -> some View { + content.onChange(of: curveRadius, initial: true) { + if curveRadius > 10 { + helper.updateMeshCurvature(curvatureRadius: 0) + } else { + helper.updateMeshCurvature(curvatureRadius: curveRadius) + } + } + } +} + +// MARK: Bridging SwiftUI and RealityKit + +private extension SDL_CurvedContentView { + private struct Box: Equatable { + var sceneActivation: Bool + var value: T + } + + /// Convenience function which triggers an `onChange` event either when `object` changes, or when + /// ``curvedUIMaterial`` finishes compiling. + func sceneActivationOrObject(_ object: T) -> some Equatable { + return Box(sceneActivation: self.curvedUIMaterial != nil && self.curvedUIEntity != nil, value: object) + } +} + +// MARK: Per-frame component refresh + +/// Attach this component to an entity to reset a RealityKit component every rendering frame. +/// This can be used to disable system-default interpolation on any component that applies it. +/// +/// Example — to reset a platform-specific component every frame: +/// entity.components.set(RenderRefreshComponent( +/// componentToRefresh: CustomComponent() +/// )) +private struct RenderRefreshComponent: TransientComponent { + var componentToRefresh: (any Component)? +} + +private struct RenderRefreshSystem: System { + static let query = EntityQuery(where: .has(RenderRefreshComponent.self)) + init(scene: RealityKit.Scene) { + RenderRefreshComponent.registerComponent() + } + + func update(context: SceneUpdateContext) { + for entity in context.entities(matching: Self.query, updatingSystemWhen: .rendering) { + guard let refresh = entity.components[RenderRefreshComponent.self], + let component = refresh.componentToRefresh else { continue } + entity.components.remove(type(of: component)) + entity.components.set(component) + } + } +} diff --git a/src/video/uikit/SDL_CurvedUIShader.swift b/src/video/uikit/SDL_CurvedUIShader.swift new file mode 100644 index 0000000000..a25ebbae66 --- /dev/null +++ b/src/video/uikit/SDL_CurvedUIShader.swift @@ -0,0 +1,544 @@ +// +// SDL_CurvedUIShader.swift +// SDL3 +// +// Created by Adrian Biagioli on 4/21/26. +// + +import Foundation +import RealityKit + +/// A MaterialX curved UI shader USDA. This is loaded on launch into a ShaderGraphMaterial. +/// +/// You can inspect this shader yourself in Reality Composer Pro. +/// To do this, copy this string and save it as a .usda file. +/// Then, add it to a Reality Composer Pro object. +private let curvedUIShaderUSDA = """ +#usda 1.0 +( + customLayerData = { + string creator = "Reality Composer Pro Version 2.0 (494.100.6)" + } + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) + +def Xform "Root" +{ + def Material "CurvedUIMaterial" + { + reorder nameChildren = ["DefaultSurfaceShader", "UnlitSurface", "TextureCoordinates", "Position", "Image2D", "Group2", "Group4", "CursorPositionOnScreen", "SelectCursorColor", "SelectCursorOpacity", "GameTextureRGB", "NormalizedDistance", "Dot", "Group", "Dot_1", "DiscardCursorOutsideRange", "MixCursorOverGame", "HideCursorIfDisabled"] + color3f inputs:CursorColor = (0, 0.87658346, 1) ( + colorSpace = "lin_srgb" + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-374.2671, 402.7502) + int stackingOrderInSubgraph = 1955 + } + } + ) + color3f inputs:CursorColorOnInteract = (0.016926037, 0, 0.7703071) ( + colorSpace = "lin_srgb" + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-408.82837, 336.09396) + int stackingOrderInSubgraph = 2017 + } + } + ) + float inputs:CursorEdgeThreshold = 0.9 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-706.12756, 582.3273) + int stackingOrderInSubgraph = 1951 + } + } + ) + float inputs:CursorOpacityEdge = 0.7 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-704.3221, 648.0528) + int stackingOrderInSubgraph = 1953 + } + } + ) + float inputs:CursorOpacityInside = 0.4 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-701.167, 710.96765) + int stackingOrderInSubgraph = 1955 + } + } + ) + float inputs:CursorSize = 0.003 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-1204.8192, 509.2949) + int stackingOrderInSubgraph = 2015 + } + } + ) + asset inputs:GameTexture ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-1270.7656, -315.35458) + int stackingOrderInSubgraph = 1834 + } + } + ) + bool inputs:IsInteracting = 0 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-373.38513, 263.61777) + int stackingOrderInSubgraph = 1955 + } + } + ) + bool inputs:ShowCursor = 1 ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (-1721.0664, 367.89142) + int stackingOrderInSubgraph = 2360 + } + } + ) + token outputs:mtlx:surface.connect = + token outputs:realitykit:vertex + token outputs:surface.connect = + float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (612.1894, 109.99387) + int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 1993 + + def Shader "DefaultSurfaceShader" ( + active = false + ) + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 1, 1) + float inputs:roughness = 0.75 + token outputs:surface + } + + def Shader "UnlitSurface" + { + uniform token info:id = "ND_realitykit_unlit_surfaceshader" + bool inputs:applyPostProcessToneMap = 0 + color3f inputs:color.connect = + bool inputs:hasPremultipliedAlpha + float inputs:opacity + float inputs:opacityThreshold + token outputs:out + float2 ui:nodegraph:node:pos = (368.7634, 58.4275) + int ui:nodegraph:node:stackingOrder = 1993 + } + + def Shader "TextureCoordinates" + { + uniform token info:id = "ND_texcoord_vector2" + float2 outputs:out + float2 ui:nodegraph:node:pos = (-1292.3005, -120.02362) + int ui:nodegraph:node:stackingOrder = 1834 + } + + def Shader "Position" + { + uniform token info:id = "ND_position_vector3" + string inputs:space = "world" + float3 outputs:out + float2 ui:nodegraph:node:pos = (-1205.6492, 445.2142) + int ui:nodegraph:node:stackingOrder = 2314 + } + + def Shader "Image2D" + { + uniform token info:id = "ND_RealityKitTexture2D_color4" + float inputs:bias + string inputs:border_color + float inputs:dynamic_min_lod_clamp + asset inputs:file.connect = + bool inputs:no_flip_v = 1 + int2 inputs:offset + float2 inputs:texcoord.connect = + string inputs:u_wrap_mode + string inputs:v_wrap_mode + color4f outputs:out + float2 ui:nodegraph:node:pos = (-1023.8389, -194.1174) + int ui:nodegraph:node:stackingOrder = 1834 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:no_flip_v"] + } + + def Scope "Group2" ( + kind = "group" + ) + { + string ui:group:annotation = "Apply final color to UnlitMaterial" + string ui:group:annotationDescription = "" + string[] ui:group:members = ["p:UnlitSurface", "o:_subgraphOutput"] + } + + def Scope "Group4" ( + kind = "group" + ) + { + string ui:group:annotation = "Sample game texture" + string ui:group:annotationDescription = "" + string[] ui:group:members = ["i:inputs:GameTexture", "p:Image2D", "p:TextureCoordinates"] + } + + def Shader "SelectCursorColor" + { + uniform token info:id = "ND_ifequal_color3B" + color3f inputs:in1.connect = + color3f inputs:in2.connect = + bool inputs:value1.connect = + bool inputs:value2 = 1 + color3f outputs:out + float2 ui:nodegraph:node:pos = (-175.6293, 330.2353) + int ui:nodegraph:node:stackingOrder = 1955 + } + + def Shader "SelectCursorOpacity" + { + uniform token info:id = "ND_ifgreater_float" + float inputs:in1.connect = + float inputs:in2.connect = + float inputs:value1.connect = + float inputs:value2.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (-463.96164, 578.08826) + int ui:nodegraph:node:stackingOrder = 1853 + } + + def Shader "GameTextureRGB" + { + uniform token info:id = "ND_swizzle_color4_color3" + string inputs:channels = "rgb" + color4f inputs:in.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (-732.1035, -11.733684) + int ui:nodegraph:node:stackingOrder = 1834 + } + + def NodeGraph "NormalizedDistance" + { + float3 inputs:A ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (79.30469, 187.10547) + int stackingOrderInSubgraph = 1406 + } + } + ) + float3 inputs:A.connect = + float3 inputs:B ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (79.234375, 270.22266) + int stackingOrderInSubgraph = 1408 + } + } + ) + float3 inputs:B.connect = + float inputs:Radius ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (306.85156, 333.83984) + int stackingOrderInSubgraph = 1406 + } + } + ) + float inputs:Radius.connect = + float outputs:ZeroToOneDistance ( + customData = { + dictionary realitykit = { + float2 positionInSubgraph = (444.625, 223) + int stackingOrderInSubgraph = 1409 + } + } + ) + float outputs:ZeroToOneDistance.connect = + float2 ui:nodegraph:node:pos = (-998.9227, 417.7417) + int ui:nodegraph:node:stackingOrder = 2010 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["outputs:Clamp_out", "inputs:A"] + float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (711.2656, 366.07812) + int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 1409 + + def Shader "Remap" + { + uniform token info:id = "ND_remap_float" + float inputs:in.connect = + float inputs:inhigh.connect = + float inputs:inlow = 0 + float inputs:outhigh = 1 + float inputs:outlow = 0 + float outputs:out + float2 ui:nodegraph:node:pos = (503, 318.58984) + int ui:nodegraph:node:stackingOrder = 1407 + } + + def Shader "MTLDistance" + { + uniform token info:id = "ND_MTL_distance_vector3_float" + float3 inputs:x.connect = + float3 inputs:y.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (304, 186.67969) + int ui:nodegraph:node:stackingOrder = 1402 + } + } + + def Shader "Dot" + { + uniform token info:id = "ND_dot_float" + float inputs:in.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (-626.7584, 475.93542) + int ui:nodegraph:node:stackingOrder = 1735 + } + + def Scope "Group" ( + kind = "group" + ) + { + string ui:group:annotation = "Select cursor color and opacity" + string ui:group:annotationDescription = "The color is selected depending if the user is interacting (click/tap/pinch/drag). The opacity is selected via the distance between this fragment's position and the cursor position" + string[] ui:group:members = ["i:inputs:IsInteracting", "p:Dot_1", "p:DiscardCursorOutsideRange", "i:inputs:CursorColorOnInteract", "p:SelectCursorColor", "i:inputs:CursorColor", "p:Dot", "i:inputs:CursorOpacityEdge", "i:inputs:CursorOpacityInside", "p:SelectCursorOpacity", "i:inputs:CursorEdgeThreshold"] + } + + def Shader "Dot_1" + { + uniform token info:id = "ND_dot_float" + float inputs:in.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (-370.1385, 475.2281) + int ui:nodegraph:node:stackingOrder = 1851 + } + + def Shader "DiscardCursorOutsideRange" + { + uniform token info:id = "ND_ifgreater_float" + float inputs:in1 = 0 + float inputs:in2.connect = + float inputs:value1.connect = + float inputs:value2 = 1 + float outputs:out + float2 ui:nodegraph:node:pos = (-192.05971, 600.1504) + int ui:nodegraph:node:stackingOrder = 1966 + } + + def Shader "MixCursorOverGame" + { + uniform token info:id = "ND_mix_color3" + color3f inputs:bg.connect = + color3f inputs:fg.connect = + float inputs:mix.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (90.70218, -17.587646) + int ui:nodegraph:node:stackingOrder = 1973 + } + + def Shader "HideCursorIfDisabled" + { + uniform token info:id = "ND_ifequal_vector3B" + float3 inputs:in1.connect = + float3 inputs:in2 = (999999, 999999, 999999) + bool inputs:value1.connect = + bool inputs:value2 = 1 + bool inputs:value2.connect = None + float3 outputs:out + float2 ui:nodegraph:node:pos = (-1281.8472, 322.0585) + int ui:nodegraph:node:stackingOrder = 2361 + } + + def Shader "HoverState" + { + uniform token info:id = "ND_realitykit_hover_state" + float outputs:intensity + bool outputs:isActive + float3 outputs:position + float outputs:timeSinceHoverStart + float2 ui:nodegraph:node:pos = (-1730.769, 258.70575) + int ui:nodegraph:node:stackingOrder = 2360 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["outputs:position"] + } + + def Shader "And" + { + uniform token info:id = "ND_realitykit_logical_and" + bool inputs:in1.connect = + bool inputs:in2.connect = + bool outputs:out + float2 ui:nodegraph:node:pos = (-1571.7467, 334.56076) + int ui:nodegraph:node:stackingOrder = 2360 + } + } +} + +""" + +/// A wrapper object around a RealityKit `ShaderGraphMaterial`, but specific to the SDL curved UI shader. +/// +/// This struct provides material parameters that pass through to the `ShaderGraphMaterial`. +@MainActor +struct CurvedUIMaterial: @MainActor Equatable { + /// A cached ShaderGraphMaterial, populated with a prototype ShaderGraphMaterial. + /// + /// On subsequent loads, the alread-loaded material is used directly. + @MainActor private static var cachedShaderGraph: ShaderGraphMaterial? + + /// The ShaderGraphMaterial which should be used to populate the curved UI Entity's `ModelComponent`. + /// + /// - Note: ShaderGraphMaterial is a value type (`struct`), so you must re-query this value after changing any parameters. + private(set) var shaderGraphMaterial: ShaderGraphMaterial + + /// Initializes the curved UI material. + /// + /// If the shader needs to compile (first launch), then it compiles before returning. + /// If the shader is already compiled, returns immediately. + @MainActor + init() async throws { + if let cachedShaderGraph = Self.cachedShaderGraph { + self.shaderGraphMaterial = cachedShaderGraph + } else { + let result = try await ShaderGraphMaterial( + named: "/Root/CurvedUIMaterial", + from: Data(curvedUIShaderUSDA.utf8) + ) + Self.cachedShaderGraph = result + self.shaderGraphMaterial = result + } + } + + /// The texture containing SDL content. + var gameTexture: TextureResource! { + get { shaderGraphMaterial.getParameter(.gameTexture) } + set { try! shaderGraphMaterial.setParameter(.gameTexture, value: newValue) } + } + + /// Color of the cursor overlay when not actively interacting. + var cursorColor: UIColor! { + get { shaderGraphMaterial.getParameter(.cursorColor) } + set { try! shaderGraphMaterial.setParameter(.cursorColor, value: newValue) } + } + + /// Color of the cursor when interacting (click/tap/pinch/drag) + var cursorColorOnInteract: UIColor! { + get { shaderGraphMaterial.getParameter(.cursorColorOnInteract) } + set { try! shaderGraphMaterial.setParameter(.cursorColorOnInteract, value: newValue) } + } + + /// The size of the cursor in meters. + var cursorSize: Float! { + get { shaderGraphMaterial.getParameter(.cursorSize) } + set { try! shaderGraphMaterial.setParameter(.cursorSize, value: newValue) } + } + + /// Whether to show the cursor overlay on the mesh surface. + var showCursor: Bool! { + get { shaderGraphMaterial.getParameter(.showCursor) } + set { try! shaderGraphMaterial.setParameter(.showCursor, value: newValue) } + } + + /// True if the user is actively interacting with the scene (e.g. click, tap, pinch, or drag). + var isInteracting: Bool! { + get { shaderGraphMaterial.getParameter(.isInteracting) } + set { try! shaderGraphMaterial.setParameter(.isInteracting, value: newValue) } + } + + static func == (lhs: CurvedUIMaterial, rhs: CurvedUIMaterial) -> Bool { + return lhs.gameTexture == rhs.gameTexture + && lhs.cursorColor == rhs.cursorColor + && lhs.cursorColorOnInteract == rhs.cursorColorOnInteract + && lhs.cursorSize == rhs.cursorSize + && lhs.showCursor == rhs.showCursor + && lhs.isInteracting == rhs.isInteracting + } +} + +@MainActor +private extension MaterialParameters.Handle { + static let gameTexture = ShaderGraphMaterial.parameterHandle(name: "GameTexture") + static let cursorColor = ShaderGraphMaterial.parameterHandle(name: "CursorColor") + static let cursorColorOnInteract = ShaderGraphMaterial.parameterHandle(name: "CursorColorOnInteract") + static let cursorSize = ShaderGraphMaterial.parameterHandle(name: "CursorSize") + static let showCursor = ShaderGraphMaterial.parameterHandle(name: "ShowCursor") + static let isInteracting = ShaderGraphMaterial.parameterHandle(name: "IsInteracting") +} + +private extension ShaderGraphMaterial { + /// Convenience function to recover a typed shader parameter (without going through `MaterialParametres.Value` enum) + func getParameter(_ handle: MaterialParameters.Handle, type: T.Type = T.self) -> T? { + guard let value = self.getParameter(handle: handle) else { return nil } + + switch (type.self, value) { + case (is MaterialParameters.Texture.Type, .texture(let v)): return (v as! T) + case (is TextureResource.Type, .texture(let v)): return (v.resource as! T) + case (is TextureResource.Type, .textureResource(let v)): return (v as! T) + case (is Float.Type, .float(let v)): return (v as! T) + case (is SIMD2.Type, .simd2Float(let v)): return (v as! T) + case (is SIMD3.Type, .simd3Float(let v)): return (v as! T) + case (is SIMD4.Type, .simd4Float(let v)): return (v as! T) + case (is UIColor.Type, .color(let v)): fallthrough + case (is CGColor.Type, .color(let v)): + // `is CGColor` works for both UIColor and CGColor + if type == CGColor.self { + return (v as! T) + } else if type == UIColor.self { + return (UIColor(cgColor: v) as! T) + } else { + preconditionFailure("Unknown Color type \(type)") + } + case (is float2x2.Type, .float2x2(let v)): return (v as! T) + case (is float3x3.Type, .float3x3(let v)): return (v as! T) + case (is float4x4.Type, .float4x4(let v)): return (v as! T) + case (is Bool.Type, .bool(let v)): return (v as! T) + case (is Int.Type, .int(let v)): return (Int(v) as! T) + case (is Int32.Type, .int(let v)): return (v as! T) + default: + preconditionFailure("Invalid type \(type) for handle with value \(value)") + } + } + + /// Convenience function to set a typed shader parameter (without going through `MaterialParametres.Value` enum) + mutating func setParameter(_ handle: MaterialParameters.Handle, value: T!) throws { + guard let value else { preconditionFailure("can not clear a material parameter") } + switch type(of: value).self { + case is MaterialParameters.Texture.Type: + try self.setParameter(handle: handle, value: .texture(value as! MaterialParameters.Texture)) + case is TextureResource.Type: + try self.setParameter(handle: handle, value: .textureResource(value as! TextureResource)) + case is Float.Type: + try self.setParameter(handle: handle, value: .float(value as! Float)) + case is SIMD2.Type: + try self.setParameter(handle: handle, value: .simd2Float(value as! SIMD2)) + case is SIMD3.Type: + try self.setParameter(handle: handle, value: .simd3Float(value as! SIMD3)) + case is SIMD4.Type: + try self.setParameter(handle: handle, value: .simd4Float(value as! SIMD4)) + case is CGColor.Type: fallthrough + case is UIColor.Type: + // `is CGColor` works for both UIColor and CGColor + if T.self == UIColor.self { + try self.setParameter(handle: handle, value: .color(value as! UIColor)) + } else if T.self == CGColor.self { + try self.setParameter(handle: handle, value: .color(value as! CGColor)) + } else { + preconditionFailure("Unknown Color type \(type(of: value))") + } + case is float2x2.Type: + try self.setParameter(handle: handle, value: .float2x2(value as! float2x2)) + case is float3x3.Type: + try self.setParameter(handle: handle, value: .float3x3(value as! float3x3)) + case is float4x4.Type: + try self.setParameter(handle: handle, value: .float4x4(value as! float4x4)) + case is Bool.Type: + try self.setParameter(handle: handle, value: .bool(value as! Bool)) + case is Int.Type: + try self.setParameter(handle: handle, value: .int(Int32(value as! Int))) + case is Int32.Type: + try self.setParameter(handle: handle, value: .int(value as! Int32)) + default: + preconditionFailure("Invalid type \(type(of: value))") + } + } +} diff --git a/src/video/uikit/SDL_RealityKitHelper.swift b/src/video/uikit/SDL_RealityKitHelper.swift new file mode 100644 index 0000000000..424ed68bea --- /dev/null +++ b/src/video/uikit/SDL_RealityKitHelper.swift @@ -0,0 +1,396 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ +import RealityKit +import SwiftUI +import Metal +import MetalKit +import simd + +/// Custom vertex format for the curved plane mesh. +/// Matches the layout described to LowLevelMesh via vertexAttributes/vertexLayouts. +private struct CurvedPlaneVertex { + var position: SIMD3 = .zero + var normal: SIMD3 = .zero + var uv: SIMD2 = .zero + + static var vertexAttributes: [LowLevelMesh.Attribute] { + [ + .init(semantic: .position, format: .float3, offset: MemoryLayout.offset(of: \.position)!), + .init(semantic: .normal, format: .float3, offset: MemoryLayout.offset(of: \.normal)!), + .init(semantic: .uv0, format: .float2, offset: MemoryLayout.offset(of: \.uv)!) + ] + } + + static var vertexLayouts: [LowLevelMesh.Layout] { + [.init(bufferIndex: 0, bufferStride: MemoryLayout.stride)] + } + + static func descriptor(vertexCount: Int, indexCount: Int) -> LowLevelMesh.Descriptor { + var desc = LowLevelMesh.Descriptor() + desc.vertexAttributes = vertexAttributes + desc.vertexLayouts = vertexLayouts + desc.vertexCapacity = vertexCount + desc.indexCapacity = indexCount + desc.indexType = .uint32 + return desc + } +} + +/// Provides RealityKit functionality +/// +/// Key responsibilities: +/// - Generate curved mesh geometry procedurally using LowLevelMesh for fast updates +/// - Update textures using LowLevelTexture for efficient Metal → RealityKit transfer +/// - Asynchronously cooks a physics collision mesh of the curved UI to be used as an input target +@MainActor +@Observable +internal class SDL_RealityKitHelper { + /// A collision shape which should be assigned to the same entity as ``lowLevelMesh``, for input targeting. + private(set) var collisionShape: ShapeResource? = nil + + /// The TextureResource object which should be assigned to an entity in the scene. + private(set) var textureResource: TextureResource? = nil + + /// The LowLevelMesh object which should be assigned to an entity in the scene, positioned at the origin. + /// + /// This mesh is auomatically updated when you change ``meshGeometry`` via ``updateMeshGeometry()``. + /// LowLevelMesh is a class (reference type) so you can add it to your Entity's `MeshResource` once at init time. + let lowLevelMesh: LowLevelMesh + + /// Topology characteristics of the generated mesh. This is fixed at initialization time. + let meshTopology: CurvedMeshTopology + + /// The current generated mesh geometry. Update this with ``updateMeshGeometry()`` + private(set) var meshGeometry: CurvedMeshGeometry = CurvedMeshGeometry(width: 1, height: 1) + + /// An async task responsible for managing physics mesh cooking. + /// + /// This guarantees that at most one cooking operation is active at a time. + /// Cooking generally takes > 1 frame, so it's important that there is not an explosion of redundant work + /// if there is a burst of resize activity. + private var physicsCookingTask: Task? + + /// ``collisionShape`` is up to date with this `CurvedMeshGeometry`. + private var lastCookedGeometry: CurvedMeshGeometry? + + /// LowLevelTexture that backs ``textureResource``. + private var lowLevelTexture: LowLevelTexture? + + struct CurvedMeshTopology: Sendable, Equatable { + /// Number of horizontal segments to use to generate the mesh grid + var segmentsX: Int = 32 + + /// Number of vertical segments to use to generate the mesh grid + var segmentsY: Int = 32 + + /// Total number of vertices required to generate a mesh with this topology + var vertexCount: Int { (segmentsX + 1) * (segmentsY + 1) } + + /// Total size of the index buffer when generating a mesh with this topology + var indexCount: Int { segmentsX * segmentsY * 6 } + } + + struct CurvedMeshGeometry: Sendable, Equatable { + /// Width of the mesh in meters. + var width: Float + + /// Height of the mesh in meters. + var height: Float + + /// Radius of the mesh curvature in meters, or `nil` for a flat mesh. + var curvatureRadius: Float = 0 + + /// The bounding box of the mesh + var bounds: BoundingBox = BoundingBox() + + /// Current snapped status + var snapped: Bool = false + + /// Converts a 3D position on the mesh surface (in meters, relative to mesh center) + /// to normalized texture coordinates (0..1, 0..1). + func normalizedUV(fromMeshPosition position: SIMD3) -> SIMD2 { + if curvatureRadius > 0 { + let halfWidth = bounds.extents.x / 2 + + let theta = asinf(halfWidth / curvatureRadius) + let angle = asinf(position.x / curvatureRadius) + + let u = (angle / theta + 1) / 2 + let v = (position.y / height) + 0.5 + return SIMD2(u, v) + } else { + let u = (position.x / width) + 0.5 + let v = (position.y / height) + 0.5 + return SIMD2(u, v) + } + } + } + + init(meshTopology: CurvedMeshTopology = CurvedMeshTopology(), + meshGeometry: CurvedMeshGeometry = CurvedMeshGeometry(width: 1, height: 1)) { + self.meshTopology = meshTopology + self.meshGeometry = CurvedMeshGeometry(width: -1, height: -1) + + let lowLevelMesh = try! meshTopology.generateMesh() + + self.lowLevelMesh = lowLevelMesh + + updateMeshGeometry(meshGeometry) + } + + // MARK: - Mesh Generation (LowLevelMesh) + + func updateSnappedStatus(snapped: Bool) { + var geometry = self.meshGeometry + geometry.snapped = snapped + updateMeshGeometry(geometry) + } + + func updateMeshSize(width: Float, height: Float) { + var geometry = self.meshGeometry + geometry.width = width + geometry.height = height + updateMeshGeometry(geometry) + } + + func updateMeshCurvature(curvatureRadius: Float) { + var geometry = self.meshGeometry + geometry.curvatureRadius = curvatureRadius + updateMeshGeometry(geometry) + } + + /// Writes vertex position/normal/uv data into the LowLevelMesh buffer. + /// This is the fast path — called on every size or curvature change without + /// recreating MeshResource or Entity. + func updateMeshGeometry(_ meshGeometry: CurvedMeshGeometry) { + if meshGeometry == self.meshGeometry { + return // nothing to do + } + + let width = meshGeometry.width + let height = meshGeometry.height + let curvatureRadius = meshGeometry.curvatureRadius + + let segmentsX = meshTopology.segmentsX + let segmentsY = meshTopology.segmentsY + let indexCount = meshTopology.indexCount + + var boundsMin = SIMD3(repeating: Float.infinity) + var boundsMax = SIMD3(repeating: -Float.infinity) + + lowLevelMesh.withUnsafeMutableBytes(bufferIndex: 0) { rawBytes in + let vertices = rawBytes.bindMemory(to: CurvedPlaneVertex.self) + + if curvatureRadius > 0 { + + // Apply cylindrical curve: Z varies with X to create wrap-around + var curve_positions: [SIMD3] = [] + var curve_normals: [SIMD3] = [] + let r = curvatureRadius + let arc_length = width / r + for x in 0...segmentsX { + let u = Float(x) / Float(segmentsX) + let angle = (u - 0.5) * arc_length + let vec: SIMD3 = simd_normalize([sin(angle), 0.0, cos(angle)]) + let pos: SIMD3 = [vec.x, vec.y, 1.0 - vec.z] * r + curve_positions.append(pos) + + // Normal points toward viewer for convex curve + curve_normals.append(-vec) + } + let offsetZ = meshGeometry.snapped ? 0 : -curve_positions[0].z + + for y in 0...segmentsY { + let v = Float(y) / Float(segmentsY) * 2 - 1 + let posY = v * height / 2 + + for x in 0...segmentsX { + let u = Float(x) / Float(segmentsX) * 2 - 1 + + let position = curve_positions[x] + SIMD3(0, posY, offsetZ) + let normal = curve_normals[x] + + let idx = y * (segmentsX + 1) + x + vertices[idx].position = position + vertices[idx].normal = normal + vertices[idx].uv = SIMD2((u + 1) / 2, (v + 1) / 2) + + boundsMin = min(boundsMin, position) + boundsMax = max(boundsMax, position) + } + } + } else { + // Flat plane — same grid, z=0 + for y in 0...segmentsY { + let v = Float(y) / Float(segmentsY) + let posY = (v - 0.5) * height + + for x in 0...segmentsX { + let u = Float(x) / Float(segmentsX) + let posX = (u - 0.5) * width + + let idx = y * (segmentsX + 1) + x + let position = SIMD3(posX, posY, 0) + vertices[idx].position = position + vertices[idx].normal = SIMD3(0, 0, -1) + vertices[idx].uv = SIMD2(u, v) + + boundsMin = min(boundsMin, position) + boundsMax = max(boundsMax, position) + } + } + } + } + + let bounds = BoundingBox(min: boundsMin, max: boundsMax) + lowLevelMesh.parts.replaceAll([ + LowLevelMesh.Part(indexCount: indexCount, topology: .triangle, bounds: bounds) + ]) + + self.meshGeometry = meshGeometry + self.meshGeometry.bounds = bounds + invalidatePhysicsMesh() + } + + // MARK: - Physics Mesh Cooking + + /// Schedules an async physics mesh cook. If a cook is already in progress, + /// it will automatically re-cook when done if the geometry has changed. + private func invalidatePhysicsMesh() { + guard physicsCookingTask == nil else { return } + physicsCookingTask = Task { + defer { physicsCookingTask = nil } + // Loop until the cooked physics mesh matches the current geometry. + // Each iteration cooks against whatever the MeshResource currently reflects. + while lastCookedGeometry != meshGeometry { + let geometryAtStart = meshGeometry + do { + let meshResource = try await MeshResource(from: lowLevelMesh) + let shape = try await ShapeResource.generateStaticMesh(from: meshResource) + collisionShape = shape + lastCookedGeometry = geometryAtStart + } catch { + NSLog("SDL_RealityKitHelper: Failed to generate physics mesh: %@", error.localizedDescription) + break + } + } + } + } + + // MARK: - Texture Updates (LowLevelTexture Pipeline) + + /// Creates or recreates the LowLevelTexture for the given dimensions + private func ensureLowLevelTexture(width: Int, height: Int, pixelFormat: MTLPixelFormat) { + // Check if we need to recreate (size or format changed) + if let lowLevelTexture, + lowLevelTexture.descriptor.width == width, + lowLevelTexture.descriptor.height == height, + lowLevelTexture.descriptor.pixelFormat == pixelFormat + { + return + } + + //NSLog("SDL_RealityKitHelper: Creating LowLevelTexture %dx%d", width, height) + + do { + // Create LowLevelTexture descriptor using Metal pixel format directly + var descriptor = LowLevelTexture.Descriptor() + descriptor.textureType = .type2D + descriptor.pixelFormat = pixelFormat + descriptor.width = width + descriptor.height = height + descriptor.depth = 1 + let size = max(width, height) + if (size > 32) { + descriptor.mipmapLevelCount = Int(floor(log2(Float(size)))) - 5 + } else { + descriptor.mipmapLevelCount = 0 + } + descriptor.textureUsage = [.shaderRead, .renderTarget] + + // Create the LowLevelTexture + lowLevelTexture = try LowLevelTexture(descriptor: descriptor) + + // Create TextureResource from LowLevelTexture (this is reusable) + textureResource = try TextureResource(from: lowLevelTexture!) + + //NSLog("SDL_RealityKitHelper: LowLevelTexture created successfully") + } catch { + NSLog("SDL_RealityKitHelper: ERROR - Failed to create LowLevelTexture: %@", error.localizedDescription) + lowLevelTexture = nil + textureResource = nil + } + } + + @objc public func getDisplayTexture(_ commandBuffer: MTLCommandBuffer, width: Int, height: Int, pixelFormat: MTLPixelFormat) -> MTLTexture? { + // Ensure LowLevelTexture exists with correct dimensions + ensureLowLevelTexture( + width: width, + height: height, + pixelFormat: pixelFormat + ) + + guard let llt = lowLevelTexture else { + NSLog("SDL_RealityKitHelper: ERROR - No LowLevelTexture available") + return nil + } + + // Get the writable texture from LowLevelTexture + return llt.replace(using: commandBuffer) + } +} + +extension SDL_RealityKitHelper.CurvedMeshTopology { + @MainActor + func generateMesh() throws -> LowLevelMesh { + //NSLog("SDL_RealityKitHelper: Creating LowLevelMesh (%dx%d grid, %d vertices, %d indices)", + // segmentsX, segmentsY, vertexCount, indexCount) + + // Create LowLevelMesh with our custom vertex format + let desc = CurvedPlaneVertex.descriptor(vertexCount: vertexCount, indexCount: indexCount) + let mesh = try LowLevelMesh(descriptor: desc) + + // Write index buffer once — topology never changes for a fixed grid + mesh.withUnsafeMutableIndices { rawIndices in + let indices = rawIndices.bindMemory(to: UInt32.self) + var idx = 0 + for y in 0.. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SDL_uikitvisionosscene_h_ +#define SDL_uikitvisionosscene_h_ + +#import +#import + +/** + * Return true if the curved content pointer mode is enabled + */ +bool SDL_VisionOS_PointerModeEnabled(); + +/** + * Check if any window is using curved content mode (UIHostingController-based). + */ +bool SDL_UIKit_HasCurvedWindow(); + +/** + * Check if a window is using curved content mode (UIHostingController-based). + * + * @param window The SDL window to check. + * @return true if the window is in curved mode, false otherwise. + */ +bool SDL_UIKit_IsCurvedWindow(SDL_Window *window); + +/** + * Get the curved content display texture. + */ +id SDL_UIKit_GetCurvedDisplayTexture(SDL_Window *window, id commandBuffer, int width, int height, MTLPixelFormat pixelFormat); + +#endif /* SDL_uikitvisionosscene_h_ */ diff --git a/src/video/uikit/SDL_UIKitBridge-swift.h b/src/video/uikit/SDL_UIKitBridge-swift.h new file mode 100644 index 0000000000..e63dc6c42b --- /dev/null +++ b/src/video/uikit/SDL_UIKitBridge-swift.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ +#import "SDL_uikitviewcontroller.h" + +// Called from Swift scene delegates when window size changes +void SDL_VisionOS_SendSizeChanged(long width, long height); + +// Called from Swift scene delegates to get the initial curvature +float SDL_VisionOS_GetCurvature(); + +// Called from Swift scene delegates when window curvature changes +void SDL_VisionOS_SendCurvatureChanged(float curvature); + +// Called from Swift scene delegates when pointer mode changes +void SDL_VisionOS_SendPointerMode(bool enabled); + +// Called from Swift scene delegates when visionOS delivers a touch event +void SDL_VisionOS_SendTouch(NSTimeInterval timestamp, SDL_FingerID fingerID, Uint32 eventType, float x, float y); + +// Called from Swift to register the RealityKit hosting object with the SDL window +void SDL_VisionOS_SetWindowRealityKitHosting(id hosting); diff --git a/src/video/uikit/SDL_UIKitBridge.m b/src/video/uikit/SDL_UIKitBridge.m new file mode 100644 index 0000000000..b5c552f51a --- /dev/null +++ b/src/video/uikit/SDL_UIKitBridge.m @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_VISIONOS + +#include "SDL_UIKitBridge-objc.h" +#include "SDL_UIKitBridge-swift.h" +#include "SDL_uikitevents.h" +#include "SDL_uikitwindow.h" +#include "SDL_uikitmetalview.h" +#include "../../events/SDL_events_c.h" + + +// Called from Swift scene delegates when window size changes +void SDL_VisionOS_SendSizeChanged(long width, long height) +{ + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (window) { + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + CGRect bounds = CGRectMake(0, 0, width, height); + + // Update the UIWindow + data.uiwindow.frame = bounds; + + // Update the view + UIView *view = data.viewcontroller.view; + view.bounds = bounds; + + // Update the metal layer + if ([view isKindOfClass:[SDL_uikitmetalview class]]) { + SDL_uikitmetalview *metalview = (SDL_uikitmetalview *)view; + + [metalview updateDrawableSize]; + } + + // Send the resize event + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, (int)width, (int)height); + } +} + +// Called from Swift scene delegates to get the initial curvature +float SDL_VisionOS_GetCurvature() +{ + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (window) { + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + return data.curvature; + } + return 0.0f; +} + +// Called from Swift scene delegates when window curvature changes +void SDL_VisionOS_SendCurvatureChanged(float curvature) +{ + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (window) { + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + if (curvature != data.curvature) { + data.curvature = curvature; + SDL_SetFloatProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_CURVATURE_FLOAT, curvature); + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_CURVATURE_CHANGED, (int)curvature, 0); + } + } +} + +static bool SDL_pointer_mode; + +void SDL_VisionOS_SendPointerMode(bool enabled) +{ + SDL_pointer_mode = enabled; +} + +bool SDL_VisionOS_PointerModeEnabled() +{ + return SDL_pointer_mode; +} + +// Called from Swift scene delegates when visionOS delivers a touch event +void SDL_VisionOS_SendTouch(NSTimeInterval timestamp, SDL_FingerID fingerID, Uint32 eventType, float x, float y) +{ + const SDL_TouchID directTouchId = 1; + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (!window) { + return; + } + + float pressure; + if (eventType == SDL_EVENT_FINGER_DOWN || eventType == SDL_EVENT_FINGER_MOTION) { + pressure = 1.0f; + } else { + pressure = 0.0f; + } + if (eventType == SDL_EVENT_FINGER_MOTION) { + SDL_SendTouchMotion(UIKit_GetEventTimestamp(timestamp), directTouchId, fingerID, window, x, y, pressure); + } else { + SDL_SendTouch(UIKit_GetEventTimestamp(timestamp), directTouchId, fingerID, window, (SDL_EventType)eventType, x, y, pressure); + } +} + +// MARK: - RealityKit Content Hosting + +// Called from Swift to register the RealityKit hosting object with the SDL window. +void SDL_VisionOS_SetWindowRealityKitHosting(id hosting) +{ + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (!window) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "VISIONOS: No focused window for RealityKit hosting"); + return; + } + + SDL_UIKitWindowData *windowData = (__bridge SDL_UIKitWindowData *)window->internal; + windowData.curvedContentHosting = hosting; + + // Updating curvedContentHosting updates the view controller so that the "container background" is hidden. + // On visionOS, this gets rid of the default glass background effect (not wanted for our content). + [windowData.viewcontroller setNeedsUpdateOfPreferredContainerBackgroundStyle]; + + //SDL_Log("VISIONOS: RealityKit hosting registered"); +} + +bool SDL_UIKit_HasCurvedWindow() +{ + SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); + if (window) { + return SDL_UIKit_IsCurvedWindow(window); + } + return false; +} + +bool SDL_UIKit_IsCurvedWindow(SDL_Window *window) +{ + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + return data && data.curvedContentHosting; +} + +id SDL_UIKit_GetCurvedDisplayTexture(SDL_Window *window, id commandBuffer, int width, int height, MTLPixelFormat pixelFormat) +{ + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + if (!data || !data.curvedContentHosting) { + return nil; + } + + id hosting = data.curvedContentHosting; + SEL getTextureSelector = NSSelectorFromString(@"getDisplayTexture:width:height:pixelFormat:"); + if (![hosting respondsToSelector:getTextureSelector]) { + return nil; + } + + NSMethodSignature *signature = [hosting methodSignatureForSelector:getTextureSelector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setSelector:getTextureSelector]; + [invocation setTarget:hosting]; + + long arg_width = width; + long arg_height = height; + [invocation setArgument:&commandBuffer atIndex:2]; + [invocation setArgument:&arg_width atIndex:3]; + [invocation setArgument:&arg_height atIndex:4]; + [invocation setArgument:&pixelFormat atIndex:5]; + [invocation invoke]; + + __unsafe_unretained id temp = nil; + [invocation getReturnValue:&temp]; + id texture = temp; + return texture; +} + +#endif /* SDL_PLATFORM_VISIONOS */ diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 4f9de24af2..a2722f0c01 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -29,6 +29,7 @@ #include "SDL_uikitopengles.h" #include "SDL_uikitvideo.h" #include "SDL_uikitwindow.h" +#include "SDL_UIKitBridge-objc.h" #import #import @@ -308,6 +309,12 @@ static bool SetGCMouseRelativeMode(bool enabled) static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed) { Uint64 timestamp = SDL_GetTicksNS(); + +#ifdef SDL_PLATFORM_VISIONOS + if (!SDL_VisionOS_PointerModeEnabled() && SDL_UIKit_HasCurvedWindow()) { + return; + } +#endif SDL_SendMouseButton(timestamp, SDL_GetMouseFocus(), mouseID, button, pressed); } @@ -318,19 +325,19 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 SDL_AddMouse(mouseID, NULL); mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); }; mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed); + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed); }; mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); }; int auxiliary_button = SDL_BUTTON_X1; for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { btn.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed); + OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed); }; ++auxiliary_button; } @@ -338,21 +345,32 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) { Uint64 timestamp = SDL_GetTicksNS(); - if (SDL_GCMouseRelativeMode()) { + bool send_motion = SDL_GCMouseRelativeMode(); +#ifdef SDL_PLATFORM_VISIONOS + if (!send_motion && SDL_VisionOS_PointerModeEnabled()) { + send_motion = true; + } +#endif + if (send_motion) { SDL_SendMouseMotion(timestamp, SDL_GetMouseFocus(), mouseID, true, deltaX, -deltaY); } }; mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { Uint64 timestamp = SDL_GetTicksNS(); - + /* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis. * The vertical values are negative moving the mouse wheel up and positive moving it down. * The horizontal values are negative moving the mouse wheel left and positive moving it right. * The vertical values are inverted compared to SDL, and the horizontal values are as expected. */ +#ifdef SDL_PLATFORM_VISIONOS + float vertical = -yValue; + float horizontal = xValue; +#else float vertical = -xValue; float horizontal = yValue; +#endif if (mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { // Since these are raw values, we need to flip them ourselves diff --git a/src/video/uikit/SDL_uikitmetalview.h b/src/video/uikit/SDL_uikitmetalview.h index 5a2523e626..4890731c08 100644 --- a/src/video/uikit/SDL_uikitmetalview.h +++ b/src/video/uikit/SDL_uikitmetalview.h @@ -1,24 +1,23 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga - 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. + 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. - */ + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ /* * @author Mark Callow, www.edgewise-consulting.com. * @@ -43,6 +42,8 @@ - (instancetype)initWithFrame:(CGRect)frame scale:(CGFloat)scale; +- (void)updateDrawableSize; + @end SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m index 596b311165..2e3d438553 100644 --- a/src/video/uikit/SDL_uikitmetalview.m +++ b/src/video/uikit/SDL_uikitmetalview.m @@ -1,24 +1,23 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga - 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. + 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. - */ + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ /* * @author Mark Callow, www.edgewise-consulting.com. * diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index d05a14a1c3..615636f594 100644 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -1,22 +1,22 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga - 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. + 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: + 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. + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_internal.h" diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index a758de7ff5..1c1e415047 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -59,6 +59,10 @@ - (void)loadView; - (void)viewDidLayoutSubviews; +#ifdef SDL_PLATFORM_VISIONOS +- (void)initializeVisionOSCurvedUI; +#endif + #ifndef SDL_PLATFORM_TVOS - (NSUInteger)supportedInterfaceOrientations; - (BOOL)prefersStatusBarHidden; diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index e9b48c2e01..dc776741d9 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -33,6 +33,10 @@ #include "SDL_uikitwindow.h" #include "SDL_uikitopengles.h" +#ifdef SDL_PLATFORM_VISIONOS +#import "SDL3/SDL3-Swift.h" +#endif + #ifdef SDL_PLATFORM_TVOS static void SDLCALL SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { @@ -119,6 +123,15 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char } } } + +#ifdef SDL_PLATFORM_VISIONOS + if (@available(visionOS 26.0, *)) { + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)self.window->internal; + if (data.curvature >= 0.0f) { + [self initializeVisionOSCurvedUI]; + } + } +#endif return self; } @@ -141,6 +154,19 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #endif } +#ifdef SDL_PLATFORM_VISIONOS +- (UIContainerBackgroundStyle)preferredContainerBackgroundStyle +{ + if (self.window) { + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)self.window->internal; + if (data && data.curvedContentHosting) { + return UIContainerBackgroundStyleHidden; + } + } + return UIContainerBackgroundStyleAutomatic; +} +#endif + - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { SDL_SetSystemTheme(UIKit_GetSystemTheme()); diff --git a/src/video/uikit/SDL_uikitviewcontroller.swift b/src/video/uikit/SDL_uikitviewcontroller.swift new file mode 100644 index 0000000000..a47519ed28 --- /dev/null +++ b/src/video/uikit/SDL_uikitviewcontroller.swift @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ + +import SwiftUI + +extension SDL_uikitviewcontroller { + @available(visionOS 26.0, *) + @objc func initializeVisionOSCurvedUI() { + Task { + let hosting = SDL_CurvedContentHosting() + hosting.present(from: self) + SDL_VisionOS_SetWindowRealityKitHosting(hosting) + } + } +} diff --git a/src/video/uikit/SDL_uikitwindow.h b/src/video/uikit/SDL_uikitwindow.h index 79b969c051..b9077ad36d 100644 --- a/src/video/uikit/SDL_uikitwindow.h +++ b/src/video/uikit/SDL_uikitwindow.h @@ -52,6 +52,12 @@ extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window *window); // Array of SDL_uikitviews owned by this window. @property(nonatomic, copy) NSMutableArray *views; +#ifdef SDL_PLATFORM_VISIONOS +// Hosting controller for curved content mode (UIHostingController-based) +@property(nonatomic, strong) id curvedContentHosting; +@property(nonatomic, assign) CGFloat curvature; +#endif + @end #endif // SDL_uikitwindow_h_ diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 3f1f1b464d..3c3b4fd926 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -53,7 +53,7 @@ @end -static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow *uiwindow, bool created) +static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow *uiwindow, SDL_PropertiesID create_props, bool created) { SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->internal; @@ -106,6 +106,19 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow #endif window->w = width; window->h = height; + + SDL_PropertiesID props = SDL_GetWindowProperties(window); + SDL_SetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, (__bridge void *)data.uiwindow); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_METAL_VIEW_TAG_NUMBER, SDL_METALVIEW_TAG); + +#ifdef SDL_PLATFORM_VISIONOS + float curvature = SDL_GetFloatProperty(create_props, SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT, -1.0f); + if (curvature > 0.0f && curvature <= 1.0f) { + curvature = 0.0f; + } + data.curvature = curvature; + SDL_SetFloatProperty(props, SDL_PROP_WINDOW_CURVATURE_FLOAT, curvature); +#endif /* The View Controller will handle rotating the view when the device * orientation changes. This will trigger resize events, if appropriate. */ @@ -119,10 +132,6 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow * hierarchy. */ [view setSDLWindow:window]; - SDL_PropertiesID props = SDL_GetWindowProperties(window); - SDL_SetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, (__bridge void *)data.uiwindow); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_METAL_VIEW_TAG_NUMBER, SDL_METALVIEW_TAG); - return true; } @@ -228,7 +237,7 @@ bool UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti } #endif - if (!SetupWindowData(_this, window, uiwindow, true)) { + if (!SetupWindowData(_this, window, uiwindow, create_props, true)) { return false; } } From fd8682ccc9aa66d309bbe1a4a3852ee8b6c80460 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Tue, 12 May 2026 23:49:34 +0000 Subject: [PATCH 258/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_video.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 57fa31f001..2076352980 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -1386,8 +1386,11 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren * * These are additional supported properties with visionOS: * - * - `SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT`: the curvature of the window on visionOS. Curved windows have square corners and additional controls for more immersive gaming. - * This can be -1 (disabled), which is the default, 0 (no curve), or set to a specific curvature radius in millimeters. A common value for a gaming monitor is 1000. + * - `SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT`: the curvature of the window on + * visionOS. Curved windows have square corners and additional controls for + * more immersive gaming. This can be -1 (disabled), which is the default, 0 + * (no curve), or set to a specific curvature radius in millimeters. A + * common value for a gaming monitor is 1000. * * If this window is being created to be used with an SDL_Renderer, you should * not add a graphics API specific property @@ -1632,7 +1635,10 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window) * * On visionOS: * - * - `SDL_PROP_WINDOW_CURVATURE_FLOAT`: the curvature of the window in curved mode on visionOS. This value is updated dynamically when changed via the screen ornaments. This can be 0 (no curve), or a specific curvature radius in millimeters. A common value for a gaming monitor is 1000. + * - `SDL_PROP_WINDOW_CURVATURE_FLOAT`: the curvature of the window in curved + * mode on visionOS. This value is updated dynamically when changed via the + * screen ornaments. This can be 0 (no curve), or a specific curvature + * radius in millimeters. A common value for a gaming monitor is 1000. * * \param window the window to query. * \returns a valid property ID on success or 0 on failure; call From 418960bb4e93feaa70f68ec2da7af0f94d08d2dc Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Tue, 12 May 2026 17:19:18 -0700 Subject: [PATCH 259/407] Handle the Amazon Fire TV's weird Bluetooth behavior --- .../app/HIDDeviceBLESteamController.java | 134 ++++++++++++++---- 1 file changed, 105 insertions(+), 29 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java index e3dc36cc7d..e14a11bad1 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java @@ -37,6 +37,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe private boolean mIsConnected = false; private boolean mIsChromebook = false; private boolean mIsReconnecting = false; + private boolean mHasEnabledNotifications = false; + private boolean mHasSeenInputUpdate = false; private boolean mFrozen = false; private LinkedList mOperations; GattOperation mCurrentOperation = null; @@ -73,6 +75,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe byte[] mValue; BluetoothGatt mGatt; boolean mResult = true; + int mDelayMs = 0; private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid) { mGatt = gatt; @@ -80,6 +83,13 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe mUuid = uuid; } + private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid, int delayMs) { + mGatt = gatt; + mOp = operation; + mUuid = uuid; + mDelayMs = delayMs; + } + private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid, byte[] value) { mGatt = gatt; mOp = operation; @@ -87,6 +97,14 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe mValue = value; } + private GattOperation(BluetoothGatt gatt, GattOperation.Operation operation, UUID uuid, byte[] value, int delayMs) { + mGatt = gatt; + mOp = operation; + mUuid = uuid; + mValue = value; + mDelayMs = delayMs; + } + public void run() { // This is executed in main thread BluetoothGattCharacteristic chr; @@ -148,6 +166,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe return mResult; } + public int getDelayMs() { return mDelayMs; } + private BluetoothGattCharacteristic getCharacteristic(UUID uuid) { BluetoothGattService valveService = mGatt.getService(steamControllerService); if (valveService == null) @@ -166,6 +186,10 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe static public GattOperation enableNotification(BluetoothGatt gatt, UUID uuid) { return new GattOperation(gatt, Operation.ENABLE_NOTIFICATION, uuid); } + + static public GattOperation enableNotification(BluetoothGatt gatt, UUID uuid, int delayMs) { + return new GattOperation(gatt, Operation.ENABLE_NOTIFICATION, uuid, delayMs); + } } HIDDeviceBLESteamController(HIDDeviceManager manager, BluetoothDevice device) { @@ -178,6 +202,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe mHandler = new Handler(Looper.getMainLooper()); mGatt = connectGatt(); + mHasEnabledNotifications = false; + mHasSeenInputUpdate = false; // final HIDDeviceBLESteamController finalThis = this; // mHandler.postDelayed(new Runnable() { // @Override @@ -414,21 +440,30 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe mCurrentOperation = mOperations.removeFirst(); } - // Run in main thread - mHandler.post(new Runnable() { - @Override - public void run() { - synchronized (mOperations) { - if (mCurrentOperation == null) { - Log.e(TAG, "Current operation null in executor?"); - return; - } + Runnable gattOperationRunnable = new Runnable() { + @Override + public void run() { + synchronized (mOperations) { + if (mCurrentOperation == null) { + Log.e(TAG, "Current operation null in executor?"); + return; + } - mCurrentOperation.run(); - // now wait for the GATT callback and when it comes, finish this operation + mCurrentOperation.run(); + // now wait for the GATT callback and when it comes, finish this operation + } } - } - }); + }; + + if (mCurrentOperation.getDelayMs() == 0) { + // Run in main thread + mHandler.post(gattOperationRunnable); + } + else { + // If we have a delay on this operation, wait before we post it. + mHandler.postDelayed(gattOperationRunnable, mCurrentOperation.getDelayMs()); + } + } private void queueGattOperation(GattOperation op) { @@ -439,8 +474,39 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe } private void enableNotification(UUID chrUuid) { - GattOperation op = HIDDeviceBLESteamController.GattOperation.enableNotification(mGatt, chrUuid); + // Add a 500ms delay to notification write for Amazon Fire TV devices, as otherwise if we do this too quickly after connecting + // it will return success and then silently drop the operation on the floor. + GattOperation op = HIDDeviceBLESteamController.GattOperation.enableNotification(mGatt, chrUuid, 500); queueGattOperation(op); + + // Amazon Fire devices can also silently timeout on writeDescriptor, so + // set up a little delayed check that will attempt to write a second time. + // + // While this only seems to be needed on Amazon Fire TV devices at present, it + // doesn't hurt to have a retry on other devices as well. + // + final HIDDeviceBLESteamController finalThis = this; + final UUID finalUuid = chrUuid; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + if (!finalThis.mHasEnabledNotifications) { + + if (finalThis.mHasSeenInputUpdate) { + // Amazon Five devices may have enabled notifications on the input characteristic and not given us a callback. If we've seen + // input reports, though, somewhat by definition notifications are enabled. + Log.w(TAG, "WriteDescriptor has never returned, but we've seen input reports. Moving on with controller initialization."); + finalThis.mHasEnabledNotifications = true; + finalThis.enableValveMode(); + return; + } + + // Give one more try. + GattOperation retry = HIDDeviceBLESteamController.GattOperation.enableNotification(finalThis.mGatt, finalUuid, 500); + finalThis.queueGattOperation(retry); + } + } + }, 1000); } void writeCharacteristic(UUID uuid, byte[] value) { @@ -538,6 +604,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe //Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue())); if (characteristic.getUuid().equals(getInputCharacteristic()) && !mFrozen) { + mHasSeenInputUpdate = true; mManager.HIDDeviceInputReport(getId(), characteristic.getValue()); } } @@ -547,27 +614,36 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe //Log.v(TAG, "onDescriptorRead status=" + status); } + private void enableValveMode() + { + BluetoothGattService valveService = mGatt.getService(steamControllerService); + if (valveService == null) + return; + + BluetoothGattCharacteristic reportChr = valveService.getCharacteristic(reportCharacteristic); + if (reportChr != null) { + if (getProductId() == TRITON_BLE_PID) { + // For Triton we just mark things registered. + Log.v(TAG, "Registering Triton Steam Controller with ID: " + getId()); + mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true); + setRegistered(); + } else { + // For the original controller, we need to manually enter Valve mode. + Log.v(TAG, "Writing report characteristic to enter valve mode"); + reportChr.setValue(enterValveMode); + mGatt.writeCharacteristic(reportChr); + } + } + } + @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { BluetoothGattCharacteristic chr = descriptor.getCharacteristic(); //Log.v(TAG, "onDescriptorWrite status=" + status + " uuid=" + chr.getUuid() + " descriptor=" + descriptor.getUuid()); if (chr.getUuid().equals(getInputCharacteristic())) { - boolean hasWrittenInputDescriptor = true; - BluetoothGattCharacteristic reportChr = chr.getService().getCharacteristic(reportCharacteristic); - if (reportChr != null) { - if (getProductId() == TRITON_BLE_PID) { - // For Triton we just mark things registered. - Log.v(TAG, "Registering Triton Steam Controller with ID: " + getId()); - mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true); - setRegistered(); - } else { - // For the original controller, we need to manually enter Valve mode. - Log.v(TAG, "Writing report characteristic to enter valve mode"); - reportChr.setValue(enterValveMode); - gatt.writeCharacteristic(reportChr); - } - } + mHasEnabledNotifications = true; + enableValveMode(); } finishCurrentGattOperation(); From 7071efb6a3a4b3a63d6a1a46516d846ae088ee2c Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Tue, 12 May 2026 16:18:27 +0100 Subject: [PATCH 260/407] Fix switching modes on RISC OS --- src/video/SDL_video.c | 4 ++++ src/video/riscos/SDL_riscosmodes.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0a387fad2a..d20d5eefea 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1533,9 +1533,13 @@ bool SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mo mode = &display->desktop_mode; } + // On RISC OS, it's necessary to switch from the desktop to single-tasking + // fullscreen so that it can handle switching back to the desktop correctly. +#ifndef SDL_PLATFORM_RISCOS if (mode == display->current_mode) { return true; } +#endif // Actually change the display mode if (_this->SetDisplayMode) { diff --git a/src/video/riscos/SDL_riscosmodes.c b/src/video/riscos/SDL_riscosmodes.c index 9dda0e5ac6..0da0cc8621 100644 --- a/src/video/riscos/SDL_riscosmodes.c +++ b/src/video/riscos/SDL_riscosmodes.c @@ -96,7 +96,7 @@ static size_t measure_mode_block(const int *block) return blockSize * 4; } -static bool read_mode_variable(int *block, int var) +static int read_mode_variable(int *block, int var) { _kernel_swi_regs regs; regs.r[0] = (int)block; From 7222c04fbf2b904e815f5ac9c8623ef8030fd261 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 12 May 2026 18:59:06 -0700 Subject: [PATCH 261/407] Synchronize controller access on the Java side on Android --- .../main/java/org/libsdl/app/SDLControllerManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index bcdf33233a..31b07b0ac0 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -340,7 +340,7 @@ class SDLJoystickHandler { } } - synchronized protected SDLJoystick getJoystick(int device_id) { + protected SDLJoystick getJoystick(int device_id) { for (SDLJoystick joystick : mJoysticks) { if (joystick.device_id == device_id) { return joystick; @@ -354,7 +354,7 @@ class SDLJoystickHandler { * @param event the event to be handled. * @return if given event was processed. */ - boolean handleMotionEvent(MotionEvent event) { + synchronized boolean handleMotionEvent(MotionEvent event) { int actionPointerIndex = event.getActionIndex(); int action = event.getActionMasked(); if (action == MotionEvent.ACTION_MOVE) { @@ -524,7 +524,7 @@ class SDLJoystickHandler { return button_mask; } - void setLED(int device_id, int red, int green, int blue) { + synchronized void setLED(int device_id, int red, int green, int blue) { if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) { return; } @@ -542,7 +542,7 @@ class SDLJoystickHandler { joystick.lightsSession.requestLights(lightsRequest.build()); } - void setSensorsEnabled(int device_id, boolean enabled) { + synchronized void setSensorsEnabled(int device_id, boolean enabled) { if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) { return; } From c362f1341f2e2e6abf34ae05d6068ad89bebd00d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 12 May 2026 19:25:58 -0700 Subject: [PATCH 262/407] Change controller sensor state on the main UI thread on Android Fixes https://github.com/libsdl-org/SDL/issues/15565 --- .../main/java/org/libsdl/app/SDLControllerManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 31b07b0ac0..2a0296eb0c 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -91,7 +91,13 @@ public class SDLControllerManager * This method is called by SDL using JNI. */ static void joystickSetSensorsEnabled(int device_id, boolean enabled) { - mJoystickHandler.setSensorsEnabled(device_id, enabled); + // Run this on the UI thread so we don't race with enableSensor() in SDLSurface.java + SDL.getContext().runOnUiThread(new Runnable() { + @Override + public void run() { + mJoystickHandler.setSensorsEnabled(device_id, enabled); + } + }); } /** From 36e1efccb473b3aebd68048927d565c17eb48beb Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 13 May 2026 18:00:02 +0300 Subject: [PATCH 263/407] revert parts of CodeSpell commit d870911202 from 3rd party sources --- src/hidapi/hidapi/hidapi.h | 2 +- src/hidapi/windows/hidapi_descriptor_reconstruct.c | 12 ++++++------ src/hidapi/windows/pp_data_dump/pp_data_dump.c | 4 ++-- src/libm/e_sqrt.c | 4 ++-- src/libm/k_rem_pio2.c | 2 +- src/stdlib/SDL_malloc.c | 10 +++++----- src/video/miniz.h | 2 +- src/video/stb_image.h | 12 ++++++------ src/video/x11/edid.h | 2 +- src/video/yuv2rgb/yuv_rgb.h | 2 +- src/video/yuv2rgb/yuv_rgb_sse.h | 2 +- src/video/yuv2rgb/yuv_rgb_std.h | 2 +- wayland-protocols/wayland.xml | 12 ++++++------ 13 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/hidapi/hidapi/hidapi.h b/src/hidapi/hidapi/hidapi.h index 5446b2c82b..0e75f0de97 100644 --- a/src/hidapi/hidapi/hidapi.h +++ b/src/hidapi/hidapi/hidapi.h @@ -64,7 +64,7 @@ #define HID_API_AS_STR(x) HID_API_AS_STR_IMPL(x) #define HID_API_TO_VERSION_STR(v1, v2, v3) HID_API_AS_STR(v1.v2.v3) -/** @brief Converts a version as Major/Minor/Patch into a number: +/** @brief Coverts a version as Major/Minor/Patch into a number: <8 bit major><16 bit minor><8 bit patch>. This macro was added in version 0.12.0. diff --git a/src/hidapi/windows/hidapi_descriptor_reconstruct.c b/src/hidapi/windows/hidapi_descriptor_reconstruct.c index 6e9f79eb0b..6697d3c3c3 100644 --- a/src/hidapi/windows/hidapi_descriptor_reconstruct.c +++ b/src/hidapi/windows/hidapi_descriptor_reconstruct.c @@ -401,11 +401,11 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha collection_node_idx = coll_child_order[collection_node_idx][0]; // In a HID Report Descriptor, the first usage declared is the most preferred usage for the control. - // While the order in the WIN32 capabiliy structures is the opposite: + // While the order in the WIN32 capabiliy strutures is the opposite: // Here the preferred usage is the last aliased usage in the sequence. if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) { - // Aliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output) + // Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output) firstDelimiterNode = main_item_list; coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list); coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list); @@ -431,7 +431,7 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha collection_node_idx = coll_child_order[collection_node_idx][nextChild]; if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) { - // Aliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output) + // Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output) firstDelimiterNode = main_item_list; coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list); coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list); @@ -491,11 +491,11 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha list_node = rd_search_main_item_list_for_bit_position(first_bit, (rd_main_items) rt_idx, pp_data->caps[caps_idx].ReportID, &coll_begin); // In a HID Report Descriptor, the first usage declared is the most preferred usage for the control. - // While the order in the WIN32 capabiliy structures is the opposite: + // While the order in the WIN32 capabiliy strutures is the opposite: // Here the preferred usage is the last aliased usage in the sequence. if (pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode == NULL)) { - // Aliased Usage (First node in pp_data->caps -> Last entry in report descriptor output) + // Alliased Usage (First node in pp_data->caps -> Last entry in report descriptor output) firstDelimiterNode = list_node; rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node); rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_close, pp_data->caps[caps_idx].ReportID, &list_node); @@ -504,7 +504,7 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node); } else if (!pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode != NULL)) { - // Aliased Collection (Last node in pp_data->caps -> First entry in report descriptor output) + // Alliased Collection (Last node in pp_data->caps -> First entry in report descriptor output) rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node); rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_open, pp_data->caps[caps_idx].ReportID, &list_node); firstDelimiterNode = NULL; diff --git a/src/hidapi/windows/pp_data_dump/pp_data_dump.c b/src/hidapi/windows/pp_data_dump/pp_data_dump.c index 9a17527263..d5df68b50f 100644 --- a/src/hidapi/windows/pp_data_dump/pp_data_dump.c +++ b/src/hidapi/windows/pp_data_dump/pp_data_dump.c @@ -85,8 +85,8 @@ void dump_hidp_link_collection_node(FILE* file, phid_pp_link_collection_node pco fprintf(file, "pp_data->LinkCollectionArray[%u]->NumberOfChildren = %hu\n", coll_idx, pcoll->NumberOfChildren); fprintf(file, "pp_data->LinkCollectionArray[%u]->NextSibling = %hu\n", coll_idx, pcoll->NextSibling); fprintf(file, "pp_data->LinkCollectionArray[%u]->FirstChild = %hu\n", coll_idx, pcoll->FirstChild); - // The compilers are not consistent on ULONG-bit-fields: They lose the unsigned or define them as int. - // Thus just always cast them to unsigned int, which should be fine, as the biggest bit-field is 28 bit + // The compilers are not consistent on ULONG-bit-fields: They lose the unsinged or define them as int. + // Thus just always cast them to unsinged int, which should be fine, as the biggest bit-field is 28 bit fprintf(file, "pp_data->LinkCollectionArray[%u]->CollectionType = %u\n", coll_idx, (unsigned int)(pcoll->CollectionType)); fprintf(file, "pp_data->LinkCollectionArray[%u]->IsAlias = %u\n", coll_idx, (unsigned int)(pcoll->IsAlias)); fprintf(file, "pp_data->LinkCollectionArray[%u]->Reserved = 0x%08X\n", coll_idx, (unsigned int)(pcoll->Reserved)); diff --git a/src/libm/e_sqrt.c b/src/libm/e_sqrt.c index 43ea26a438..f0add57953 100644 --- a/src/libm/e_sqrt.c +++ b/src/libm/e_sqrt.c @@ -38,7 +38,7 @@ * If (2) is false, then q = q ; otherwise q = q + 2 . * i+1 i i+1 i * - * With some algebraic manipulation, it is not difficult to see + * With some algebric manipulation, it is not difficult to see * that (2) is equivalent to * -(i+1) * s + 2 <= y (3) @@ -281,7 +281,7 @@ A. sqrt(x) by Newton Iteration This formula has one division fewer than the one above; however, it requires more multiplications and additions. Also x must be scaled in advance to avoid spurious overflow in evaluating the - expression 3y*y+x. Hence it is not recommended unless division + expression 3y*y+x. Hence it is not recommended uless division is slow. If division is very slow, then one should use the reciproot algorithm given in section B. diff --git a/src/libm/k_rem_pio2.c b/src/libm/k_rem_pio2.c index c82f0c5b06..29dd9f3753 100644 --- a/src/libm/k_rem_pio2.c +++ b/src/libm/k_rem_pio2.c @@ -41,7 +41,7 @@ * z = (z-x[i])*2**24 * * - * y[] output result in an array of double precision numbers. + * y[] ouput result in an array of double precision numbers. * The dimension of y[] is: * 24-bit precision 1 * 53-bit precision 2 diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index 5079172020..d30a8bbb13 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -1722,7 +1722,7 @@ SDL_FORCE_INLINE void* win32direct_mmap(size_t size) { return (ptr != 0)? ptr: MFAIL; } -/* This function supports releasing coalesced segments */ +/* This function supports releasing coalesed segments */ SDL_FORCE_INLINE int win32munmap(void* ptr, size_t size) { MEMORY_BASIC_INFORMATION minfo; char* cptr = (char*)ptr; @@ -1810,7 +1810,7 @@ SDL_FORCE_INLINE int win32munmap(void* ptr, size_t size) { #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL #endif /* HAVE_MMAP && HAVE_MREMAP */ -/* mstate bit set if contiguous morecore disabled or failed */ +/* mstate bit set if continguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ @@ -4725,7 +4725,7 @@ void* dlmalloc(size_t bytes) { void dlfree(void* mem) { /* - Consolidate freed chunks with preceding or succeeding bordering + Consolidate freed chunks with preceeding or succeeding bordering free chunks, if they exist, and then place in a bin. Intermixed with special cases for top, dv, mmapped chunks, and usage errors. */ @@ -6259,10 +6259,10 @@ History: Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshold + * Use ordered bins instead of best-fit threshhold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top - * Fix error occurring when initial sbrk_base not word-aligned. + * Fix error occuring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen diff --git a/src/video/miniz.h b/src/video/miniz.h index 0cb0b338b6..ed4a9bc262 100644 --- a/src/video/miniz.h +++ b/src/video/miniz.h @@ -9,7 +9,7 @@ * Change History 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!): - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug - would only have occurred in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place() + would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place() (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag). - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries. diff --git a/src/video/stb_image.h b/src/video/stb_image.h index 3223cf067a..fed28a0a9e 100644 --- a/src/video/stb_image.h +++ b/src/video/stb_image.h @@ -2318,7 +2318,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n) unsigned int k; int sgn; if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s instead of continuing + if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) k = stbi_lrot(j->code_buffer, n); @@ -2333,7 +2333,7 @@ stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) { unsigned int k; if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s instead of continuing + if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing k = stbi_lrot(j->code_buffer, n); j->code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; @@ -2345,7 +2345,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) { unsigned int k; if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s instead of continuing + if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing k = j->code_buffer; j->code_buffer <<= 1; --j->code_bits; @@ -5193,7 +5193,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - // between here and free(out) below, exiting would leak + // between here and free(out) below, exitting would leak temp_out = p; if (pal_img_n == 3) { @@ -7107,7 +7107,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i // 0: not specified. } - // background is what out is after the undoing of the previous frame; + // background is what out is after the undoing of the previou frame; memcpy( g->background, g->out, 4 * g->w * g->h ); } @@ -8147,7 +8147,7 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user 1.31 (2011-06-20) a few more leak fixes, bug in PNG handling (SpartanJ) 1.30 (2011-06-11) - added ability to load files via callbacks to accommodate custom input streams (Ben Wenger) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) removed deprecated format-specific test/load functions removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) diff --git a/src/video/x11/edid.h b/src/video/x11/edid.h index 5b94b4cc5d..4581291896 100644 --- a/src/video/x11/edid.h +++ b/src/video/x11/edid.h @@ -146,7 +146,7 @@ struct MonitorInfo int width_mm; // -1 if not specified int height_mm; // -1 if not specified - double aspect_ratio; // -1.0 if not specified + double aspect_ratio; // -1.0 if not specififed double gamma; // -1.0 if not specified diff --git a/src/video/yuv2rgb/yuv_rgb.h b/src/video/yuv2rgb/yuv_rgb.h index cca9435dde..c3593168f8 100644 --- a/src/video/yuv2rgb/yuv_rgb.h +++ b/src/video/yuv2rgb/yuv_rgb.h @@ -17,7 +17,7 @@ // is suboptimal for image quality, but by far the fastest method. // For all methods, width and height should be even, if not, the last row/column of the result image won't be affected. -// For sse methods, if the width if not divisible by 32, the last (width%32) pixels of each line won't be affected. +// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected. /*#include */ diff --git a/src/video/yuv2rgb/yuv_rgb_sse.h b/src/video/yuv2rgb/yuv_rgb_sse.h index d30bafeb3e..bfad8564ac 100644 --- a/src/video/yuv2rgb/yuv_rgb_sse.h +++ b/src/video/yuv2rgb/yuv_rgb_sse.h @@ -3,7 +3,7 @@ #include "yuv_rgb_common.h" // yuv to rgb, sse implementation -// pointers must be 16 byte aligned, and strides must be divisible by 16 +// pointers must be 16 byte aligned, and strides must be divisable by 16 void yuv420_rgb565_sse( uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, diff --git a/src/video/yuv2rgb/yuv_rgb_std.h b/src/video/yuv2rgb/yuv_rgb_std.h index 945837844c..c9f856ba98 100644 --- a/src/video/yuv2rgb/yuv_rgb_std.h +++ b/src/video/yuv2rgb/yuv_rgb_std.h @@ -14,7 +14,7 @@ // is suboptimal for image quality, but by far the fastest method. // For all methods, width and height should be even, if not, the last row/column of the result image won't be affected. -// For sse methods, if the width if not divisible by 32, the last (width%32) pixels of each line won't be affected. +// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected. /*#include */ diff --git a/wayland-protocols/wayland.xml b/wayland-protocols/wayland.xml index 15cb32e244..bee74a1008 100644 --- a/wayland-protocols/wayland.xml +++ b/wayland-protocols/wayland.xml @@ -1511,7 +1511,7 @@ Destroying the wl_buffer after wl_buffer.release does not change the surface contents. Destroying the wl_buffer before wl_buffer.release - is allowed as long as the underlying buffer storage isn't reused (this + is allowed as long as the underlying buffer storage isn't re-used (this can happen e.g. on client process termination). However, if the client destroys the wl_buffer before receiving the wl_buffer.release event and mutates the underlying buffer storage, the surface contents become @@ -2003,8 +2003,8 @@ before announcing capabilities. This event only sent once per seat object, and the name does not change over the lifetime of the wl_seat global. - Compositors may reuse the same seat name if the wl_seat global is - destroyed and recreated later. + Compositors may re-use the same seat name if the wl_seat global is + destroyed and re-created later. @@ -2972,8 +2972,8 @@ only sent once per output object, and the name does not change over the lifetime of the wl_output global. - Compositors may reuse the same output name if the wl_output global is - destroyed and recreated later. Compositors should avoid reusing the + Compositors may re-use the same output name if the wl_output global is + destroyed and re-created later. Compositors should avoid re-using the same name if possible. The name event will be followed by a done event. @@ -3288,7 +3288,7 @@ The compositor will emit a wl_display.delete_id event with the object ID of the registry and will no longer emit any events on the registry. The - client should reuse the object ID once it receives the + client should re-use the object ID once it receives the wl_display.delete_id event. Date: Tue, 12 May 2026 20:12:56 -0700 Subject: [PATCH 264/407] Use predefined names for constant keyboard and mouse IDs Fixes https://github.com/libsdl-org/SDL/issues/15563 --- src/events/SDL_keyboard.c | 24 ++++++++++++++++-------- src/events/SDL_mouse.c | 30 ++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 0945339e44..f6969e37ed 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -201,14 +201,22 @@ SDL_KeyboardID *SDL_GetKeyboards(int *count) const char *SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id) { const char *name = NULL; - if (!SDL_FindInHashTable(SDL_keyboard_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { - SDL_SetError("Keyboard %" SDL_PRIu32 " not found", instance_id); - return NULL; - } - if (!name) { - // SDL_strdup() failed during insert - SDL_OutOfMemory(); - return NULL; + + switch (instance_id) { + case SDL_GLOBAL_KEYBOARD_ID: + name = "Keyboard"; + break; + default: + if (!SDL_FindInHashTable(SDL_keyboard_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { + SDL_SetError("Keyboard %" SDL_PRIu32 " not found", instance_id); + return NULL; + } + if (!name) { + // SDL_strdup() failed during insert + SDL_OutOfMemory(); + return NULL; + } + break; } return name; } diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 5dd25d713a..96641495ae 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -422,14 +422,28 @@ SDL_MouseID *SDL_GetMice(int *count) const char *SDL_GetMouseNameForID(SDL_MouseID instance_id) { const char *name = NULL; - if (!SDL_FindInHashTable(SDL_mouse_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { - SDL_SetError("Mouse %" SDL_PRIu32 " not found", instance_id); - return NULL; - } - if (!name) { - // SDL_strdup() failed during insert - SDL_OutOfMemory(); - return NULL; + + switch (instance_id) { + case SDL_GLOBAL_MOUSE_ID: + name = "Mouse"; + break; + case SDL_TOUCH_MOUSEID: + name = "Touch"; + break; + case SDL_PEN_MOUSEID: + name = "Pen"; + break; + default: + if (!SDL_FindInHashTable(SDL_mouse_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { + SDL_SetError("Mouse %" SDL_PRIu32 " not found", instance_id); + return NULL; + } + if (!name) { + // SDL_strdup() failed during insert + SDL_OutOfMemory(); + return NULL; + } + break; } return name; } From 716c767b7e7099fb0e2fda9db59227a7e1d1d8a4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 12 May 2026 20:15:42 -0700 Subject: [PATCH 265/407] Document that you may receive mouse events with SDL_PEN_MOUSEID --- include/SDL3/SDL_events.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index 5b60e3df9b..ed6950ad3b 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -457,7 +457,7 @@ typedef struct SDL_MouseMotionEvent Uint32 reserved; Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ SDL_WindowID windowID; /**< The window with mouse focus, if any */ - SDL_MouseID which; /**< The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0 */ + SDL_MouseID which; /**< The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, SDL_PEN_MOUSEID for pen events, or 0 */ SDL_MouseButtonFlags state; /**< The current button state */ float x; /**< X coordinate, relative to window */ float y; /**< Y coordinate, relative to window */ From b1f390255a239940050f87cfb52dacb796e76728 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Wed, 13 May 2026 14:33:16 +0100 Subject: [PATCH 266/407] Allow formats with alpha channels for window textures Because the blend mode is explicitly set to SDL_BLENDMODE_NONE, it doesn't matter if there's a transparency channel in the texture format or not for opaque windows. This ensures that a 32-bit format is used with Metal instead of SDL_PIXELFORMAT_RGB565. --- src/video/SDL_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index d20d5eefea..6e3eeeeba8 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -424,7 +424,7 @@ static bool SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, !SDL_ISPIXELFORMAT_10BIT(texture_format) && !SDL_ISPIXELFORMAT_FLOAT(texture_format) && !SDL_ISPIXELFORMAT_INDEXED(texture_format) && - transparent == SDL_ISPIXELFORMAT_ALPHA(texture_format)) { + (!transparent || SDL_ISPIXELFORMAT_ALPHA(texture_format))) { *format = texture_format; break; } From 3dbd3e43e293931cfa7b356e09fca8e89aac5e53 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 13 May 2026 09:07:36 -0700 Subject: [PATCH 267/407] Return the touch device name for SDL_TOUCH_MOUSEID --- src/events/SDL_mouse.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 96641495ae..eaf1f2cdfd 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -428,7 +428,17 @@ const char *SDL_GetMouseNameForID(SDL_MouseID instance_id) name = "Mouse"; break; case SDL_TOUCH_MOUSEID: - name = "Touch"; + // We can't tell which touch device it was, just use the first one + { + SDL_TouchID *devices = SDL_GetTouchDevices(NULL); + if (devices) { + name = SDL_GetTouchDeviceName(devices[0]); + SDL_free(devices); + } + } + if (!name) { + name = "Touch"; + } break; case SDL_PEN_MOUSEID: name = "Pen"; From 70159c34f63abb234c3110c661c1e78579c3bc44 Mon Sep 17 00:00:00 2001 From: Eddy Jansson Date: Wed, 13 May 2026 18:05:39 +0200 Subject: [PATCH 268/407] DOS & Tray: Don't do NULL-checks before SDL_free() --- src/audio/dos/SDL_dosaudio_sb.c | 8 ++------ src/thread/dos/SDL_sysmutex.c | 4 +--- src/thread/dos/SDL_syssem.c | 4 +--- src/tray/unix/SDL_dbustray.c | 12 +++--------- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/audio/dos/SDL_dosaudio_sb.c b/src/audio/dos/SDL_dosaudio_sb.c index 881750d1d4..bf53adec4f 100644 --- a/src/audio/dos/SDL_dosaudio_sb.c +++ b/src/audio/dos/SDL_dosaudio_sb.c @@ -485,12 +485,8 @@ static void DOSSOUNDBLASTER_CloseDevice(SDL_AudioDevice *device) } // Free ring buffer resources. - if (hidden->ring_buffer) { - SDL_free(hidden->ring_buffer); - } - if (hidden->staging_buffer) { - SDL_free(hidden->staging_buffer); - } + SDL_free(hidden->ring_buffer); + SDL_free(hidden->staging_buffer); // Clear ISR-visible statics. isr_ring_buffer = NULL; diff --git a/src/thread/dos/SDL_sysmutex.c b/src/thread/dos/SDL_sysmutex.c index 69f70c0125..e9a73058f1 100644 --- a/src/thread/dos/SDL_sysmutex.c +++ b/src/thread/dos/SDL_sysmutex.c @@ -48,9 +48,7 @@ SDL_Mutex *SDL_CreateMutex(void) void SDL_DestroyMutex(SDL_Mutex *mutex) { - if (mutex) { - SDL_free(mutex); - } + SDL_free(mutex); } void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS diff --git a/src/thread/dos/SDL_syssem.c b/src/thread/dos/SDL_syssem.c index ea10d84d9d..a71b6bbc31 100644 --- a/src/thread/dos/SDL_syssem.c +++ b/src/thread/dos/SDL_syssem.c @@ -44,9 +44,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value) void SDL_DestroySemaphore(SDL_Semaphore *sem) { - if (sem) { - SDL_free(sem); - } + SDL_free(sem); } bool SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS) diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index c2c66679e7..3a015d55d7 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -561,9 +561,7 @@ void DestroyMenu(SDL_TrayMenu *menu) SDL_ListClear(&menu_dbus->menu); } - if (menu_dbus->array_representation) { - SDL_free(menu_dbus->array_representation); - } + SDL_free(menu_dbus->array_representation); SDL_free(menu_dbus); SDL_free(menu); @@ -656,9 +654,7 @@ void SetTrayTooltip(SDL_Tray *tray, const char *text) driver = (SDL_TrayDriverDBus *)tray->driver->internal; tray_dbus = (SDL_TrayDBus *)tray->internal; - if (tray_dbus->tooltip) { - SDL_free(tray_dbus->tooltip); - } + SDL_free(tray_dbus->tooltip); if (text) { tray_dbus->tooltip = SDL_strdup(text); @@ -907,9 +903,7 @@ SDL_TrayEntry **GetTrayEntries(SDL_TrayMenu *menu, int *count) menu_dbus = (SDL_TrayMenuDBus *)menu->internal; - if (menu_dbus->array_representation) { - SDL_free(menu_dbus->array_representation); - } + SDL_free(menu_dbus->array_representation); sz = SDL_ListCountEntries(&menu_dbus->menu); array_representation = SDL_calloc(sz + 1, sizeof(SDL_TrayEntry *)); From 4eb221881a3d51eae8aa42d1ced97bb994917325 Mon Sep 17 00:00:00 2001 From: Eddy Jansson Date: Wed, 13 May 2026 18:10:50 +0200 Subject: [PATCH 269/407] DOS: Replace SDL_memset() with SDL_zero*() --- src/core/dos/SDL_dos_scheduler.c | 4 ++-- src/thread/dos/SDL_systls.c | 4 ++-- src/video/dos/SDL_dosframebuffer.c | 4 ++-- src/video/dos/SDL_dosmodes.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/dos/SDL_dos_scheduler.c b/src/core/dos/SDL_dos_scheduler.c index 9c0163ce12..6800b7a17e 100644 --- a/src/core/dos/SDL_dos_scheduler.c +++ b/src/core/dos/SDL_dos_scheduler.c @@ -82,7 +82,7 @@ void DOS_SchedulerInit(void) return; } - SDL_memset(threads, 0, sizeof(threads)); + SDL_zeroa(threads); // Thread 0 is the main thread (already running) threads[0].state = DOS_THREAD_RUNNING; @@ -146,7 +146,7 @@ int DOS_CreateThread(int (*fn)(void *), void *arg, size_t stack_size) _go32_dpmi_lock_data(stack, stack_size); DOS_ThreadContext *ctx = &threads[tid]; - SDL_memset(ctx, 0, sizeof(*ctx)); + SDL_zerop(ctx); ctx->id = tid; ctx->state = DOS_THREAD_READY; ctx->stack_base = stack; diff --git a/src/thread/dos/SDL_systls.c b/src/thread/dos/SDL_systls.c index da9406f0a9..86220de356 100644 --- a/src/thread/dos/SDL_systls.c +++ b/src/thread/dos/SDL_systls.c @@ -34,7 +34,7 @@ static SDL_TLSData *tls_data[DOS_MAX_THREADS]; void SDL_SYS_InitTLSData(void) { - SDL_memset(tls_data, 0, sizeof(tls_data)); + SDL_zeroa(tls_data); } SDL_TLSData *SDL_SYS_GetTLSData(void) @@ -58,7 +58,7 @@ bool SDL_SYS_SetTLSData(SDL_TLSData *data) void SDL_SYS_QuitTLSData(void) { - SDL_memset(tls_data, 0, sizeof(tls_data)); + SDL_zeroa(tls_data); } #endif /* SDL_THREAD_DOS */ diff --git a/src/video/dos/SDL_dosframebuffer.c b/src/video/dos/SDL_dosframebuffer.c index 2a707c9526..85d6992d93 100644 --- a/src/video/dos/SDL_dosframebuffer.c +++ b/src/video/dos/SDL_dosframebuffer.c @@ -105,7 +105,7 @@ static SDL_Surface *GetConvertedCursorSurface(SDL_CursorData *curdata, SDL_Surfa // Track which palette indices are used by opaque pixels. bool used[256]; - SDL_memset(used, 0, sizeof(used)); + SDL_zeroa(used); // First pass: blit with BLENDMODE_NONE to get raw color-matched indices. SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); @@ -181,7 +181,7 @@ static SDL_Surface *CreateSystemSurface(SDL_VideoData *data, int w, int h, SDL_P // Initialize palette to all-black so that transitions start // from black instead of flashing uninitialized (white) colors. SDL_Color black[256]; - SDL_memset(black, 0, sizeof(black)); + SDL_zeroa(black); for (int i = 0; i < 256; i++) { black[i].a = SDL_ALPHA_OPAQUE; } diff --git a/src/video/dos/SDL_dosmodes.c b/src/video/dos/SDL_dosmodes.c index 2976caf8c9..2f9962ec13 100644 --- a/src/video/dos/SDL_dosmodes.c +++ b/src/video/dos/SDL_dosmodes.c @@ -529,7 +529,7 @@ bool DOSVESA_SetDisplayMode(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_displ // Clear the framebuffer { Uint8 zero_buf[320]; - SDL_memset(zero_buf, 0, sizeof(zero_buf)); + SDL_zeroa(zero_buf); Uint32 vga_base = (Uint32)VGA_MODE_13H_SEGMENT << 4; for (int row = 0; row < 200; row++) { dosmemput(zero_buf, 320, vga_base + row * 320); @@ -590,7 +590,7 @@ bool DOSVESA_SetDisplayMode(SDL_VideoDevice *device, SDL_VideoDisplay *sdl_displ Uint32 win_size_bytes = (Uint32)modedata->win_size * 1024; Uint32 win_base = (Uint32)modedata->win_a_segment << 4; Uint8 zero_buf[1024]; - SDL_memset(zero_buf, 0, sizeof(zero_buf)); + SDL_zeroa(zero_buf); Uint32 offset = 0; int current_bank = -1; From e8127a9a11a5d6d720062612d15ddc2c9c812648 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Sun, 3 May 2026 10:58:49 -0400 Subject: [PATCH 270/407] Fix #15500: deprecation warning on Android for slCreateEngine --- src/audio/openslES/SDL_openslES.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c index 0f49585d55..409d07150f 100644 --- a/src/audio/openslES/SDL_openslES.c +++ b/src/audio/openslES/SDL_openslES.c @@ -33,6 +33,11 @@ #include #include +// OpenSL ES is deprecated, but we still support it for now. +#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // HAVE_GCC_DIAGNOSTIC_PRAGMA #define NUM_BUFFERS 2 // -- Don't lower this! @@ -805,4 +810,8 @@ void OPENSLES_PauseDevices(void) } } +#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic pop +#endif // HAVE_GCC_DIAGNOSTIC_PRAGMA + #endif // SDL_AUDIO_DRIVER_OPENSLES From 9672f5b68b1f3f438bb86c65f8a3c198eb4b9eb1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 30 Apr 2026 19:59:15 -0400 Subject: [PATCH 271/407] android: Change how apps access their APK's "assets" directory. Now they can explicitly access it with "assets://" filenames, and SDL_GetBasePath() returns "assets://" Fixes #15347. Fixes #5044. --- docs/README-android.md | 18 +++++++++++++ src/core/android/SDL_android.c | 25 ++++++++++++++---- src/filesystem/SDL_filesystem.c | 30 ++++++++++++++-------- src/filesystem/android/SDL_sysfilesystem.c | 2 +- src/filesystem/posix/SDL_sysfsops.c | 16 +++++++++--- src/io/SDL_iostream.c | 5 ++-- 6 files changed, 72 insertions(+), 24 deletions(-) diff --git a/docs/README-android.md b/docs/README-android.md index 61e289fee8..d3526c0247 100644 --- a/docs/README-android.md +++ b/docs/README-android.md @@ -212,6 +212,24 @@ Any files you put in the "app/src/main/assets" directory of your project directory will get bundled into the application package and you can load them using the standard functions in SDL_iostream.h. +As of SDL 3.6.0, SDL APIs, such as SDL_EnumerateDirectory() and +SDL_IOFromFile(), understand paths that are prefixed with "assets://" and will +look for paths exclusively inside the APK's "assets" directory. Since this is +where app-specific data files are meant to be located, SDL_GetBasePath() on +Android now returns "assets://" to make this work as expected across platforms. +Note that SDL 3.2.28 to 3.6.0 returned "./" on Android, and before that, +SDL_GetBasePath() always returned NULL on this platform. + +Obviously, paths prefixed with "assets://" are only useful to SDL; other APIs, +like fopen(), will not understand them at all. + +As an alternate approach: SDL APIs on Android treat relative paths in a +special way. It will look for files under the path returned by +SDL_GetAndroidInternalStoragePath() first, and failing that, will attempt to +look for them as if they were prefixed by "assets://", with the relative path +starting in the base of the assets tree. Absolute paths never check against +internal storage or assets. + There are also a few Android specific functions that allow you to get other useful paths for saving and loading data: * SDL_GetAndroidInternalStoragePath() diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 3e24056bd5..27289bbba0 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1901,9 +1901,16 @@ static APKNode *FindAPKChildNode(APKNode *parent, const char *child) static const APKNode *FindAPKNode(const char *constpath) { + //SDL_Log("FindAPKNode('%s') ...", constpath); + if (SDL_strncmp(constpath, "assets://", 9) == 0) { + constpath += 9; + } + APKNode *parent = APKRootNode; if (!parent) { return NULL; + } else if (*constpath == '\0') { + return parent; } const size_t pathlen = SDL_strlen(constpath); @@ -2362,12 +2369,20 @@ static void Internal_Android_Destroy_AssetManager(void) static const char *GetAssetPath(const char *path) { - if (path && path[0] == '.' && path[1] == '/') { - path += 2; - while (*path == '/') { - ++path; - } + if (!path) { + return NULL; } + + if (path[0] == '.' && ((path[1] == '/') || (path[1] == '\0'))) { + path++; + } else if (SDL_strncmp(path, "assets://", 9) == 0) { + path += 9; + } + + while (*path == '/') { + ++path; + } + return path; } diff --git a/src/filesystem/SDL_filesystem.c b/src/filesystem/SDL_filesystem.c index dca0da5c99..bfce6a3292 100644 --- a/src/filesystem/SDL_filesystem.c +++ b/src/filesystem/SDL_filesystem.c @@ -371,20 +371,28 @@ char **SDL_InternalGlobDirectory(const char *path, const char *pattern, SDL_Glob return NULL; } - // if path ends with any slash, chop them off, so we don't confuse the pattern matcher later. char *pathcpy = NULL; size_t pathlen = SDL_strlen(path); - if ((pathlen > 1) && ((path[pathlen-1] == '/') || (path[pathlen-1] == '\\'))) { - pathcpy = SDL_strdup(path); - if (!pathcpy) { - return NULL; + + // if path ends with any slash, chop them off, so we don't confuse the pattern matcher later. + #ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(path, "assets://") == 0) { // don't chop '//' off this if we're looking for the root of the asset tree. + pathlen--; // we'll add a 1 again later. + } else + #endif + { + if ((pathlen > 1) && ((path[pathlen-1] == '/') || (path[pathlen-1] == '\\'))) { + pathcpy = SDL_strdup(path); + if (!pathcpy) { + return NULL; + } + char *ptr = &pathcpy[pathlen-1]; + while ((ptr > pathcpy) && ((*ptr == '/') || (*ptr == '\\'))) { + *(ptr--) = '\0'; + --pathlen; + } + path = pathcpy; } - char *ptr = &pathcpy[pathlen-1]; - while ((ptr > pathcpy) && ((*ptr == '/') || (*ptr == '\\'))) { - *(ptr--) = '\0'; - --pathlen; - } - path = pathcpy; } if (!pattern) { diff --git a/src/filesystem/android/SDL_sysfilesystem.c b/src/filesystem/android/SDL_sysfilesystem.c index 7eddd28774..1f50abf165 100644 --- a/src/filesystem/android/SDL_sysfilesystem.c +++ b/src/filesystem/android/SDL_sysfilesystem.c @@ -31,7 +31,7 @@ char *SDL_SYS_GetBasePath(void) { - return SDL_strdup("./"); + return SDL_strdup("assets://"); } char *SDL_SYS_GetPrefPath(const char *org, const char *app) diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index fd42876215..6183485b22 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -47,6 +47,13 @@ bool SDL_SYS_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback #if defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_IOS) if (*path != '/') { #ifdef SDL_PLATFORM_ANDROID + if (SDL_strncmp(path, "assets://", 9) == 0) { + char *pathwithsep = NULL; + SDL_asprintf(&pathwithsep, "%s%s", path, (path[SDL_strlen(path) - 1] != '/') ? "/" : ""); + const bool retval = pathwithsep ? Android_JNI_EnumerateAssetDirectory(pathwithsep, cb, userdata) : false; + SDL_free(pathwithsep); + return retval; + } SDL_asprintf(&apath, "%s/%s", SDL_GetAndroidInternalStoragePath(), path); #elif defined(SDL_PLATFORM_IOS) char *base = SDL_GetPrefPath("", ""); @@ -89,14 +96,13 @@ bool SDL_SYS_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback DIR *dir = opendir(pathwithsep); if (!dir) { -#ifdef SDL_PLATFORM_ANDROID // Maybe it's an asset...? +#ifdef SDL_PLATFORM_ANDROID // Maybe it's an asset... that didn't use an "assets://" URL? const bool retval = Android_JNI_EnumerateAssetDirectory(pathwithsep + extralen, cb, userdata); SDL_free(pathwithsep); return retval; -#else +#endif SDL_free(pathwithsep); return SDL_SetError("Can't open directory: %s", strerror(errno)); -#endif } SDL_EnumerationResult result = SDL_ENUM_CONTINUE; @@ -342,6 +348,8 @@ bool SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info) #ifdef SDL_PLATFORM_ANDROID if (*path == '/') { rc = stat(path, &statbuf); + } else if (SDL_strncmp(path, "assets://", 9) == 0) { + return Android_JNI_GetAssetPathInfo(path, info); } else { char *apath = NULL; SDL_asprintf(&apath, "%s/%s", SDL_GetAndroidInternalStoragePath(), path); @@ -351,7 +359,7 @@ bool SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info) rc = stat(apath, &statbuf); SDL_free(apath); } - if (rc < 0) { + if (rc < 0) { // Maybe it's an asset... that didn't use an "assets://" URL? return Android_JNI_GetAssetPathInfo(path, info); } #elif defined(SDL_PLATFORM_IOS) diff --git a/src/io/SDL_iostream.c b/src/io/SDL_iostream.c index 4f3b0606ad..6b19364678 100644 --- a/src/io/SDL_iostream.c +++ b/src/io/SDL_iostream.c @@ -1021,7 +1021,7 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode) } return SDL_IOFromFP(fp, true); - } else { + } else if (SDL_strncmp(file, "assets://", 9) != 0) { // Try opening it from internal storage if it's a relative path char *path = NULL; SDL_asprintf(&path, "%s/%s", SDL_GetAndroidInternalStoragePath(), file); @@ -1040,8 +1040,7 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode) } #endif // HAVE_STDIO_H - // Try to open the file from the asset system - + // Try to open the file from the asset system? void *iodata = NULL; if (!Android_JNI_FileOpen(&iodata, file, mode)) { return NULL; From c6b232f5d4478af7d2c2ebfe080450931c15f414 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Wed, 13 May 2026 20:51:02 +0100 Subject: [PATCH 272/407] Support loading JPEG images through SDL_LoadSurface() --- include/SDL3/SDL_surface.h | 60 ++++++++++++++-- src/dynapi/SDL_dynapi.exports | 2 + src/dynapi/SDL_dynapi.sym | 2 + src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 2 + src/video/SDL_stb.c | 110 ++++++++++++++++++++++++++++++ src/video/SDL_surface.c | 2 + src/video/SDL_surface_c.h | 1 + 8 files changed, 175 insertions(+), 6 deletions(-) diff --git a/include/SDL3/SDL_surface.h b/include/SDL3/SDL_surface.h index 885f8f5d98..1194596cd2 100644 --- a/include/SDL3/SDL_surface.h +++ b/include/SDL3/SDL_surface.h @@ -29,10 +29,10 @@ * provides a reasonable toolbox for transforming the data, including copying * between surfaces, filling rectangles in the image data, etc. * - * There is also a simple .bmp loader, SDL_LoadBMP(), and a simple .png - * loader, SDL_LoadPNG(). SDL itself does not provide loaders for other file - * formats, but there are several excellent external libraries that do, - * including its own satellite library, + * There is also a simple .bmp loader, SDL_LoadBMP(), a simple .png loader, + * SDL_LoadPNG(), and a simple .jpg loader, SDL_LoadJPG(). SDL itself does not + * provide loaders for other file formats, but there are several excellent + * external libraries that do, including its own satellite library, * [SDL_image](https://wiki.libsdl.org/SDL3_image) * . * @@ -510,7 +510,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_LockSurface(SDL_Surface *surface); extern SDL_DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface); /** - * Load a BMP or PNG image from a seekable SDL data stream. + * Load a BMP, PNG or JPEG image from a seekable SDL data stream. * * The new surface should be freed with SDL_DestroySurface(). Not doing so * will result in a memory leak. @@ -531,7 +531,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface); extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadSurface_IO(SDL_IOStream *src, bool closeio); /** - * Load a BMP or PNG image from a file. + * Load a BMP, PNG or JPEG image from a file. * * The new surface should be freed with SDL_DestroySurface(). Not doing so * will result in a memory leak. @@ -729,6 +729,54 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SavePNG_IO(SDL_Surface *surface, SDL_IOStre */ extern SDL_DECLSPEC bool SDLCALL SDL_SavePNG(SDL_Surface *surface, const char *file); +/** + * Load a JPEG image from a seekable SDL data stream. + * + * This is intended as a convenience function for loading images from trusted + * sources. If you want to load arbitrary images you should use libjpeg or + * another image loading library designed with security in mind. + * + * The new surface should be freed with SDL_DestroySurface(). Not doing so + * will result in a memory leak. + * + * \param src the data stream for the surface. + * \param closeio if true, calls SDL_CloseIO() on `src` before returning, even + * in the case of an error. + * \returns a pointer to a new SDL_Surface structure or NULL on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.6.0. + * + * \sa SDL_DestroySurface + * \sa SDL_LoadJPG + */ +extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadJPG_IO(SDL_IOStream *src, bool closeio); + +/** + * Load a JPEG image from a file. + * + * This is intended as a convenience function for loading images from trusted + * sources. If you want to load arbitrary images you should use libjpeg or + * another image loading library designed with security in mind. + * + * The new surface should be freed with SDL_DestroySurface(). Not doing so + * will result in a memory leak. + * + * \param file the JPG file to load. + * \returns a pointer to a new SDL_Surface structure or NULL on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.6.0. + * + * \sa SDL_DestroySurface + * \sa SDL_LoadJPG_IO + */ +extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadJPG(const char *file); + /** * Set the RLE acceleration hint for a surface. * diff --git a/src/dynapi/SDL_dynapi.exports b/src/dynapi/SDL_dynapi.exports index 5953db3622..67600f2b7b 100644 --- a/src/dynapi/SDL_dynapi.exports +++ b/src/dynapi/SDL_dynapi.exports @@ -1285,3 +1285,5 @@ _SDL_SetGPURenderStateStorageBuffers _SDL_GDKSuspendRenderer _SDL_GDKResumeRenderer _SDL_IsPhone +_SDL_LoadJPG_IO +_SDL_LoadJPG diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index a16d0f79c3..3fdc470a33 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1286,6 +1286,8 @@ SDL3_0.0.0 { SDL_GDKSuspendRenderer; SDL_GDKResumeRenderer; SDL_IsPhone; + SDL_LoadJPG_IO; + SDL_LoadJPG; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c60b5223d4..7b88affdc6 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1312,3 +1312,5 @@ #define SDL_GDKSuspendRenderer SDL_GDKSuspendRenderer_REAL #define SDL_GDKResumeRenderer SDL_GDKResumeRenderer_REAL #define SDL_IsPhone SDL_IsPhone_REAL +#define SDL_LoadJPG_IO SDL_LoadJPG_IO_REAL +#define SDL_LoadJPG SDL_LoadJPG_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 0d2d4ce5c7..24a5afad98 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1320,3 +1320,5 @@ SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageBuffers,(SDL_GPURenderState *a, SDL_DYNAPI_PROC(void,SDL_GDKSuspendRenderer,(SDL_Renderer *a),(a),) SDL_DYNAPI_PROC(void,SDL_GDKResumeRenderer,(SDL_Renderer *a),(a),) SDL_DYNAPI_PROC(bool,SDL_IsPhone,(void),(),return) +SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG_IO,(SDL_IOStream *a,bool b),(a,b),return) +SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG,(const char *a),(a),return) diff --git a/src/video/SDL_stb.c b/src/video/SDL_stb.c index 732b4ef016..fe5d0c70e9 100644 --- a/src/video/SDL_stb.c +++ b/src/video/SDL_stb.c @@ -363,6 +363,116 @@ static SDL_Surface *SDL_LoadSTB_IO(SDL_IOStream *src) } #endif // SDL_HAVE_STB +/* FIXME: This is a copypaste from JPEGLIB! Pull that out of the ifdefs */ +/* Define this for quicker (but less perfect) JPEG identification */ +#define FAST_IS_JPEG + +/* See if an image is contained in a data source */ +bool SDL_IsJPG(SDL_IOStream *src) +{ + Sint64 start; + bool is_JPG; + bool in_scan; + Uint8 magic[4]; + + /* This detection code is by Steaphan Greene */ + /* Blame me, not Sam, if this doesn't work right. */ + /* And don't forget to report the problem to the the sdl list too! */ + + if (!src) { + return false; + } + + start = SDL_TellIO(src); + is_JPG = false; + in_scan = false; + if (SDL_ReadIO(src, magic, 2) == 2) { + if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) { + is_JPG = true; + while (is_JPG) { + if (SDL_ReadIO(src, magic, 2) != 2) { + is_JPG = false; + } else if ( (magic[0] != 0xFF) && !in_scan ) { + is_JPG = false; + } else if ( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) { + /* Extra padding in JPEG (legal) */ + /* or this is data and we are scanning */ + SDL_SeekIO(src, -1, SDL_IO_SEEK_CUR); + } else if (magic[1] == 0xD9) { + /* Got to end of good JPEG */ + break; + } else if ( in_scan && (magic[1] == 0x00) ) { + /* This is an encoded 0xFF within the data */ + } else if ( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) { + /* These have nothing else */ + } else if (SDL_ReadIO(src, magic+2, 2) != 2) { + is_JPG = false; + } else { + /* Yes, it's big-endian */ + Sint64 innerStart; + Uint32 size; + Sint64 end; + innerStart = SDL_TellIO(src); + size = (magic[2] << 8) + magic[3]; + end = SDL_SeekIO(src, size-2, SDL_IO_SEEK_CUR); + if ( end != innerStart + size - 2 ) { + is_JPG = false; + } + if ( magic[1] == 0xDA ) { + /* Now comes the actual JPEG meat */ +#ifdef FAST_IS_JPEG + /* Ok, I'm convinced. It is a JPEG. */ + break; +#else + /* I'm not convinced. Prove it! */ + in_scan = true; +#endif + } + } + } + } + } + SDL_SeekIO(src, start, SDL_IO_SEEK_SET); + return is_JPG; +} + +SDL_Surface *SDL_LoadJPG_IO(SDL_IOStream *src, bool closeio) +{ + SDL_Surface *surface = NULL; + + CHECK_PARAM(!src) { + SDL_InvalidParamError("src"); + goto done; + } + + if (!SDL_IsJPG(src)) { + SDL_SetError("File is not a JPEG file"); + goto done; + } + +#ifdef SDL_HAVE_STB + surface = SDL_LoadSTB_IO(src); +#else + SDL_SetError("SDL not built with STB image support"); +#endif // SDL_HAVE_STB + +done: + if (src && closeio) { + SDL_CloseIO(src); + } + return surface; +} + +SDL_Surface *SDL_LoadJPG(const char *file) +{ + SDL_IOStream *stream = SDL_IOFromFile(file, "rb"); + if (!stream) { + return NULL; + } + + return SDL_LoadJPG_IO(stream, true); +} + bool SDL_IsPNG(SDL_IOStream *src) { Sint64 start; diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 8164f76fbc..6a03fad732 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -3118,6 +3118,8 @@ SDL_Surface *SDL_LoadSurface_IO(SDL_IOStream *src, bool closeio) return SDL_LoadBMP_IO(src, closeio); } else if (SDL_IsPNG(src)) { return SDL_LoadPNG_IO(src, closeio); + } else if (SDL_IsJPG(src)) { + return SDL_LoadJPG_IO(src, closeio); } else { if (closeio) { SDL_CloseIO(src); diff --git a/src/video/SDL_surface_c.h b/src/video/SDL_surface_c.h index 168f05e515..231cc7430b 100644 --- a/src/video/SDL_surface_c.h +++ b/src/video/SDL_surface_c.h @@ -94,6 +94,7 @@ extern float SDL_GetSurfaceHDRHeadroom(SDL_Surface *surface, SDL_Colorspace colo extern SDL_Surface *SDL_GetSurfaceImage(SDL_Surface *surface, float display_scale); extern SDL_Surface *SDL_ConvertSurfaceRect(SDL_Surface *surface, const SDL_Rect *rect, SDL_PixelFormat format); extern bool SDL_IsBMP(SDL_IOStream *src); +extern bool SDL_IsJPG(SDL_IOStream *src); extern bool SDL_IsPNG(SDL_IOStream *src); #endif // SDL_surface_c_h_ From c247f06f01477d319abf6981c860e3a1ed02b05e Mon Sep 17 00:00:00 2001 From: Joel Auterson Date: Thu, 14 May 2026 01:01:33 +0100 Subject: [PATCH 273/407] Add libusb-1.0-0-dev to Linux deps doc libusb-1.0-0 is needed to enable SDL_HIDAPI_LIBUSB. It does not work with the `libusb-dev` package on Ubuntu, which is for the older version. --- docs/README-linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README-linux.md b/docs/README-linux.md index edd7019ed9..ced2ebbd58 100644 --- a/docs/README-linux.md +++ b/docs/README-linux.md @@ -20,7 +20,7 @@ Ubuntu 18.04, all available features enabled: libaudio-dev libfribidi-dev libjack-dev libsndio-dev libx11-dev libxext-dev \ libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \ libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ - libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libthai-dev + libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libthai-dev libusb-1.0-0-dev Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev` to that command line. From 4884dbbe5610d6cd444b03ee694e63f086fa5825 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 13 May 2026 20:14:50 -0700 Subject: [PATCH 274/407] Added SDL_SendGamepadEffect() support for the new Steam Controller --- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index b911dae02e..812a9c4059 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -475,6 +475,13 @@ static bool HIDAPI_DriverSteamTriton_SetJoystickLED(SDL_HIDAPI_Device *device, S static bool HIDAPI_DriverSteamTriton_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) { + if (size == HID_FEATURE_REPORT_BYTES) { + int rc = SDL_hid_send_feature_report(device->dev, data, size); + if (rc != size) { + return false; + } + return true; + } return SDL_Unsupported(); } From e50faf4e6aa48d2684818420201260e0c4caf957 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Mon, 11 May 2026 19:19:07 +0100 Subject: [PATCH 275/407] Support the full set of standard CSS cursors --- .../main/java/org/libsdl/app/SDLActivity.java | 128 +++++++++++++----- include/SDL3/SDL_mouse.h | 14 ++ src/video/SDL_video.c | 50 ++++++- src/video/cocoa/SDL_cocoamouse.m | 38 ++++++ src/video/haiku/SDL_bvideo.cc | 14 ++ src/video/qnx/SDL_qnxmouse.c | 33 +++++ src/video/wayland/SDL_waylandmouse.c | 44 +++++- src/video/windows/SDL_windowsmouse.c | 68 +++++----- src/video/x11/SDL_x11mouse.c | 14 ++ test/testcustomcursor.c | 28 ++++ test/testwm.c | 50 ++++--- 11 files changed, 391 insertions(+), 90 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 0491ccab20..9df90cd446 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -170,26 +170,40 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Cursor types // private static final int SDL_SYSTEM_CURSOR_NONE = -1; - private static final int SDL_SYSTEM_CURSOR_ARROW = 0; - private static final int SDL_SYSTEM_CURSOR_IBEAM = 1; + private static final int SDL_SYSTEM_CURSOR_DEFAULT = 0; + private static final int SDL_SYSTEM_CURSOR_TEXT = 1; private static final int SDL_SYSTEM_CURSOR_WAIT = 2; private static final int SDL_SYSTEM_CURSOR_CROSSHAIR = 3; - private static final int SDL_SYSTEM_CURSOR_WAITARROW = 4; - private static final int SDL_SYSTEM_CURSOR_SIZENWSE = 5; - private static final int SDL_SYSTEM_CURSOR_SIZENESW = 6; - private static final int SDL_SYSTEM_CURSOR_SIZEWE = 7; - private static final int SDL_SYSTEM_CURSOR_SIZENS = 8; - private static final int SDL_SYSTEM_CURSOR_SIZEALL = 9; - private static final int SDL_SYSTEM_CURSOR_NO = 10; - private static final int SDL_SYSTEM_CURSOR_HAND = 11; - private static final int SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT = 12; - private static final int SDL_SYSTEM_CURSOR_WINDOW_TOP = 13; - private static final int SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT = 14; - private static final int SDL_SYSTEM_CURSOR_WINDOW_RIGHT = 15; - private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT = 16; - private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOM = 17; - private static final int SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT = 18; - private static final int SDL_SYSTEM_CURSOR_WINDOW_LEFT = 19; + private static final int SDL_SYSTEM_CURSOR_PROGRESS = 4; + private static final int SDL_SYSTEM_CURSOR_NWSE_RESIZE = 5; + private static final int SDL_SYSTEM_CURSOR_NESW_RESIZE = 6; + private static final int SDL_SYSTEM_CURSOR_EW_RESIZE = 7; + private static final int SDL_SYSTEM_CURSOR_NS_RESIZE = 8; + private static final int SDL_SYSTEM_CURSOR_MOVE = 9; + private static final int SDL_SYSTEM_CURSOR_NOT_ALLOWED = 10; + private static final int SDL_SYSTEM_CURSOR_POINTER = 11; + private static final int SDL_SYSTEM_CURSOR_NW_RESIZE = 12; + private static final int SDL_SYSTEM_CURSOR_N_RESIZE = 13; + private static final int SDL_SYSTEM_CURSOR_NE_RESIZE = 14; + private static final int SDL_SYSTEM_CURSOR_E_RESIZE = 15; + private static final int SDL_SYSTEM_CURSOR_SE_RESIZE = 16; + private static final int SDL_SYSTEM_CURSOR_S_RESIZE = 17; + private static final int SDL_SYSTEM_CURSOR_SW_RESIZE = 18; + private static final int SDL_SYSTEM_CURSOR_W_RESIZE = 19; + private static final int SDL_SYSTEM_CURSOR_CONTEXT_MENU = 20; + private static final int SDL_SYSTEM_CURSOR_HELP = 21; + private static final int SDL_SYSTEM_CURSOR_CELL = 22; + private static final int SDL_SYSTEM_CURSOR_VERTICAL_TEXT = 23; + private static final int SDL_SYSTEM_CURSOR_ALIAS = 24; + private static final int SDL_SYSTEM_CURSOR_COPY = 25; + private static final int SDL_SYSTEM_CURSOR_NO_DROP = 26; + private static final int SDL_SYSTEM_CURSOR_GRAB = 27; + private static final int SDL_SYSTEM_CURSOR_GRABBING = 28; + private static final int SDL_SYSTEM_CURSOR_COL_RESIZE = 29; + private static final int SDL_SYSTEM_CURSOR_ROW_RESIZE = 30; + private static final int SDL_SYSTEM_CURSOR_ALL_SCROLL = 31; + private static final int SDL_SYSTEM_CURSOR_ZOOM_IN = 32; + private static final int SDL_SYSTEM_CURSOR_ZOOM_OUT = 33; protected static final int SDL_ORIENTATION_UNKNOWN = 0; protected static final int SDL_ORIENTATION_LANDSCAPE = 1; @@ -1862,10 +1876,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static boolean setSystemCursor(int cursorID) { int cursor_type = 0; //PointerIcon.TYPE_NULL; switch (cursorID) { - case SDL_SYSTEM_CURSOR_ARROW: + case SDL_SYSTEM_CURSOR_DEFAULT: cursor_type = 1000; //PointerIcon.TYPE_ARROW; break; - case SDL_SYSTEM_CURSOR_IBEAM: + case SDL_SYSTEM_CURSOR_TEXT: cursor_type = 1008; //PointerIcon.TYPE_TEXT; break; case SDL_SYSTEM_CURSOR_WAIT: @@ -1874,54 +1888,96 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh case SDL_SYSTEM_CURSOR_CROSSHAIR: cursor_type = 1007; //PointerIcon.TYPE_CROSSHAIR; break; - case SDL_SYSTEM_CURSOR_WAITARROW: + case SDL_SYSTEM_CURSOR_PROGRESS: cursor_type = 1004; //PointerIcon.TYPE_WAIT; break; - case SDL_SYSTEM_CURSOR_SIZENWSE: + case SDL_SYSTEM_CURSOR_NWSE_RESIZE: cursor_type = 1017; //PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_SIZENESW: + case SDL_SYSTEM_CURSOR_NESW_RESIZE: cursor_type = 1016; //PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_SIZEWE: + case SDL_SYSTEM_CURSOR_EW_RESIZE: cursor_type = 1014; //PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_SIZENS: + case SDL_SYSTEM_CURSOR_NS_RESIZE: cursor_type = 1015; //PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_SIZEALL: + case SDL_SYSTEM_CURSOR_MOVE: cursor_type = 1020; //PointerIcon.TYPE_GRAB; break; - case SDL_SYSTEM_CURSOR_NO: + case SDL_SYSTEM_CURSOR_NOT_ALLOWED: cursor_type = 1012; //PointerIcon.TYPE_NO_DROP; break; - case SDL_SYSTEM_CURSOR_HAND: + case SDL_SYSTEM_CURSOR_POINTER: cursor_type = 1002; //PointerIcon.TYPE_HAND; break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: + case SDL_SYSTEM_CURSOR_NW_RESIZE: cursor_type = 1017; //PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_TOP: + case SDL_SYSTEM_CURSOR_N_RESIZE: cursor_type = 1015; //PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: + case SDL_SYSTEM_CURSOR_NE_RESIZE: cursor_type = 1016; //PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: + case SDL_SYSTEM_CURSOR_E_RESIZE: cursor_type = 1014; //PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: + case SDL_SYSTEM_CURSOR_SE_RESIZE: cursor_type = 1017; //PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: + case SDL_SYSTEM_CURSOR_S_RESIZE: cursor_type = 1015; //PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: + case SDL_SYSTEM_CURSOR_SW_RESIZE: cursor_type = 1016; //PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW; break; - case SDL_SYSTEM_CURSOR_WINDOW_LEFT: + case SDL_SYSTEM_CURSOR_W_RESIZE: cursor_type = 1014; //PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; break; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + cursor_type = 1001; //PointerIcon.TYPE_CONTEXT_MENU; + break; + case SDL_SYSTEM_CURSOR_HELP: + cursor_type = 1003; //PointerIcon.TYPE_HELP; + break; + case SDL_SYSTEM_CURSOR_CELL: + cursor_type = 1006; //PointerIcon.TYPE_CELL; + break; + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: + cursor_type = 1009; //PointerIcon.TYPE_VERTICAL_TEXT; + break; + case SDL_SYSTEM_CURSOR_ALIAS: + cursor_type = 1010; //PointerIcon.TYPE_ALIAS; + break; + case SDL_SYSTEM_CURSOR_COPY: + cursor_type = 1011; //PointerIcon.TYPE_COPY; + break; + case SDL_SYSTEM_CURSOR_NO_DROP: + cursor_type = 1012; //PointerIcon.TYPE_NO_DROP; + break; + case SDL_SYSTEM_CURSOR_GRAB: + cursor_type = 1020; //PointerIcon.TYPE_GRAB; + break; + case SDL_SYSTEM_CURSOR_GRABBING: + cursor_type = 1021; //PointerIcon.TYPE_GRABBING; + break; + case SDL_SYSTEM_CURSOR_COL_RESIZE: + cursor_type = 1014; //PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; + break; + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + cursor_type = 1015; //PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; + break; + case SDL_SYSTEM_CURSOR_ALL_SCROLL: + cursor_type = 1013; //PointerIcon.TYPE_ALL_SCROLL; + break; + case SDL_SYSTEM_CURSOR_ZOOM_IN: + cursor_type = 1018; //PointerIcon.TYPE_ZOOM_IN; + break; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + cursor_type = 1019; //PointerIcon.TYPE_ZOOM_OUT; + break; } if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { try { diff --git a/include/SDL3/SDL_mouse.h b/include/SDL3/SDL_mouse.h index fb03c0178d..a5227d89d5 100644 --- a/include/SDL3/SDL_mouse.h +++ b/include/SDL3/SDL_mouse.h @@ -116,6 +116,20 @@ typedef enum SDL_SystemCursor SDL_SYSTEM_CURSOR_S_RESIZE, /**< Window resize bottom. May be NS_RESIZE. */ SDL_SYSTEM_CURSOR_SW_RESIZE, /**< Window resize bottom-left. May be NESW_RESIZE. */ SDL_SYSTEM_CURSOR_W_RESIZE, /**< Window resize left. May be EW_RESIZE. */ + SDL_SYSTEM_CURSOR_CONTEXT_MENU, /**< A context menu is available for the object under the cursor. */ + SDL_SYSTEM_CURSOR_HELP, /**< Help is available for the object under the cursor. */ + SDL_SYSTEM_CURSOR_CELL, /**< A set of cells may be selected. */ + SDL_SYSTEM_CURSOR_VERTICAL_TEXT,/**< Text selection. May be TEXT */ + SDL_SYSTEM_CURSOR_ALIAS, /**< A shortcut is to be created. */ + SDL_SYSTEM_CURSOR_COPY, /**< Something is to be copied. */ + SDL_SYSTEM_CURSOR_NO_DROP, /**< The dragged item cannot be dropped at this location. May be NOT_ALLOWED. */ + SDL_SYSTEM_CURSOR_GRAB, /**< The object under the cursor can be grabbed */ + SDL_SYSTEM_CURSOR_GRABBING, /**< An object is currently being grabbed. */ + SDL_SYSTEM_CURSOR_COL_RESIZE, /**< Column resize. May be EW_RESIZE. */ + SDL_SYSTEM_CURSOR_ROW_RESIZE, /**< Row resize. May be NS_RESIZE. */ + SDL_SYSTEM_CURSOR_ALL_SCROLL, /**< Four pointed arrow pointing north, south, east, and west. */ + SDL_SYSTEM_CURSOR_ZOOM_IN, /**< Zoom in. */ + SDL_SYSTEM_CURSOR_ZOOM_OUT, /**< Zoom out. */ SDL_SYSTEM_CURSOR_COUNT } SDL_SystemCursor; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 6e3eeeeba8..86826b8b61 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -6463,7 +6463,10 @@ const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name return "ns-resize"; case SDL_SYSTEM_CURSOR_MOVE: - return "all-scroll"; + if (fallback_name) { + *fallback_name = "all-scroll"; + } + return "move"; case SDL_SYSTEM_CURSOR_NOT_ALLOWED: return "not-allowed"; @@ -6495,6 +6498,51 @@ const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name case SDL_SYSTEM_CURSOR_W_RESIZE: return "w-resize"; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + return "context-menu"; + + case SDL_SYSTEM_CURSOR_HELP: + return "help"; + + case SDL_SYSTEM_CURSOR_CELL: + return "cell"; + + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: + return "vertical-text"; + + case SDL_SYSTEM_CURSOR_ALIAS: + return "alias"; + + case SDL_SYSTEM_CURSOR_COPY: + return "copy"; + + case SDL_SYSTEM_CURSOR_NO_DROP: + return "no-drop"; + + case SDL_SYSTEM_CURSOR_GRAB: + return "grab"; + + case SDL_SYSTEM_CURSOR_GRABBING: + return "grabbing"; + + case SDL_SYSTEM_CURSOR_COL_RESIZE: + return "col-resize"; + + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + return "row-resize"; + + case SDL_SYSTEM_CURSOR_ALL_SCROLL: + if (fallback_name) { + *fallback_name = "move"; + } + return "all-scroll"; + + case SDL_SYSTEM_CURSOR_ZOOM_IN: + return "zoom-in"; + + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + return "zoom-out"; + default: return "default"; } diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 8fb9cc2328..1cfd23ad3f 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -200,9 +200,11 @@ static SDL_Cursor *Cocoa_CreateSystemCursor(SDL_SystemCursor id) nscursor = LoadHiddenSystemCursor(@"resizenorthsouth", @selector(resizeUpDownCursor)); break; case SDL_SYSTEM_CURSOR_MOVE: + case SDL_SYSTEM_CURSOR_ALL_SCROLL: nscursor = LoadHiddenSystemCursor(@"move", @selector(closedHandCursor)); break; case SDL_SYSTEM_CURSOR_NOT_ALLOWED: + case SDL_SYSTEM_CURSOR_NO_DROP: nscursor = [NSCursor operationNotAllowedCursor]; break; case SDL_SYSTEM_CURSOR_POINTER: @@ -232,6 +234,42 @@ static SDL_Cursor *Cocoa_CreateSystemCursor(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_W_RESIZE: nscursor = LoadHiddenSystemCursor(@"resizeeastwest", @selector(resizeLeftRightCursor)); break; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + nscursor = [NSCursor contextualMenuCursor]; + break; + case SDL_SYSTEM_CURSOR_HELP: + nscursor = LoadHiddenSystemCursor(@"help", @selector(helpCursor)); + break; + case SDL_SYSTEM_CURSOR_CELL: + nscursor = LoadHiddenSystemCursor(@"cell", @selector(cellCursor)); + break; + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: + nscursor = [NSCursor IBeamCursorForVerticalLayout]; + break; + case SDL_SYSTEM_CURSOR_ALIAS: + nscursor = [NSCursor dragLinkCursor]; + break; + case SDL_SYSTEM_CURSOR_COPY: + nscursor = [NSCursor dragCopyCursor]; + break; + case SDL_SYSTEM_CURSOR_GRAB: + nscursor = [NSCursor openHandCursor]; + break; + case SDL_SYSTEM_CURSOR_GRABBING: + nscursor = [NSCursor closedHandCursor]; + break; + case SDL_SYSTEM_CURSOR_COL_RESIZE: + nscursor = [NSCursor resizeLeftRightCursor]; + break; + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + nscursor = [NSCursor resizeUpDownCursor]; + break; + case SDL_SYSTEM_CURSOR_ZOOM_IN: + nscursor = LoadHiddenSystemCursor(@"zoomin", @selector(zoomInCursor)); + break; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + nscursor = LoadHiddenSystemCursor(@"zoomout", @selector(zoomOutCursor)); + break; default: SDL_assert(!"Unknown system cursor"); return NULL; diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index 9297704a7a..4ed466fa6c 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -173,6 +173,20 @@ static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id) CURSORCASE(S_RESIZE, RESIZE_NORTH_SOUTH); CURSORCASE(SW_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); CURSORCASE(W_RESIZE, RESIZE_EAST_WEST); + CURSORCASE(CONTEXT_MENU, CONTEXT_MENU); + CURSORCASE(HELP, HELP); + CURSORCASE(CELL, CROSS_HAIR); + CURSORCASE(VERTICAL_TEXT, I_BEAM_HORIZONTAL); + CURSORCASE(ALIAS, CREATE_LINK); + CURSORCASE(COPY, COPY); + CURSORCASE(NO_DROP, NOT_ALLOWED); + CURSORCASE(GRAB, GRAB); + CURSORCASE(GRABBING, GRABBING); + CURSORCASE(COL_RESIZE, RESIZE_EAST_WEST); + CURSORCASE(ROW_RESIZE, RESIZE_NORTH_SOUTH); + CURSORCASE(ALL_SCROLL, MOVE); + CURSORCASE(ZOOM_IN, ZOOM_IN); + CURSORCASE(ZOOM_OUT, ZOOM_OUT); #undef CURSORCASE default: SDL_assert(0); diff --git a/src/video/qnx/SDL_qnxmouse.c b/src/video/qnx/SDL_qnxmouse.c index 849c62d595..585006ecbd 100644 --- a/src/video/qnx/SDL_qnxmouse.c +++ b/src/video/qnx/SDL_qnxmouse.c @@ -36,15 +36,19 @@ static int SDLToScreenCursorShape(SDL_SystemCursor id) { case SDL_SYSTEM_CURSOR_DEFAULT: case SDL_SYSTEM_CURSOR_NOT_ALLOWED: + case SDL_SYSTEM_CURSOR_NO_DROP: shape = SCREEN_CURSOR_SHAPE_ARROW; break; case SDL_SYSTEM_CURSOR_TEXT: + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: shape = SCREEN_CURSOR_SHAPE_IBEAM; break; case SDL_SYSTEM_CURSOR_WAIT: + case SDL_SYSTEM_CURSOR_PROGRESS: shape = SCREEN_CURSOR_SHAPE_WAIT; break; case SDL_SYSTEM_CURSOR_CROSSHAIR: + case SDL_SYSTEM_CURSOR_CELL: shape = SCREEN_CURSOR_SHAPE_CROSS; break; case SDL_SYSTEM_CURSOR_NWSE_RESIZE: @@ -52,11 +56,40 @@ static int SDLToScreenCursorShape(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_EW_RESIZE: case SDL_SYSTEM_CURSOR_NS_RESIZE: case SDL_SYSTEM_CURSOR_MOVE: + case SDL_SYSTEM_CURSOR_NW_RESIZE: + case SDL_SYSTEM_CURSOR_N_RESIZE: + case SDL_SYSTEM_CURSOR_NE_RESIZE: + case SDL_SYSTEM_CURSOR_E_RESIZE: + case SDL_SYSTEM_CURSOR_SE_RESIZE: + case SDL_SYSTEM_CURSOR_S_RESIZE: + case SDL_SYSTEM_CURSOR_SW_RESIZE: + case SDL_SYSTEM_CURSOR_W_RESIZE: + case SDL_SYSTEM_CURSOR_COL_RESIZE: + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + case SDL_SYSTEM_CURSOR_ALL_SCROLL: shape = SCREEN_CURSOR_SHAPE_MOVE; break; case SDL_SYSTEM_CURSOR_POINTER: + case SDL_SYSTEM_CURSOR_HELP: + case SDL_SYSTEM_CURSOR_ALIAS: + case SDL_SYSTEM_CURSOR_COPY: shape = SCREEN_CURSOR_SHAPE_HAND; break; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + shape = SCREEN_CURSOR_SHAPE_MENU; + break; + case SDL_SYSTEM_CURSOR_GRAB: + shape = SCREEN_CURSOR_SHAPE_GRAB; + break; + case SDL_SYSTEM_CURSOR_GRABBING: + shape = SCREEN_CURSOR_SHAPE_GRABBING; + break; + case SDL_SYSTEM_CURSOR_ZOOM_IN: + shape = SCREEN_CURSOR_SHAPE_ZOOM_IN; + break; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + shape = SCREEN_CURSOR_SHAPE_ZOOM_OUT; + break; default: break; } diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index 1a23544d64..92db17158e 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -989,7 +989,7 @@ static enum wp_cursor_shape_device_v1_shape Wayland_GetSystemCursorShape(SDL_Sys shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE; break; case SDL_SYSTEM_CURSOR_MOVE: - shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL; + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE; break; case SDL_SYSTEM_CURSOR_NOT_ALLOWED: shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED; @@ -1021,6 +1021,48 @@ static enum wp_cursor_shape_device_v1_shape Wayland_GetSystemCursorShape(SDL_Sys case SDL_SYSTEM_CURSOR_W_RESIZE: shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_W_RESIZE; break; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CONTEXT_MENU; + break; + case SDL_SYSTEM_CURSOR_HELP: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP; + break; + case SDL_SYSTEM_CURSOR_CELL: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CELL; + break; + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_VERTICAL_TEXT; + break; + case SDL_SYSTEM_CURSOR_ALIAS: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALIAS; + break; + case SDL_SYSTEM_CURSOR_COPY: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COPY; + break; + case SDL_SYSTEM_CURSOR_NO_DROP: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP; + break; + case SDL_SYSTEM_CURSOR_GRAB: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB; + break; + case SDL_SYSTEM_CURSOR_GRABBING: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING; + break; + case SDL_SYSTEM_CURSOR_COL_RESIZE: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE; + break; + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE; + break; + case SDL_SYSTEM_CURSOR_ALL_SCROLL: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL; + break; + case SDL_SYSTEM_CURSOR_ZOOM_IN: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_IN; + break; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_OUT; + break; default: SDL_assert(0); // Should never be here... shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT; diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index 3e7772b451..5bf634b7c2 100644 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -490,62 +490,62 @@ static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id) name = IDC_ARROW; break; case SDL_SYSTEM_CURSOR_TEXT: + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: name = IDC_IBEAM; break; case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break; case SDL_SYSTEM_CURSOR_CROSSHAIR: + case SDL_SYSTEM_CURSOR_CELL: name = IDC_CROSS; break; case SDL_SYSTEM_CURSOR_PROGRESS: name = IDC_APPSTARTING; break; case SDL_SYSTEM_CURSOR_NWSE_RESIZE: - name = IDC_SIZENWSE; - break; - case SDL_SYSTEM_CURSOR_NESW_RESIZE: - name = IDC_SIZENESW; - break; - case SDL_SYSTEM_CURSOR_EW_RESIZE: - name = IDC_SIZEWE; - break; - case SDL_SYSTEM_CURSOR_NS_RESIZE: - name = IDC_SIZENS; - break; - case SDL_SYSTEM_CURSOR_MOVE: - name = IDC_SIZEALL; - break; - case SDL_SYSTEM_CURSOR_NOT_ALLOWED: - name = IDC_NO; - break; - case SDL_SYSTEM_CURSOR_POINTER: - name = IDC_HAND; - break; case SDL_SYSTEM_CURSOR_NW_RESIZE: - name = IDC_SIZENWSE; - break; - case SDL_SYSTEM_CURSOR_N_RESIZE: - name = IDC_SIZENS; - break; - case SDL_SYSTEM_CURSOR_NE_RESIZE: - name = IDC_SIZENESW; - break; - case SDL_SYSTEM_CURSOR_E_RESIZE: - name = IDC_SIZEWE; - break; case SDL_SYSTEM_CURSOR_SE_RESIZE: name = IDC_SIZENWSE; break; - case SDL_SYSTEM_CURSOR_S_RESIZE: - name = IDC_SIZENS; - break; + case SDL_SYSTEM_CURSOR_NESW_RESIZE: + case SDL_SYSTEM_CURSOR_NE_RESIZE: case SDL_SYSTEM_CURSOR_SW_RESIZE: name = IDC_SIZENESW; break; + case SDL_SYSTEM_CURSOR_EW_RESIZE: + case SDL_SYSTEM_CURSOR_E_RESIZE: case SDL_SYSTEM_CURSOR_W_RESIZE: + case SDL_SYSTEM_CURSOR_COL_RESIZE: name = IDC_SIZEWE; break; + case SDL_SYSTEM_CURSOR_NS_RESIZE: + case SDL_SYSTEM_CURSOR_N_RESIZE: + case SDL_SYSTEM_CURSOR_S_RESIZE: + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + name = IDC_SIZENS; + break; + case SDL_SYSTEM_CURSOR_MOVE: + case SDL_SYSTEM_CURSOR_ALL_SCROLL: + name = IDC_SIZEALL; + break; + case SDL_SYSTEM_CURSOR_NOT_ALLOWED: + case SDL_SYSTEM_CURSOR_NO_DROP: + name = IDC_NO; + break; + case SDL_SYSTEM_CURSOR_POINTER: + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + case SDL_SYSTEM_CURSOR_ALIAS: + case SDL_SYSTEM_CURSOR_COPY: + case SDL_SYSTEM_CURSOR_GRAB: + case SDL_SYSTEM_CURSOR_GRABBING: + case SDL_SYSTEM_CURSOR_ZOOM_IN: + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + name = IDC_HAND; + break; + case SDL_SYSTEM_CURSOR_HELP: + name = IDC_HELP; + break; } return WIN_CreateCursorAndData(LoadCursor(NULL, name)); } diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index 7ad974b132..b214e98120 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -298,6 +298,20 @@ static unsigned int GetLegacySystemCursorShape(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_S_RESIZE: return XC_bottom_side; case SDL_SYSTEM_CURSOR_SW_RESIZE: return XC_bottom_left_corner; case SDL_SYSTEM_CURSOR_W_RESIZE: return XC_left_side; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: return XC_hand2; + case SDL_SYSTEM_CURSOR_HELP: return XC_question_arrow; + case SDL_SYSTEM_CURSOR_CELL: return XC_cross; + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: return XC_xterm; + case SDL_SYSTEM_CURSOR_ALIAS: return XC_hand2; + case SDL_SYSTEM_CURSOR_COPY: return XC_hand2; + case SDL_SYSTEM_CURSOR_NO_DROP: return XC_pirate; + case SDL_SYSTEM_CURSOR_GRAB: return XC_hand2; + case SDL_SYSTEM_CURSOR_GRABBING: return XC_hand2; + case SDL_SYSTEM_CURSOR_COL_RESIZE: return XC_sb_h_double_arrow; + case SDL_SYSTEM_CURSOR_ROW_RESIZE: return XC_sb_v_double_arrow; + case SDL_SYSTEM_CURSOR_ALL_SCROLL: return XC_fleur; + case SDL_SYSTEM_CURSOR_ZOOM_IN: return XC_hand2; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: return XC_hand2; case SDL_SYSTEM_CURSOR_COUNT: break; // so the compiler might notice if an enum value is missing here. } diff --git a/test/testcustomcursor.c b/test/testcustomcursor.c index bf4e136e1d..4fb7ad5b87 100644 --- a/test/testcustomcursor.c +++ b/test/testcustomcursor.c @@ -397,6 +397,34 @@ static const char *get_active_cursor_name() return "Window resize bottom-left"; case SDL_SYSTEM_CURSOR_W_RESIZE: return "Window resize left"; + case SDL_SYSTEM_CURSOR_CONTEXT_MENU: + return "Context menu"; + case SDL_SYSTEM_CURSOR_HELP: + return "Help"; + case SDL_SYSTEM_CURSOR_CELL: + return "Cell"; + case SDL_SYSTEM_CURSOR_VERTICAL_TEXT: + return "Vertical text"; + case SDL_SYSTEM_CURSOR_ALIAS: + return "Alias"; + case SDL_SYSTEM_CURSOR_COPY: + return "Copy"; + case SDL_SYSTEM_CURSOR_NO_DROP: + return "No drop"; + case SDL_SYSTEM_CURSOR_GRAB: + return "Grab"; + case SDL_SYSTEM_CURSOR_GRABBING: + return "Grabbing"; + case SDL_SYSTEM_CURSOR_COL_RESIZE: + return "Column resize"; + case SDL_SYSTEM_CURSOR_ROW_RESIZE: + return "Row resize"; + case SDL_SYSTEM_CURSOR_ALL_SCROLL: + return "All scroll: Four pointed arrow pointing north, south, east, and west"; + case SDL_SYSTEM_CURSOR_ZOOM_IN: + return "Zoom in"; + case SDL_SYSTEM_CURSOR_ZOOM_OUT: + return "Zoom out"; default: return "UNKNOWN CURSOR TYPE, FIX THIS PROGRAM."; } diff --git a/test/testwm.c b/test/testwm.c index 393f82c3f7..77d89102bc 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -22,26 +22,40 @@ static SDLTest_CommonState *state; static int done; static const char *cursorNames[] = { - "arrow", - "ibeam", + "default", + "text", "wait", "crosshair", - "waitarrow", - "sizeNWSE", - "sizeNESW", - "sizeWE", - "sizeNS", - "sizeALL", - "NO", - "hand", - "window top left", - "window top", - "window top right", - "window right", - "window bottom right", - "window bottom", - "window bottom left", - "window left" + "progress", + "NWSE resize", + "NESW resize", + "EW resize", + "NS resize", + "move", + "not allowed", + "pointer", + "NW resize", + "N resize", + "NE resize", + "E resize", + "SE resize", + "S resize", + "SW resize", + "W resize", + "context menu", + "help", + "cell", + "vertical text", + "alias", + "copy", + "no drop", + "grab", + "grabbing", + "column resize", + "row resize", + "all scroll", + "zoom in", + "zoom out" }; SDL_COMPILE_TIME_ASSERT(cursorNames, SDL_arraysize(cursorNames) == SDL_SYSTEM_CURSOR_COUNT); From 0e5e772ba9c67d6822e2e22fc782657f8ec58000 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 13 May 2026 20:39:38 -0700 Subject: [PATCH 276/407] Fixed windows getting the wrong size when setting size and aspect ratio back to back --- src/video/SDL_video.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 86826b8b61..318f05b1df 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3239,10 +3239,15 @@ bool SDL_SetWindowAspectRatio(SDL_Window *window, float min_aspect, float max_as window->min_aspect = min_aspect; window->max_aspect = max_aspect; + if (_this->SetWindowAspectRatio) { _this->SetWindowAspectRatio(_this, window); } - return SDL_SetWindowSize(window, window->floating.w, window->floating.h); + + // Ensure that window has the correct aspect ratio + int w = window->last_size_pending ? window->pending.w : window->floating.w; + int h = window->last_size_pending ? window->pending.h : window->floating.h; + return SDL_SetWindowSize(window, w, h); } bool SDL_GetWindowAspectRatio(SDL_Window *window, float *min_aspect, float *max_aspect) @@ -3346,8 +3351,6 @@ bool SDL_SetWindowMinimumSize(SDL_Window *window, int min_w, int min_h) // Ensure that window is not smaller than minimal size int w = window->last_size_pending ? window->pending.w : window->floating.w; int h = window->last_size_pending ? window->pending.h : window->floating.h; - w = window->min_w ? SDL_max(w, window->min_w) : w; - h = window->min_h ? SDL_max(h, window->min_h) : h; return SDL_SetWindowSize(window, w, h); } @@ -3388,8 +3391,6 @@ bool SDL_SetWindowMaximumSize(SDL_Window *window, int max_w, int max_h) // Ensure that window is not larger than maximal size int w = window->last_size_pending ? window->pending.w : window->floating.w; int h = window->last_size_pending ? window->pending.h : window->floating.h; - w = window->max_w ? SDL_min(w, window->max_w) : w; - h = window->max_h ? SDL_min(h, window->max_h) : h; return SDL_SetWindowSize(window, w, h); } From 0f175891a608108a458890be6194358e0234f09f Mon Sep 17 00:00:00 2001 From: Gabriel Wang Date: Thu, 14 May 2026 14:37:46 +0800 Subject: [PATCH 277/407] Add SVE2 SIMD Alpha-Blending Blitter (#15504) SVE/SVE2 is a new SIMD extension for AArch64. Compared to NEON, SVE/SVE2 brings the following benefits that are good for SDL projects: - Lane prediction: we don't have to treat the tail part of a stride separately when the width is n times the hardware vector size - Although the performance is almost no difference from NEON when the hardware vector size is 128bits, when the hardware provides a longer vector size, e.g. 256, 512, ... 2048, we can enjoy the large performance gain without modifying the source code or recompiling a library. The functional correctness is validated in a dedicated [qemu project](https://github.com/GorgonMeducer/aarch64_qemu_mac_template/tree/SDL-SVE2-Acceleration-Validation). The performance is tested on [Radxa Orion 6 N](https://radxa.com/products/orion/o6n/), which provides 4x A720 and 4x A520 processors. Since the vector size is 128 bits, which is the same as NEON, the performance is almost the same (or no worse than) the NEON acceleration. --- Android.mk | 1 + CMakeLists.txt | 36 + include/SDL3/SDL_cpuinfo.h | 12 + include/SDL3/SDL_intrin.h | 28 + include/build_config/SDL_build_config.h.cmake | 1 + include/build_config/SDL_build_config_ios.h | 3 + src/cpuinfo/SDL_cpuinfo.c | 33 + src/dynapi/SDL_dynapi.exports | 1 + src/dynapi/SDL_dynapi.sym | 1 + src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/video/SDL_blit_A.c | 28 + src/video/SDL_blit_N.c | 21 + src/video/arm/SDL_sve2_blit_A.c | 89 + src/video/arm/SDL_sve2_blit_A.h | 37 + src/video/arm/SDL_sve2_blit_N.c | 64 + src/video/arm/SDL_sve2_blit_N.h | 35 + src/video/arm/SDL_sve2_extension.h | 1142 ++++++++ src/video/arm/SDL_sve2_swizzle.h | 2375 +++++++++++++++++ src/video/arm/SDL_sve2_util.h | 206 ++ test/testplatform.c | 1 + 21 files changed, 4116 insertions(+) create mode 100644 src/video/arm/SDL_sve2_blit_A.c create mode 100644 src/video/arm/SDL_sve2_blit_A.h create mode 100644 src/video/arm/SDL_sve2_blit_N.c create mode 100644 src/video/arm/SDL_sve2_blit_N.h create mode 100644 src/video/arm/SDL_sve2_extension.h create mode 100644 src/video/arm/SDL_sve2_swizzle.h create mode 100644 src/video/arm/SDL_sve2_util.h diff --git a/Android.mk b/Android.mk index 2e3b11483c..d53bf403b1 100644 --- a/Android.mk +++ b/Android.mk @@ -84,6 +84,7 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/tray/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/android/*.c) \ + $(wildcard $(LOCAL_PATH)/src/video/arm/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/yuv2rgb/*.c)) LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES diff --git a/CMakeLists.txt b/CMakeLists.txt index e591a011c1..851e11add9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,6 +314,7 @@ dep_option(SDL_SSE4_2 "Use SSE4.2 assembly routines" ON "SDL_ASSEMB dep_option(SDL_MMX "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) dep_option(SDL_ALTIVEC "Use Altivec assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_POWERPC32 OR SDL_CPU_POWERPC64" OFF) dep_option(SDL_ARMNEON "Use NEON assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF) +dep_option(SDL_ARMSVE2 "Use SVE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_ARM64" OFF) dep_option(SDL_LSX "Use LSX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) dep_option(SDL_LASX "Use LASX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) @@ -939,6 +940,37 @@ if(SDL_ASSEMBLY) endif() endif() + if(SDL_ARMSVE2) + cmake_push_check_state() + string(APPEND CMAKE_REQUIRED_FLAGS " -march=armv8-a+sve2") + check_arm_source_compiles([==[ + #include + svuint32_t sve2_test(svuint32_t a, svuint32_t b) { + return svadd_u32_x(svptrue_b32(), a, b); + } + int main(int argc, char *argv[]) { + sve2_test(svdup_u32(0), svdup_u32(0)); + return 0; + }]==] COMPILER_SUPPORTS_ARMSVE2) + if(COMPILER_SUPPORTS_ARMSVE2) + set(HAVE_ARMSVE2 TRUE) + endif() + cmake_pop_check_state() + + if(HAVE_ARMSVE2) + sdl_sources( + "${SDL3_SOURCE_DIR}/src/video/arm/SDL_sve2_blit_A.c" + "${SDL3_SOURCE_DIR}/src/video/arm/SDL_sve2_blit_N.c" + ) + set_source_files_properties( + "${SDL3_SOURCE_DIR}/src/video/arm/SDL_sve2_blit_A.c" + "${SDL3_SOURCE_DIR}/src/video/arm/SDL_sve2_blit_N.c" + PROPERTIES + SKIP_PRECOMPILE_HEADERS ON + ) + endif() + endif() + if(USE_GCC OR USE_CLANG) # TODO: Those all seem to be quite GCC specific - needs to be # reworked for better compiler support @@ -1055,6 +1087,10 @@ if(NOT HAVE_ARMNEON) set(SDL_DISABLE_NEON 1) endif() +if(NOT HAVE_ARMSVE2) + set(SDL_DISABLE_SVE2 1) +endif() + set(SDL_DISABLE_ALLOCA 0) check_include_file("alloca.h" "HAVE_ALLOCA_H") if(MSVC) diff --git a/include/SDL3/SDL_cpuinfo.h b/include/SDL3/SDL_cpuinfo.h index 5669c2373d..765cadf287 100644 --- a/include/SDL3/SDL_cpuinfo.h +++ b/include/SDL3/SDL_cpuinfo.h @@ -281,6 +281,18 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasARMSIMD(void); */ extern SDL_DECLSPEC bool SDLCALL SDL_HasNEON(void); +/** + * Determine whether the CPU has SVE2 (Scalable Vector Extension 2). + * + * This is only relevant on ARM64 Linux. On other platforms it always returns + * false. + * + * \returns true if the CPU has SVE2, false otherwise. + * + * \since This function is available since SDL 3.6.0. + */ +extern SDL_DECLSPEC bool SDLCALL SDL_HasSVE2(void); + /** * Determine whether the CPU has LSX (LOONGARCH SIMD) features. * diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h index a2e968080c..ecd8192941 100644 --- a/include/SDL3/SDL_intrin.h +++ b/include/SDL3/SDL_intrin.h @@ -85,6 +85,16 @@ */ #define SDL_NEON_INTRINSICS 1 +/** + * Defined if (and only if) the compiler supports ARM SVE2 intrinsics. + * + * If this macro is defined, SDL will have already included `` + * as appropriate. + * + * \since This macro is available since SDL 3.6.0. + */ +#define SDL_SVE2_INTRINSICS 1 + /** * Defined if (and only if) the compiler supports PowerPC Altivec intrinsics. * @@ -237,6 +247,10 @@ _m_prefetch(void *__P) # define SDL_NEON_INTRINSICS 1 # include #endif +#if defined(__ARM_FEATURE_SVE2) && !defined(SDL_DISABLE_SVE2) +# define SDL_SVE2_INTRINSICS 1 +# include +#endif #else /* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC to have it included. */ @@ -265,6 +279,20 @@ _m_prefetch(void *__P) # endif # endif #endif +#ifndef SDL_DISABLE_SVE2 +# if defined(SDL_PLATFORM_WINDOWS) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined (_M_ARM64) && 0 /* Please only remove this 0 when MSVC releasing support for SVE2 officially. */ +# define SDL_SVE2_INTRINSICS 1 +# include +# define __ARM_FEATURE_SVE2 1 /* Set __ARM_FEATURE_SVE2 so that it can be used elsewhere, at compile time */ +# define __ARM_ARCH 8 +# endif +# elif !defined(SDL_PLATFORM_MACOS) /* Apple has no AArch64 device supporting SVE2 */ +# define SDL_SVE2_INTRINSICS 1 +# include +# endif +#endif #endif /* compiler version */ #ifdef SDL_WIKI_DOCUMENTATION_SECTION diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index e7d0b34f42..2e0cdc21b4 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -625,6 +625,7 @@ typedef unsigned int uintptr_t; #cmakedefine SDL_DISABLE_LSX 1 #cmakedefine SDL_DISABLE_LASX 1 #cmakedefine SDL_DISABLE_NEON 1 +#cmakedefine SDL_DISABLE_SVE2 1 #ifdef SDL_PLATFORM_PRIVATE #include "SDL_end_config_private.h" diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h index 308270b5a0..56f17f8b8f 100644 --- a/include/build_config/SDL_build_config_ios.h +++ b/include/build_config/SDL_build_config_ios.h @@ -226,4 +226,7 @@ /* Enable tray subsystem */ #define SDL_TRAY_DUMMY 1 +/* Disable ARM SVE2 intrinsics until we confirm they're available on all Apple mobile and TV hardware */ +#define SDL_DISABLE_SVE2 1 + #endif /* SDL_build_config_ios_h_ */ diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c index 966a5ae79a..19daae4421 100644 --- a/src/cpuinfo/SDL_cpuinfo.c +++ b/src/cpuinfo/SDL_cpuinfo.c @@ -109,6 +109,7 @@ #define CPU_HAS_ARM_SIMD (1 << 11) #define CPU_HAS_LSX (1 << 12) #define CPU_HAS_LASX (1 << 13) +#define CPU_HAS_SVE2 (1 << 14) #define CPU_CFG2 0x2 #define CPU_CFG2_LSX (1 << 6) @@ -514,6 +515,27 @@ static int CPU_haveNEON(void) #endif } +#ifndef AT_HWCAP2 +#define AT_HWCAP2 26 +#endif +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif +#ifndef HWCAP2_SVE2 +#define HWCAP2_SVE2 (1 << 1) +#endif + +static int CPU_haveSVE2(void) +{ +#if defined(__aarch64__) && \ + ((defined(SDL_PLATFORM_LINUX) && defined(HAVE_GETAUXVAL)) || defined(SDL_PLATFORM_ANDROID)) + return ((getauxval(AT_HWCAP2) & HWCAP2_SVE2) == HWCAP2_SVE2) + && ((getauxval(AT_HWCAP) & HWCAP_SVE) == HWCAP_SVE); +#else + return 0; +#endif +} + static int CPU_readCPUCFG(void) { uint32_t cfg2 = 0; @@ -960,6 +982,8 @@ static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void) spot_mask = CPU_HAS_LSX; } else if (ref_string_equals("lasx", spot, end)) { spot_mask = CPU_HAS_LASX; + } else if (ref_string_equals("sve2", spot, end)) { + spot_mask = CPU_HAS_SVE2; } else { // Ignore unknown/incorrect cpu feature(s) continue; @@ -1036,6 +1060,10 @@ static Uint32 SDL_GetCPUFeatures(void) SDL_CPUFeatures |= CPU_HAS_LASX; SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32); } + if (CPU_haveSVE2()) { + SDL_CPUFeatures |= CPU_HAS_SVE2; + SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16); + } SDL_CPUFeatures &= SDL_CPUFeatureMaskFromHint(); } return SDL_CPUFeatures; @@ -1117,6 +1145,11 @@ bool SDL_HasLASX(void) return CPU_FEATURE_AVAILABLE(CPU_HAS_LASX); } +bool SDL_HasSVE2(void) +{ + return CPU_FEATURE_AVAILABLE(CPU_HAS_SVE2); +} + static int SDL_SystemRAM = 0; int SDL_GetSystemRAM(void) diff --git a/src/dynapi/SDL_dynapi.exports b/src/dynapi/SDL_dynapi.exports index 67600f2b7b..32e9fbff86 100644 --- a/src/dynapi/SDL_dynapi.exports +++ b/src/dynapi/SDL_dynapi.exports @@ -1287,3 +1287,4 @@ _SDL_GDKResumeRenderer _SDL_IsPhone _SDL_LoadJPG_IO _SDL_LoadJPG +_SDL_HasSVE2 diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 3fdc470a33..ca1a1c97d9 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1288,6 +1288,7 @@ SDL3_0.0.0 { SDL_IsPhone; SDL_LoadJPG_IO; SDL_LoadJPG; + SDL_HasSVE2; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 7b88affdc6..677768ff2f 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1314,3 +1314,4 @@ #define SDL_IsPhone SDL_IsPhone_REAL #define SDL_LoadJPG_IO SDL_LoadJPG_IO_REAL #define SDL_LoadJPG SDL_LoadJPG_REAL +#define SDL_HasSVE2 SDL_HasSVE2_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 24a5afad98..99899b346e 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1322,3 +1322,4 @@ SDL_DYNAPI_PROC(void,SDL_GDKResumeRenderer,(SDL_Renderer *a),(a),) SDL_DYNAPI_PROC(bool,SDL_IsPhone,(void),(),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG_IO,(SDL_IOStream *a,bool b),(a,b),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG,(const char *a),(a),return) +SDL_DYNAPI_PROC(bool,SDL_HasSVE2,(void),(),return) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index f7a997f3b0..0dcd25d885 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -25,6 +25,10 @@ #include "SDL_pixels_c.h" #include "SDL_surface_c.h" +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#include "./arm/SDL_sve2_blit_A.h" +#endif + // Functions to perform alpha blended blitting // N->1 blending with per-surface alpha @@ -1477,6 +1481,17 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) } case 2: +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) + if (SDL_HasSVE2()) { + if (sf->bytes_per_pixel == 4 && + df->bytes_per_pixel == 2 && + df->Rmask == 0x0000F800 && + df->Gmask == 0x000007E0 && + df->Bmask == 0x0000001F) { + return Blit8888to565PixelAlphaSwizzleSVE2; + } + } +#endif if (sf->bytes_per_pixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { if (df->Gmask == 0x7e0) { return BlitARGBto565PixelAlpha; @@ -1504,6 +1519,19 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) return Blit8888to8888PixelAlphaSwizzleLSX; } #endif +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) + if (SDL_HasSVE2() + /* NEON is faster than SVE2 when vector size is 128bit */ + #if defined(SDL_NEON_INTRINSICS) + && SDL_GetSVEVectorSize() > 128 + #endif + ) { + // To prevent "unused function" compiler warnings/errors + (void)Blit8888to8888PixelAlpha; + (void)Blit8888to8888PixelAlphaSwizzle; + return Blit8888to8888PixelAlphaSwizzleSVE2; + } +#endif #if defined(SDL_NEON_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) // To prevent "unused function" compiler warnings/errors (void)Blit8888to8888PixelAlpha; diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 204c1addbd..b014d4233a 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -26,6 +26,10 @@ #include "SDL_surface_c.h" #include "SDL_blit_copy.h" +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#include "./arm/SDL_sve2_blit_N.h" +#endif + // General optimized routines that write char by char #define HAVE_FAST_WRITE_INT8 1 @@ -3117,10 +3121,27 @@ SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface) return Blit8888to8888PixelSwizzleSSE41; } #endif +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) + if (SDL_HasSVE2()) { + return Blit8888to8888PixelSwizzleSVE2; + } +#endif #if defined(SDL_NEON_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) return Blit8888to8888PixelSwizzleNEON; #endif } +#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) + if (SDL_HasSVE2()) { + /* RGBA8888/ARGB8888/XRGB8888 -> RGB565 */ + if (srcfmt->bytes_per_pixel == 4 && + dstfmt->bytes_per_pixel == 2 && + dstfmt->Rmask == 0x0000F800 && + dstfmt->Gmask == 0x000007E0 && + dstfmt->Bmask == 0x0000001F) { + return Blit8888to565PixelSwizzleSVE2; + } + } +#endif blitfun = NULL; if (dstfmt->bits_per_pixel > 8) { diff --git a/src/video/arm/SDL_sve2_blit_A.c b/src/video/arm/SDL_sve2_blit_A.c new file mode 100644 index 0000000000..be029bcc70 --- /dev/null +++ b/src/video/arm/SDL_sve2_blit_A.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_sve2_blit_A.h" +#include + +#ifdef SDL_SVE2_INTRINSICS + +#undef sdl_sve_rgb32_blend_op_fill_alpha +#define sdl_sve_rgb32_blend_op_fill_alpha(ma_alpha_chn_idx) \ + if (sve_src_chn_idx == (ma_alpha_chn_idx)) { \ + /* fill alpha */ \ + sve_target_u16 = svdup_u16(0xFF); \ + } else { \ + svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ + sve_target_u16 = sdl_sve_chn_blend_with_mask(sve_source_u16, \ + sve_target_u16, \ + vMask); \ + } + +#undef sdl_sve_rgb32_blend_op_copy_alpha +#define sdl_sve_rgb32_blend_op_copy_alpha(ma_alpha_chn_idx) \ + if (sve_src_chn_idx == (ma_alpha_chn_idx)) { \ + svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ + sve_target_u16 = sdl_sve_chn_blend_with_mask(svdup_u16(0xFF), \ + sve_target_u16, \ + vMask); \ + } else { \ + svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ + sve_target_u16 = sdl_sve_chn_blend_with_mask(sve_source_u16, \ + sve_target_u16, \ + vMask); \ + } + +#undef sdl_sve_rgb32_blend_to_rgb565_op +#define sdl_sve_rgb32_blend_to_rgb565_op(ma_alpha_chn_idx) \ + do { \ + svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ + sve_target_u16 = sdl_sve_chn_blend_with_mask(sve_source_u16, \ + sve_target_u16, \ + vMask); \ + } while (0) + +#include "SDL_sve2_swizzle.h" + +/*-----------------------------------------------------------------------------* + * Swizzle Blend with Alpha * + *-----------------------------------------------------------------------------*/ +SDL_TARGETING("arch=armv8-a+sve2") +void Blit8888to8888PixelAlphaSwizzleSVE2(SDL_BlitInfo *info) +{ + const SDL_PixelFormatDetails *srcfmt = info->src_fmt; + assert(0 != srcfmt->Amask); + (void)srcfmt; + + sdl_sve_8888_to_8888_swizzle_dispatcher(info); +} + +SDL_TARGETING("arch=armv8-a+sve2") +void Blit8888to565PixelAlphaSwizzleSVE2(SDL_BlitInfo *info) +{ + sdl_sve_rgb32_to_rgb565_swizzle_dispatcher(info); +} + +SDL_TARGETING("arch=armv8-a+sve2") +size_t SDL_GetSVEVectorSize(void) +{ + return svlen(svundef_u8()) * 8; +} + +#endif /* SDL_SVE2_INTRINSICS */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_blit_A.h b/src/video/arm/SDL_sve2_blit_A.h new file mode 100644 index 0000000000..2a7e2b8149 --- /dev/null +++ b/src/video/arm/SDL_sve2_blit_A.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_sve2_blit_A_h_ +#define SDL_sve2_blit_A_h_ + +#include "../../SDL_internal.h" +#include "../SDL_blit.h" + +#ifdef SDL_SVE2_INTRINSICS + +void Blit8888to8888PixelAlphaSwizzleSVE2(SDL_BlitInfo *info); +void Blit8888to565PixelAlphaSwizzleSVE2(SDL_BlitInfo *info); + +size_t SDL_GetSVEVectorSize(void); + +#endif /* SDL_SVE2_INTRINSICS */ + +#endif /* SDL_sve2_blitters_h_ */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_blit_N.c b/src/video/arm/SDL_sve2_blit_N.c new file mode 100644 index 0000000000..c6ae97e53b --- /dev/null +++ b/src/video/arm/SDL_sve2_blit_N.c @@ -0,0 +1,64 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_sve2_blit_N.h" +#include + +#ifdef SDL_SVE2_INTRINSICS + +#undef sdl_sve_rgb32_blend_op_fill_alpha +#define sdl_sve_rgb32_blend_op_fill_alpha(ma_alpha_chn_idx) \ + do { \ + if (sve_src_chn_idx == (ma_alpha_chn_idx)) { \ + /* fill alpha */ \ + sve_target_u16 = svdup_u16(0xFF); \ + } else { \ + sve_target_u16 = sve_source_u16; \ + } \ + } while (0) + +#undef sdl_sve_rgb32_blend_op_copy_alpha +#define sdl_sve_rgb32_blend_op_copy_alpha(ma_alpha_chn_idx) \ + do { \ + sve_target_u16 = sve_source_u16; \ + } while (0) + +#undef sdl_sve_rgb32_blend_to_rgb565_op +#define sdl_sve_rgb32_blend_to_rgb565_op(ma_alpha_chn_idx) \ + do { \ + sve_target_u16 = sve_source_u16; \ + } while (0) + +#include "SDL_sve2_swizzle.h" + +SDL_TARGETING("arch=armv8-a+sve2") +void Blit8888to8888PixelSwizzleSVE2(SDL_BlitInfo *info) +{ + sdl_sve_8888_to_8888_swizzle_dispatcher(info); +} + +SDL_TARGETING("arch=armv8-a+sve2") +void Blit8888to565PixelSwizzleSVE2(SDL_BlitInfo *info) +{ + sdl_sve_rgb32_to_rgb565_swizzle_dispatcher(info); +} + +#endif /* SDL_SVE2_INTRINSICS */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_blit_N.h b/src/video/arm/SDL_sve2_blit_N.h new file mode 100644 index 0000000000..3868de0dbb --- /dev/null +++ b/src/video/arm/SDL_sve2_blit_N.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_sve2_blit_N_h_ +#define SDL_sve2_blit_N_h_ + +#include "../../SDL_internal.h" +#include "../SDL_blit.h" + +#ifdef SDL_SVE2_INTRINSICS + +void Blit8888to8888PixelSwizzleSVE2(SDL_BlitInfo *info); +void Blit8888to565PixelSwizzleSVE2(SDL_BlitInfo *info); + +#endif /* SDL_SVE2_INTRINSICS */ + +#endif /* SDL_sve2_blitters_h_ */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_extension.h b/src/video/arm/SDL_sve2_extension.h new file mode 100644 index 0000000000..2f5a74a12b --- /dev/null +++ b/src/video/arm/SDL_sve2_extension.h @@ -0,0 +1,1142 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ + +#if !defined(SDL_SVE2_EXTENSION_H) //&& (defined(__ARM_FEATURE_SVE2) && __ARM_FEATURE_SVE2) +#define SDL_SVE2_EXTENSION_H + +#include "SDL_sve2_util.h" +#include +#include + +/*! + * \brief a wrapper for __attribute__((nonnull)) + */ +#ifndef ARM_NONNULL +#define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) +#endif + +#define svlenu8() svcntb_pat(SV_ALL) +#define svlenu16() (svcntb_pat(SV_ALL) / sizeof(uint16_t)) +#define svlenu32() (svcntb_pat(SV_ALL) / sizeof(uint32_t)) +#define svlenu64() (svcntb_pat(SV_ALL) / sizeof(uint64_t)) + +#define svlens8() svlenu8() +#define svlens16() svlenu16() +#define svlens32() svlenu32() +#define svlens64() svlenu64() + +#define sdl_sve_stride_loop_accc8888(ma_stride_size, ma_pred_name) \ + for (svbool_t ma_pred_name, *pTemp = &ma_pred_name; \ + pTemp != NULL; \ + pTemp = NULL) \ + for (size_t SVE_SAFE_NAME(n) = 0, \ + sve_iteration_advance = svlenu32() * 4; \ + ({ \ + ma_pred_name = svwhilelt_b8((int32_t)SVE_SAFE_NAME(n), \ + (int32_t)(ma_stride_size)); \ + SVE_SAFE_NAME(n) < (ma_stride_size); \ + }); \ + SVE_SAFE_NAME(n) += sve_iteration_advance) + +#define sdl_sve_stride_loop_rgb32(ma_stride_size, ma_pred_name) \ + sdl_sve_stride_loop_accc8888(ma_stride_size, ma_pred_name) + +#define sdl_sve_stride_loop_rgb16(ma_stride_size, ma_pred_name) \ + for (svbool_t ma_pred_name, *pTemp = &ma_pred_name; \ + pTemp != NULL; \ + pTemp = NULL) \ + for (size_t SVE_SAFE_NAME(n) = 0, \ + sve_iteration_advance = svlenu16(); \ + ({ \ + ma_pred_name = svwhilelt_b16((int32_t)SVE_SAFE_NAME(n), \ + (int32_t)(ma_stride_size)); \ + SVE_SAFE_NAME(n) < (ma_stride_size); \ + }); \ + SVE_SAFE_NAME(n) += sve_iteration_advance) + +#define sdl_sve_pixel_ccc_foreach_chn(ma_source_u16x3, \ + ma_target_u16x3, \ + ...) \ + do { \ + svuint16x3_t sve_source_u16x3 = ma_source_u16x3; \ + (void)sve_source_u16x3; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget3((ma_source_u16x3), 0); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget3((ma_source_u16x3), 1); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget3((ma_source_u16x3), 2); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_accc_foreach_chn012(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_accc_foreach_chn(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_accc_ccca(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_ccca_accc(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_a123_a321(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_123a_321a(ma_source_u16x4, \ + ma_target_u16x4, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 3; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 3); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 3, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 2, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget4((ma_target_u16x4), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x4 = svset4(ma_target_u16x4, 1, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_argb_rgb565(ma_source_u16x4, \ + ma_target_u16x3, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_rgba_rgb565(ma_source_u16x4, \ + ma_target_u16x3, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_bgra_rgb565(ma_source_u16x4, \ + ma_target_u16x3, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 3; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 3); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +#define sdl_sve_pixel_u16x4_foreach_chn_abgr_rgb565(ma_source_u16x4, \ + ma_target_u16x3, \ + ...) \ + do { \ + svuint16x4_t sve_source_u16x4 = ma_source_u16x4; \ + (void)sve_source_u16x4; \ + do { \ + const uint8_t sve_src_chn_idx = 2; \ + const uint8_t sve_dst_chn_idx = 0; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 2); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 0); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 0, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 1; \ + const uint8_t sve_dst_chn_idx = 1; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 1); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 1); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 1, sve_target_u16); \ + } while (0); \ + do { \ + const uint8_t sve_src_chn_idx = 0; \ + const uint8_t sve_dst_chn_idx = 2; \ + (void)sve_src_chn_idx; \ + (void)sve_dst_chn_idx; \ + svuint16_t sve_source_u16 = svget4((ma_source_u16x4), 0); \ + svuint16_t sve_target_u16 = svget3((ma_target_u16x3), 2); \ + (void)sve_source_u16; \ + (void)sve_target_u16; \ + __VA_ARGS__ \ + ma_target_u16x3 = svset3(ma_target_u16x3, 2, sve_target_u16); \ + } while (0); \ + } while (0) + +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16x3_t sdl_sve_rgb565_unpack(svuint16_t vPixels) +{ + svuint16_t vBlue = svand_n_u16_m(svptrue_b16(), vPixels, 0x1F); + svuint16_t vGreen = svand_n_u16_m(svptrue_b16(), vPixels, (0x3F << 5)); + svuint16_t vRed = svand_n_u16_m(svptrue_b16(), vPixels, (0x1F << 11)); + + return svcreate3_u16(svlsl_n_u16_m(svptrue_b16(), vBlue, 3), + svlsr_n_u16_m(svptrue_b16(), vGreen, 3), + svlsr_n_u16_m(svptrue_b16(), vRed, 8)); +} + +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_rgb565_pack(svuint16x3_t vRGB16x3) +{ + svuint16_t vRed = svlsr_n_u16_m(svptrue_b16(), svget3_u16(vRGB16x3, 0), 3); + svuint16_t vGreen = svlsl_n_u16_m(svptrue_b16(), + svand_n_u16_m(svptrue_b16(), + svget3_u16(vRGB16x3, 1), + (0x3F << 2)), + 3); + svuint16_t vBlue = svlsl_n_u16_m(svptrue_b16(), + svand_n_u16_m(svptrue_b16(), + svget3_u16(vRGB16x3, 2), + (0x1F << 3)), + 8); + + svuint16_t vPixel = svorr_u16_m(svptrue_b16(), vRed, vGreen); + return svorr_u16_m(svptrue_b16(), vPixel, vBlue); + + // return (svget3_u16(vRGB16x3, 0) >> 3) + // | ((svget3_u16(vRGB16x3, 1) & (0x3F << 2)) << 3) + // | ((svget3_u16(vRGB16x3, 2) & (0x1F << 3)) << 8); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(2, 3, 4) +static inline void svld3rgb565_u16(svbool_t vPredu8, + uint16_t *phwSource, + svuint16x3_t *pvLow, + svuint16x3_t *pvHigh) +{ + svuint8x2_t vInput8x2 = svld2_u8(vPredu8, (uint8_t *)phwSource); + + svuint16_t vLowByteLowHalf = svunpklo_u16(svget2_u8(vInput8x2, 0)); + svuint16_t vLowByteHighHalf = svunpkhi_u16(svget2_u8(vInput8x2, 0)); + + svuint16_t vHighByteLowHalf = svunpklo_u16(svget2_u8(vInput8x2, 1)); + svuint16_t vHighByteHighHalf = svunpkhi_u16(svget2_u8(vInput8x2, 1)); + + //*pvLow = sdl_sve_rgb565_unpack ( vLowByteLowHalf + // | (vHighByteLowHalf << 8)); + *pvLow = sdl_sve_rgb565_unpack( + svorr_u16_m(svptrue_b16(), + vLowByteLowHalf, + //(vHighByteLowHalf << 8) + svlsl_n_u16_m(svptrue_b16(), vHighByteLowHalf, 8))); + + //*pvHigh = sdl_sve_rgb565_unpack ( vLowByteHighHalf + // | (vHighByteHighHalf << 8)); + *pvHigh = sdl_sve_rgb565_unpack( + svorr_u16_m(svptrue_b16(), + vLowByteHighHalf, + //(vHighByteHighHalf << 8) + svlsl_n_u16_m(svptrue_b16(), vHighByteHighHalf, 8))); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(2) +static inline void svst3rgb565_u16(svbool_t vPredu8, + uint16_t *phwTarget, + svuint16x3_t vLow, + svuint16x3_t vHigh) +{ + svuint16_t vLowByteLowHalf = svundef_u16(); + svuint16_t vHighByteLowHalf = svundef_u16(); + + /* pack low half pixels */ + do { + svuint16_t vPixel = sdl_sve_rgb565_pack(vLow); + + // vLowByteLowHalf = vPixel & 0xFF; + vLowByteLowHalf = svand_n_u16_m(svptrue_b16(), vPixel, 0xFF); + + // vHighByteLowHalf = vPixel >> 8; + vHighByteLowHalf = svlsr_n_u16_m(svptrue_b16(), vPixel, 8); + } while (0); + + svuint16_t vLowByteHighHalf = svundef_u16(); + svuint16_t vHighByteHighHalf = svundef_u16(); + + /* pack high half pixels */ + do { + svuint16_t vPixel = sdl_sve_rgb565_pack(vHigh); + + // vLowByteHighHalf = vPixel & 0xFF; + vLowByteHighHalf = svand_n_u16_m(svptrue_b16(), vPixel, 0xFF); + + // vHighByteHighHalf = vPixel >> 8; + vHighByteHighHalf = svlsr_n_u16_m(svptrue_b16(), vPixel, 8); + } while (0); + + /* save rgb565 pixels */ + svuint8_t vLowByte = svuzp1_u8(svreinterpret_u8(vLowByteLowHalf), + svreinterpret_u8(vLowByteHighHalf)); + + svuint8_t vHighByte = svuzp1_u8(svreinterpret_u8(vHighByteLowHalf), + svreinterpret_u8(vHighByteHighHalf)); + + svst2_u8(vPredu8, (uint8_t *)phwTarget, svcreate2_u8(vLowByte, vHighByte)); +} + +#if defined(__GNUC__) && !defined(__clang__) +#define svld4ub_u16(ma_pred, \ + ma_src_ptr, \ + ma_svuint16x4_low_ptr, \ + ma_svuint16x4_high_ptr) \ + do { \ + svuint8x4_t vInput8x4 = svld4_u8((ma_pred), (ma_src_ptr)); \ + \ + *(ma_svuint16x4_low_ptr) = svset4_u16(*(ma_svuint16x4_low_ptr), 0, svunpklo_u16(svget4_u8(vInput8x4, 0))); \ + *(ma_svuint16x4_low_ptr) = svset4_u16(*(ma_svuint16x4_low_ptr), 1, svunpklo_u16(svget4_u8(vInput8x4, 1))); \ + *(ma_svuint16x4_low_ptr) = svset4_u16(*(ma_svuint16x4_low_ptr), 2, svunpklo_u16(svget4_u8(vInput8x4, 2))); \ + *(ma_svuint16x4_low_ptr) = svset4_u16(*(ma_svuint16x4_low_ptr), 3, svunpklo_u16(svget4_u8(vInput8x4, 3))); \ + \ + *(ma_svuint16x4_high_ptr) = svset4_u16(*(ma_svuint16x4_high_ptr), 0, svunpkhi_u16(svget4_u8(vInput8x4, 0))); \ + *(ma_svuint16x4_high_ptr) = svset4_u16(*(ma_svuint16x4_high_ptr), 1, svunpkhi_u16(svget4_u8(vInput8x4, 1))); \ + *(ma_svuint16x4_high_ptr) = svset4_u16(*(ma_svuint16x4_high_ptr), 2, svunpkhi_u16(svget4_u8(vInput8x4, 2))); \ + *(ma_svuint16x4_high_ptr) = svset4_u16(*(ma_svuint16x4_high_ptr), 3, svunpkhi_u16(svget4_u8(vInput8x4, 3))); \ + } while (0) + +#define svst4ub_u16(ma_pred, \ + ma_dst_ptr, \ + ma_svuint16x4_low, \ + ma_svuint16x4_high) \ + do { \ + svuint8_t vCH0u8 = svuzp1_u8(svreinterpret_u8(svget4_u16((ma_svuint16x4_low), 0)), \ + svreinterpret_u8(svget4_u16((ma_svuint16x4_high), 0))); \ + \ + svuint8_t vCH1u8 = svuzp1_u8(svreinterpret_u8(svget4_u16((ma_svuint16x4_low), 1)), \ + svreinterpret_u8(svget4_u16((ma_svuint16x4_high), 1))); \ + \ + svuint8_t vCH2u8 = svuzp1_u8(svreinterpret_u8(svget4_u16((ma_svuint16x4_low), 2)), \ + svreinterpret_u8(svget4_u16((ma_svuint16x4_high), 2))); \ + \ + svuint8_t vCH3u8 = svuzp1_u8(svreinterpret_u8(svget4_u16((ma_svuint16x4_low), 3)), \ + svreinterpret_u8(svget4_u16((ma_svuint16x4_high), 3))); \ + \ + svst4_u8((ma_pred), (ma_dst_ptr), svcreate4_u8(vCH0u8, vCH1u8, vCH2u8, vCH3u8)); \ + } while (0) +#else +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(2, 3, 4) +static inline void svld4ub_u16(svbool_t vPredu8, + uint8_t *pchSource, + svuint16x4_t *pvLow, + svuint16x4_t *pvHigh) +{ + svuint8x4_t vInput8x4 = svld4_u8(vPredu8, pchSource); + + *pvLow = svset4_u16(*pvLow, 0, svunpklo_u16(svget4_u8(vInput8x4, 0))); + *pvLow = svset4_u16(*pvLow, 1, svunpklo_u16(svget4_u8(vInput8x4, 1))); + *pvLow = svset4_u16(*pvLow, 2, svunpklo_u16(svget4_u8(vInput8x4, 2))); + *pvLow = svset4_u16(*pvLow, 3, svunpklo_u16(svget4_u8(vInput8x4, 3))); + + *pvHigh = svset4_u16(*pvHigh, 0, svunpkhi_u16(svget4_u8(vInput8x4, 0))); + *pvHigh = svset4_u16(*pvHigh, 1, svunpkhi_u16(svget4_u8(vInput8x4, 1))); + *pvHigh = svset4_u16(*pvHigh, 2, svunpkhi_u16(svget4_u8(vInput8x4, 2))); + *pvHigh = svset4_u16(*pvHigh, 3, svunpkhi_u16(svget4_u8(vInput8x4, 3))); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(2) +static inline void svst4ub_u16(svbool_t vPredu8, + uint8_t *pchTarget, + svuint16x4_t vLow, + svuint16x4_t vHigh) +{ + + svuint8_t vCH0u8 = svuzp1_u8(svreinterpret_u8(svget4_u16(vLow, 0)), + svreinterpret_u8(svget4_u16(vHigh, 0))); + + svuint8_t vCH1u8 = svuzp1_u8(svreinterpret_u8(svget4_u16(vLow, 1)), + svreinterpret_u8(svget4_u16(vHigh, 1))); + + svuint8_t vCH2u8 = svuzp1_u8(svreinterpret_u8(svget4_u16(vLow, 2)), + svreinterpret_u8(svget4_u16(vHigh, 2))); + + svuint8_t vCH3u8 = svuzp1_u8(svreinterpret_u8(svget4_u16(vLow, 3)), + svreinterpret_u8(svget4_u16(vHigh, 3))); + + svst4_u8(vPredu8, pchTarget, svcreate4_u8(vCH0u8, vCH1u8, vCH2u8, vCH3u8)); +} +#endif + +/*! \note the Element range of vMask is [0, 0xFF] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_mask(svuint16_t vSource, svuint16_t vTarget, svuint16_t vMask) +{ + // vTarget = vSource * vMask + vTarget * (255 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + vTemp0 = svmla_u16_m(svptrue_b16(), + vTemp0, + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(255), + vMask)); + + vTemp0 = svadd_n_u16_m(svptrue_b16(), vTemp0, 1); + + svuint16_t vTemp1 = svlsr_n_u16_m(svptrue_b16(), vTemp0, 8); + /* x += x >> 8 */ + vTemp0 = svadd_u16_m(svptrue_b16(), + vTemp0, + vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTemp0, 8); // vTarget >> 8; +} + +/*! \note the hwOpacity range [0, 0x100] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_opacity(svuint16_t vSource, + svuint16_t vTarget, + uint16_t hwOpacity) +{ + // svuint16_t vOpacity = svdup_u16(hwOpacity); + // vTarget = vSource * vOpacity + vTarget * (256 - vOpacity); + + svuint16_t vTemp0 = svmul_n_u16_m(svptrue_b16(), vSource, hwOpacity); + svuint16_t vTemp1 = svmul_n_u16_m(svptrue_b16(), + vTarget, + 256 - hwOpacity); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +/*! \note the Element range of vMask is [0, 0xFF] + * \note the hwOpacity range [0, 0x100] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_mask_and_opacity(svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask, + uint16_t hwOpacity) +{ + vMask = svsel(svcmpeq_n_u16(svptrue_b16(), vMask, 255), + svdup_u16(hwOpacity), + //(vMask * hwOpacity) >> 8, + svlsr_n_u16_m(svptrue_b16(), + svmul_n_u16_m(svptrue_b16(), vMask, hwOpacity), + 8)); + + // vTarget = vSource * vMask + vTarget * (256 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + svuint16_t vTemp1 = svmul_u16_m(svptrue_b16(), + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(256), + vMask)); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +/*! \note the Element range of vMask0/1 is [0, 0xFF] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_masks(svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask0, + svuint16_t vMask1) +{ + vMask1 = svadd_u16_m(svcmpeq_n_u16(svptrue_b16(), vMask1, 255), + vMask1, + svdup_u16(1)); + + svuint16_t vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask0, 255), + vMask1, + //(vMask0 * vMask1) >> 8, + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask0, vMask1), + 8)); + + // vTarget = vSource * vMask + vTarget * (256 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + svuint16_t vTemp1 = svmul_u16_m(svptrue_b16(), + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(256), + vMask)); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +/*! \note the Element range of vMask0/1 is [0, 0xFF] + * \note the hwOpacity range [0, 0x100] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_masks_and_opacity( + svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask0, + svuint16_t vMask1, + uint16_t hwOpacity) +{ + vMask0 = svadd_u16_m(svcmpeq_n_u16(svptrue_b16(), vMask0, 255), + vMask0, + svdup_u16(1)); + + svuint16_t vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask1, 255), /* >= 255 */ + vMask0, + //(vMask0 * vMask1) >> 8 + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask0, vMask1), + 8)); + + vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask, 255), + svdup_u16(hwOpacity), + //(vMask * hwOpacity) >> 8, + svlsr_n_u16_m(svptrue_b16(), + svmul_n_u16_m(svptrue_b16(), vMask, hwOpacity), + 8)); + + // vTarget = vSource * vMask + vTarget * (256 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + svuint16_t vTemp1 = svmul_u16_m(svptrue_b16(), + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(256), + vMask)); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +/*! \note the Element range of vMask0/1 is [0, 0xFF] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_3masks(svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask0, + svuint16_t vMask1, + svuint16_t vMask2) +{ + vMask0 = svadd_u16_m(svcmpeq_n_u16(svptrue_b16(), vMask0, 255), + vMask0, + svdup_u16(1)); + + svuint16_t vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask1, 255), + vMask0, + //(vMask0 * vMask1) >> 8 + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask0, vMask1), + 8)); + + vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask2, 255), + vMask, + //(vMask * vMask2) >> 8 + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask, vMask2), + 8)); + + // vTarget = vSource * vMask + vTarget * (256 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + svuint16_t vTemp1 = svmul_u16_m(svptrue_b16(), + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(256), + vMask)); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +/*! \note the Element range of vMask0/1 is [0, 0xFF] + * \note the hwOpacity range [0, 0x100] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_3masks_and_opacity( + svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask0, + svuint16_t vMask1, + svuint16_t vMask2, + uint16_t hwOpacity) +{ + vMask0 = svadd_u16_m(svcmpeq_n_u16(svptrue_b16(), vMask0, 255), + vMask0, + svdup_u16(1)); + + svuint16_t vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask1, 255), + vMask0, + //(vMask0 * vMask1) >> 8 + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask0, vMask1), + 8)); + + vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask2, 255), + vMask, + svlsr_n_u16_m(svptrue_b16(), + svmul_u16_m(svptrue_b16(), vMask, vMask2), + 8)); + //(vMask * vMask2) >> 8); + + vMask = + svsel(svcmpge_n_u16(svptrue_b16(), vMask, 255), + svdup_u16(hwOpacity), + //(vMask * hwOpacity) >> 8 + svlsr_n_u16_m(svptrue_b16(), + svmul_n_u16_m(svptrue_b16(), vMask, hwOpacity), + 8)); + + // vTarget = vSource * vMask + vTarget * (256 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + svuint16_t vTemp1 = svmul_u16_m(svptrue_b16(), + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(256), + vMask)); + vTarget = svadd_u16_m(svptrue_b16(), vTemp0, vTemp1); + + return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; +} + +#endif /* SDL_SVE2_EXTENSION_H */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_swizzle.h b/src/video/arm/SDL_sve2_swizzle.h new file mode 100644 index 0000000000..a2d6f978d2 --- /dev/null +++ b/src/video/arm/SDL_sve2_swizzle.h @@ -0,0 +1,2375 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + 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. +*/ + +#if !defined(SD_SVE2_SWIZZLE_H) //&& (defined(__ARM_FEATURE_SVE2) && __ARM_FEATURE_SVE2) +#define SD_SVE2_SWIZZLE_H + +#include "SDL_sve2_extension.h" + +#define sdl_sve_rgb32_stride_impl(ma_sve_chn_iterator, ...) \ + sdl_sve_stride_loop_rgb32(uStride, vTailPred) \ + { \ + \ + svuint16x4_t vSourceLow16x4 = svundef4_u16(); \ + svuint16x4_t vSourceHigh16x4 = svundef4_u16(); \ + \ + svuint16x4_t vTargetLow16x4 = svundef4_u16(); \ + svuint16x4_t vTargetHigh16x4 = svundef4_u16(); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwSource, \ + &vSourceLow16x4, \ + &vSourceHigh16x4); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwTarget, \ + &vTargetLow16x4, \ + &vTargetHigh16x4); \ + \ + /* process low half */ \ + ma_sve_chn_iterator(vSourceLow16x4, vTargetLow16x4, \ + __VA_ARGS__); \ + \ + /* process high half */ \ + ma_sve_chn_iterator(vSourceHigh16x4, vTargetHigh16x4, \ + __VA_ARGS__); \ + \ + svst4ub_u16(vTailPred, \ + (uint8_t *)pwTarget, \ + vTargetLow16x4, \ + vTargetHigh16x4); \ + \ + pwSource += sve_iteration_advance; \ + pwTarget += sve_iteration_advance; \ + } + +#define sdl_sve_rgb32_no_alpha_stride_impl( \ + ma_alpha_idx, \ + ma_sve_chn_iterator, \ + ...) \ + sdl_sve_stride_loop_rgb32(uStride, vTailPred) \ + { \ + \ + svuint16x4_t vSourceLow16x4 = svundef4_u16(); \ + svuint16x4_t vSourceHigh16x4 = svundef4_u16(); \ + \ + svuint16x4_t vTargetLow16x4 = svundef4_u16(); \ + svuint16x4_t vTargetHigh16x4 = svundef4_u16(); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwSource, \ + &vSourceLow16x4, \ + &vSourceHigh16x4); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwTarget, \ + &vTargetLow16x4, \ + &vTargetHigh16x4); \ + \ + vSourceLow16x4 = svset4(vSourceLow16x4, \ + (ma_alpha_idx), \ + svdup_u16(0xFF)); \ + vSourceHigh16x4 = svset4(vSourceHigh16x4, \ + (ma_alpha_idx), \ + svdup_u16(0xFF)); \ + \ + /* process low half */ \ + ma_sve_chn_iterator(vSourceLow16x4, vTargetLow16x4, \ + __VA_ARGS__); \ + \ + /* process high half */ \ + ma_sve_chn_iterator(vSourceHigh16x4, vTargetHigh16x4, \ + __VA_ARGS__); \ + \ + svst4ub_u16(vTailPred, \ + (uint8_t *)pwTarget, \ + vTargetLow16x4, \ + vTargetHigh16x4); \ + \ + pwSource += sve_iteration_advance; \ + pwTarget += sve_iteration_advance; \ + } + +#define sdl_sve_rgb32_to_rgb565_stride_impl(ma_sve_chn_iterator, ...) \ + sdl_sve_stride_loop_rgb32(uStride, vTailPred) \ + { \ + \ + svuint16x4_t vSourceLow16x4 = svundef4_u16(); \ + svuint16x4_t vSourceHigh16x4 = svundef4_u16(); \ + \ + svuint16x3_t vTargetLow16x3 = svundef3_u16(); \ + svuint16x3_t vTargetHigh16x3 = svundef3_u16(); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwSource, \ + &vSourceLow16x4, \ + &vSourceHigh16x4); \ + \ + svld3rgb565_u16(vTailPred, \ + phwTarget, \ + &vTargetLow16x3, \ + &vTargetHigh16x3); \ + \ + ma_sve_chn_iterator(vSourceLow16x4, vTargetLow16x3, \ + __VA_ARGS__); \ + \ + ma_sve_chn_iterator(vSourceHigh16x4, vTargetHigh16x3, \ + __VA_ARGS__); \ + \ + svst3rgb565_u16(vTailPred, \ + phwTarget, \ + vTargetLow16x3, \ + vTargetHigh16x3); \ + \ + pwSource += sve_iteration_advance; \ + phwTarget += sve_iteration_advance; \ + } + +#define sdl_sve_rgb32_no_alpha_to_rgb565_stride_impl( \ + ma_alpha_idx, \ + ma_sve_chn_iterator, \ + ...) \ + sdl_sve_stride_loop_rgb32(uStride, vTailPred) \ + { \ + \ + svuint16x4_t vSourceLow16x4 = svundef4_u16(); \ + svuint16x4_t vSourceHigh16x4 = svundef4_u16(); \ + \ + svuint16x3_t vTargetLow16x3 = svundef3_u16(); \ + svuint16x3_t vTargetHigh16x3 = svundef3_u16(); \ + \ + svld4ub_u16(vTailPred, \ + (uint8_t *)pwSource, \ + &vSourceLow16x4, \ + &vSourceHigh16x4); \ + \ + vSourceLow16x4 = svset4(vSourceLow16x4, \ + (ma_alpha_idx), \ + svdup_u16(0xFF)); \ + vSourceHigh16x4 = svset4(vSourceHigh16x4, \ + (ma_alpha_idx), \ + svdup_u16(0xFF)); \ + \ + svld3rgb565_u16(vTailPred, \ + phwTarget, \ + &vTargetLow16x3, \ + &vTargetHigh16x3); \ + \ + ma_sve_chn_iterator(vSourceLow16x4, vTargetLow16x3, \ + __VA_ARGS__); \ + \ + ma_sve_chn_iterator(vSourceHigh16x4, vTargetHigh16x3, \ + __VA_ARGS__); \ + \ + svst3rgb565_u16(vTailPred, \ + phwTarget, \ + vTargetLow16x3, \ + vTargetHigh16x3); \ + \ + pwSource += sve_iteration_advance; \ + phwTarget += sve_iteration_advance; \ + } + +#ifndef sdl_sve_rgb32_blend_op_fill_alpha +#define sdl_sve_rgb32_blend_op_fill_alpha(ma_alpha_chn_idx) +#endif + +#ifndef sdl_sve_rgb32_blend_op_copy_alpha +#define sdl_sve_rgb32_blend_op_copy_alpha(ma_alpha_chn_idx) +#endif + +/* + * Source: ACCC and CCCA + */ +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_accc_stride_blend_to_accc_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn, + + sdl_sve_rgb32_blend_op_fill_alpha(3); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_accc_stride_blend_to_accc_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_ccca_stride_blend_to_ccca_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_fill_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_ccca_stride_blend_to_ccca_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn, + + sdl_sve_rgb32_blend_op_copy_alpha(0); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_accc_blend_to_accc_fill_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_accc_stride_blend_to_accc_fill_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_accc_blend_to_accc_copy_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_accc_stride_blend_to_accc_copy_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_ccca_blend_to_ccca_fill_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_ccca_stride_blend_to_ccca_fill_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_ccca_blend_to_ccca_copy_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_ccca_stride_blend_to_ccca_copy_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_a123_stride_blend_to_321a_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_fill_alpha(3); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_a123_stride_blend_to_321a_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_copy_alpha(3); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_a123_blend_to_321a_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_a123_stride_blend_to_321a_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_a123_blend_to_321a_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_a123_stride_blend_to_321a_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123a_stride_blend_to_a321_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_fill_alpha(0); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123a_stride_blend_to_a321_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_copy_alpha(0); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123a_blend_to_a321_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123a_stride_blend_to_a321_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123a_blend_to_a321_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123a_stride_blend_to_a321_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_accc_stride_blend_to_ccca_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_accc_ccca, + sdl_sve_rgb32_blend_op_fill_alpha(3); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_accc_stride_blend_to_ccca_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_accc_ccca, + sdl_sve_rgb32_blend_op_copy_alpha(3); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_accc_blend_to_ccca_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_accc_stride_blend_to_ccca_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_accc_blend_to_ccca_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_accc_stride_blend_to_ccca_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_ccca_stride_blend_to_accc_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_ccca_accc, + sdl_sve_rgb32_blend_op_fill_alpha(0); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_ccca_stride_blend_to_accc_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_ccca_accc, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_ccca_blend_to_accc_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_ccca_stride_blend_to_accc_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_ccca_blend_to_accc_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_ccca_stride_blend_to_accc_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_a123_stride_blend_to_a321_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_a123_a321, + sdl_sve_rgb32_blend_op_fill_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_a123_stride_blend_to_a321_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_a123_a321, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_a123_blend_to_a321_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_a123_stride_blend_to_a321_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_a123_blend_to_a321_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_a123_stride_blend_to_a321_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123a_stride_blend_to_321a_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_123a_321a, + sdl_sve_rgb32_blend_op_fill_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123a_stride_blend_to_321a_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + sdl_sve_rgb32_stride_impl(sdl_sve_pixel_u16x4_foreach_chn_123a_321a, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123a_blend_to_321a_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123a_stride_blend_to_321a_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123a_blend_to_321a_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123a_stride_blend_to_321a_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +/* + * Source: XCCC and CCCX + */ + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xccc_stride_blend_to_accc_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_fill_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xccc_stride_blend_to_accc_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_cccx_stride_blend_to_ccca_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_fill_alpha(0); + + ); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_cccx_stride_blend_to_ccca_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xccc_blend_to_accc_fill_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xccc_stride_blend_to_accc_fill_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xccc_blend_to_accc_copy_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xccc_stride_blend_to_accc_copy_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_cccx_blend_to_ccca_fill_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_cccx_stride_blend_to_ccca_fill_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_cccx_blend_to_ccca_copy_alpha( + uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_cccx_stride_blend_to_ccca_copy_alpha( + (uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_x123_stride_blend_to_321a_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_fill_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_x123_stride_blend_to_321a_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_x123_blend_to_321a_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_x123_stride_blend_to_321a_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_x123_blend_to_321a_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_x123_stride_blend_to_321a_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123x_stride_blend_to_a321_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_fill_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123x_stride_blend_to_a321_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_src_dst_rev, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123x_blend_to_a321_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123x_stride_blend_to_a321_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123x_blend_to_a321_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123x_stride_blend_to_a321_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xccc_stride_blend_to_ccca_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_accc_ccca, + sdl_sve_rgb32_blend_op_fill_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xccc_stride_blend_to_ccca_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_accc_ccca, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xccc_blend_to_ccca_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xccc_stride_blend_to_ccca_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xccc_blend_to_ccca_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xccc_stride_blend_to_ccca_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_cccx_stride_blend_to_accc_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_ccca_accc, + sdl_sve_rgb32_blend_op_fill_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_cccx_stride_blend_to_accc_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_ccca_accc, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_cccx_blend_to_accc_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_cccx_stride_blend_to_accc_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_cccx_blend_to_accc_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_cccx_stride_blend_to_accc_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_x123_stride_blend_to_a321_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_a123_a321, + sdl_sve_rgb32_blend_op_fill_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_x123_stride_blend_to_a321_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(3, + sdl_sve_pixel_u16x4_foreach_chn_a123_a321, + sdl_sve_rgb32_blend_op_copy_alpha(3);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_x123_blend_to_a321_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_x123_stride_blend_to_a321_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_x123_blend_to_a321_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_x123_stride_blend_to_a321_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123x_stride_blend_to_321a_fill_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_123a_321a, + sdl_sve_rgb32_blend_op_fill_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_123x_stride_blend_to_321a_copy_alpha( + uint32_t *SDL_RESTRICT pwSource, + uint32_t *SDL_RESTRICT pwTarget, + size_t uStride) +{ + sdl_sve_rgb32_no_alpha_stride_impl(0, + sdl_sve_pixel_u16x4_foreach_chn_123a_321a, + sdl_sve_rgb32_blend_op_copy_alpha(0);); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123x_blend_to_321a_fill_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123x_stride_blend_to_321a_fill_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_123x_blend_to_321a_copy_alpha(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_123x_stride_blend_to_321a_copy_alpha((uint32_t *)pchSource, + (uint32_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1) +static inline void sdl_sve_8888_to_8888_swizzle_dispatcher(SDL_BlitInfo *info) +{ + int width = info->dst_w; + int height = info->dst_h; + uint8_t *src = info->src; + int srcskip = info->src_skip; + uint8_t *dst = info->dst; + int dstskip = info->dst_skip; + + const SDL_PixelFormatDetails *srcfmt = info->src_fmt; + const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; + + // Set up some basic variables + int srcbpp = srcfmt->bytes_per_pixel; + int dstbpp = dstfmt->bytes_per_pixel; + + assert((srcbpp == 4) && (dstbpp == 4)); + + bool fill_alpha = (!dstfmt->Amask); + + int srcstride = srcskip + srcbpp * width; + int dststride = dstskip + dstbpp * width; + + switch (srcfmt->format) { + case SDL_PIXELFORMAT_XRGB8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_xccc_blend_to_accc_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_xccc_blend_to_accc_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_xccc_blend_to_ccca_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_xccc_blend_to_ccca_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_x123_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_x123_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_x123_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_x123_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_ARGB8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_accc_blend_to_accc_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_accc_blend_to_accc_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_accc_blend_to_ccca_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_accc_blend_to_ccca_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_a123_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_a123_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_a123_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_a123_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_RGBX8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_cccx_blend_to_accc_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_cccx_blend_to_accc_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_cccx_blend_to_ccca_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_cccx_blend_to_ccca_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_123x_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123x_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_123x_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123x_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_ccca_blend_to_accc_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_ccca_blend_to_accc_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_ccca_blend_to_ccca_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_ccca_blend_to_ccca_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_123a_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123a_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_123a_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123a_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_XBGR8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_x123_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_x123_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_x123_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_x123_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_xccc_blend_to_accc_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_xccc_blend_to_accc_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_xccc_blend_to_ccca_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_xccc_blend_to_ccca_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_a123_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_a123_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_a123_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_a123_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_accc_blend_to_accc_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_accc_blend_to_accc_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_accc_blend_to_ccca_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_accc_blend_to_ccca_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_BGRX8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_123x_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123x_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_123x_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123x_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_cccx_blend_to_accc_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_cccx_blend_to_accc_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_cccx_blend_to_ccca_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_cccx_blend_to_ccca_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + switch (dstfmt->format) { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_XRGB8888: + if (fill_alpha) { + sdl_sve_123a_blend_to_a321_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123a_blend_to_a321_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_RGBX8888: + if (fill_alpha) { + sdl_sve_123a_blend_to_321a_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_123a_blend_to_321a_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_XBGR8888: + if (fill_alpha) { + sdl_sve_ccca_blend_to_accc_fill_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_ccca_blend_to_accc_copy_alpha(src, + srcstride, + dst, + dststride, + width, + height); + } + break; + + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_BGRX8888: + if (fill_alpha) { + sdl_sve_ccca_blend_to_ccca_fill_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } else { + sdl_sve_ccca_blend_to_ccca_copy_alpha( + src, + srcstride, + dst, + dststride, + width, + height); + } + break; + default: + assert(false); + break; + } + break; + + default: + assert(false); + break; + } +} + +#ifndef sdl_sve_rgb32_blend_to_rgb565_op +#define sdl_sve_rgb32_blend_to_rgb565_op(ma_alpha_chn_idx) +#endif + +/* + * ACCC or CCCA + */ +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_argb8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_to_rgb565_stride_impl( + sdl_sve_pixel_u16x4_foreach_chn_argb_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(3); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_argb8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_argb8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_rgba8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_to_rgb565_stride_impl( + sdl_sve_pixel_u16x4_foreach_chn_rgba_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(0); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_rgba8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_rgba8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_bgra8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_to_rgb565_stride_impl( + sdl_sve_pixel_u16x4_foreach_chn_bgra_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(0); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_bgra8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_bgra8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_abgr8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_to_rgb565_stride_impl( + sdl_sve_pixel_u16x4_foreach_chn_abgr_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(3); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_abgr8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_abgr8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +/* + * XCCC or CCCX + */ +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xrgb8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_no_alpha_to_rgb565_stride_impl( + 3, + sdl_sve_pixel_u16x4_foreach_chn_argb_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(3); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xrgb8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xrgb8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_rgbx8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_no_alpha_to_rgb565_stride_impl( + 0, + sdl_sve_pixel_u16x4_foreach_chn_rgba_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(0); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_rgbx8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_rgbx8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_bgrx8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_no_alpha_to_rgb565_stride_impl( + 0, + sdl_sve_pixel_u16x4_foreach_chn_bgra_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(0); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_bgrx8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_bgrx8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_xbgr8888_stride_blend_to_rgb565(uint32_t *SDL_RESTRICT pwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride) +{ + sdl_sve_rgb32_no_alpha_to_rgb565_stride_impl( + 3, + sdl_sve_pixel_u16x4_foreach_chn_abgr_rgb565, + { + sdl_sve_rgb32_blend_to_rgb565_op(3); + }); +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_xbgr8888_blend_to_rgb565(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight) +{ + while (nHeight--) { + + sdl_sve_xbgr8888_stride_blend_to_rgb565((uint32_t *)pchSource, + (uint16_t *)pchTarget, + nWidth); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1) +static inline void sdl_sve_rgb32_to_rgb565_swizzle_dispatcher(SDL_BlitInfo *info) +{ + int width = info->dst_w; + int height = info->dst_h; + uint8_t *src = info->src; + int srcskip = info->src_skip; + uint8_t *dst = info->dst; + int dstskip = info->dst_skip; + + const SDL_PixelFormatDetails *srcfmt = info->src_fmt; + const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; + + // Set up some basic variables + int srcbpp = srcfmt->bytes_per_pixel; + int dstbpp = dstfmt->bytes_per_pixel; + + assert(srcbpp == 4); + assert(dstbpp == 2); + + int srcstride = srcskip + srcbpp * width; + int dststride = dstskip + dstbpp * width; + + switch (srcfmt->format) { + case SDL_PIXELFORMAT_XRGB8888: + sdl_sve_xrgb8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_ARGB8888: + sdl_sve_argb8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_RGBX8888: + sdl_sve_rgbx8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_RGBA8888: + sdl_sve_rgba8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_XBGR8888: + sdl_sve_xbgr8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_ABGR8888: + sdl_sve_abgr8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_BGRX8888: + sdl_sve_bgrx8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + case SDL_PIXELFORMAT_BGRA8888: + sdl_sve_bgra8888_blend_to_rgb565(src, + srcstride, + dst, + dststride, + width, + height); + break; + + default: + assert(false); + break; + } +} + +#endif /* SD_SVE2_SWIZZLE_H */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_util.h b/src/video/arm/SDL_sve2_util.h new file mode 100644 index 0000000000..2a1602b432 --- /dev/null +++ b/src/video/arm/SDL_sve2_util.h @@ -0,0 +1,206 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_SVE2_UTIL_H +#define SDL_SVE2_UTIL_H + +#undef SVE_0_CONNECT2 +#undef SVE_0_CONNECT3 +#undef SVE_0_CONNECT4 +#undef SVE_0_CONNECT5 +#undef SVE_0_CONNECT6 +#undef SVE_0_CONNECT7 +#undef SVE_0_CONNECT8 +#undef SVE_0_CONNECT9 + +#undef SVE_CONNECT2 +#undef SVE_CONNECT3 +#undef SVE_CONNECT4 +#undef SVE_CONNECT5 +#undef SVE_CONNECT6 +#undef SVE_CONNECT7 +#undef SVE_CONNECT8 +#undef SVE_CONNECT9 +#undef ALT_SVE_CONNECT2 + +#undef SVE_SAFE_NAME + +#undef SVE_CONNECT + +#define SVE_0_CONNECT2(ma_A, ma_B) ma_A##ma_B +#define SVE_0_CONNECT3(ma_A, ma_B, ma_C) ma_A##ma_B##ma_C +#define SVE_0_CONNECT4(ma_A, ma_B, ma_C, ma_D) ma_A##ma_B##ma_C##ma_D +#define SVE_0_CONNECT5(ma_A, ma_B, ma_C, ma_D, ma_E) \ + ma_A##ma_B##ma_C##ma_D##ma_E +#define SVE_0_CONNECT6(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F) \ + ma_A##ma_B##ma_C##ma_D##ma_E##ma_F +#define SVE_0_CONNECT7(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G) \ + ma_A##ma_B##ma_C##ma_D##ma_E##ma_F##ma_G +#define SVE_0_CONNECT8(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H) \ + ma_A##ma_B##ma_C##ma_D##ma_E##ma_F##ma_G##ma_H +#define SVE_0_CONNECT9(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H, ma_I) \ + ma_A##ma_B##ma_C##ma_D##ma_E##ma_F##ma_G##ma_H##ma_I + +#define ALT_SVE_CONNECT2(ma_A, ma_B) SVE_0_CONNECT2(ma_A, ma_B) +#define SVE_CONNECT2(ma_A, ma_B) SVE_0_CONNECT2(ma_A, ma_B) +#define SVE_CONNECT3(ma_A, ma_B, ma_C) SVE_0_CONNECT3(ma_A, ma_B, ma_C) +#define SVE_CONNECT4(ma_A, ma_B, ma_C, ma_D) \ + SVE_0_CONNECT4(ma_A, ma_B, ma_C, ma_D) +#define SVE_CONNECT5(ma_A, ma_B, ma_C, ma_D, ma_E) \ + SVE_0_CONNECT5(ma_A, ma_B, ma_C, ma_D, ma_E) +#define SVE_CONNECT6(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F) \ + SVE_0_CONNECT6(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F) +#define SVE_CONNECT7(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G) \ + SVE_0_CONNECT7(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G) +#define SVE_CONNECT8(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H) \ + SVE_0_CONNECT8(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H) +#define SVE_CONNECT9(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H, ma_I) \ + SVE_0_CONNECT9(ma_A, ma_B, ma_C, ma_D, ma_E, ma_F, ma_G, ma_H, ma_I) + +#define SVE_CONNECT(...) \ + ALT_SVE_CONNECT2(SVE_CONNECT, \ + SVE_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__) + +#ifndef SVE_VA_NUM_ARGS_IMPL +#define SVE_VA_NUM_ARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, \ + _12, _13, _14, _15, _16, ma_N, ...) ma_N +#endif + +#ifndef SVE_VA_NUM_ARGS +#define SVE_VA_NUM_ARGS(...) \ + SVE_VA_NUM_ARGS_IMPL(0, ##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, \ + 8, 7, 6, 5, 4, 3, 2, 1, 0) +#endif + +#define SVE_SAFE_NAME(ma_NAME) SVE_CONNECT3(ma_, ma_NAME, ma_LINEma_) + +/* ---------------------------------------------------------------------------* + * SVE Test Helper * + * ---------------------------------------------------------------------------*/ + +#define SVT_PRINT_VECTOR(ma_VECOTOR, ma_ELEMENT_T, ma_FORMAT_STRING) \ + do { \ + int_fast8_t nElementCount = svcntb_pat(SV_ALL) / sizeof(ma_ELEMENT_T); \ + uint8_t SVE_SAFE_NAME(chVectorBuffer) \ + [nElementCount * sizeof(ma_ELEMENT_T)]; \ + \ + svst1_u8(svptrue_b8(), \ + SVE_SAFE_NAME(chVectorBuffer), \ + svreinterpret_u8(ma_VECOTOR)); \ + \ + ma_ELEMENT_T *pElement = (ma_ELEMENT_T *)SVE_SAFE_NAME(chVectorBuffer); \ + printf("%s\t[", #ma_VECOTOR); \ + do { \ + printf(ma_FORMAT_STRING "\t", (int)*pElement++); \ + } while (--nElementCount); \ + printf("]\r\n"); \ + } while (0) + +#define SVT_INIT_VECOTR(ma_VECTOR, ma_ELEMENT_T, ...) \ + do { \ + uint8_t SVE_SAFE_NAME(chVectorBuffer)[svcntb_pat(SV_ALL)]; \ + \ + memset(SVE_SAFE_NAME(chVectorBuffer), /* This should NOT be SDL_memset() */ \ + 0, \ + sizeof(SVE_SAFE_NAME(chVectorBuffer))); \ + memcpy(SVE_SAFE_NAME(chVectorBuffer), /* This should NOT be SDL_memcpy() */ \ + (ma_ELEMENT_T[]){ __VA_ARGS__ }, \ + MIN(sizeof(SVE_SAFE_NAME(chVectorBuffer)), \ + sizeof((ma_ELEMENT_T[]){ __VA_ARGS__ }))); \ + \ + ma_VECTOR = svld1(svptrue_b8(), \ + (ma_ELEMENT_T *)SVE_SAFE_NAME(chVectorBuffer)); \ + } while (0) + +#define SVT_INIT_PRED(ma_PREDICT, ...) \ + do { \ + uint8_t SVE_SAFE_NAME(chBuffer)[svlen(svundef_u64())]; \ + memset(SVE_SAFE_NAME(chBuffer), /* This should NOT be SDL_memset() */ \ + 0, \ + sizeof(SVE_SAFE_NAME(chBuffer))); \ + \ + memcpy(SVE_SAFE_NAME(chBuffer), /* This should NOT be SDL_memcpy() */ \ + (uint8_t[]){ __VA_ARGS__ }, \ + MIN(sizeof(SVE_SAFE_NAME(chBuffer)), \ + sizeof((uint8_t[]){ __VA_ARGS__ }))); \ + \ + ma_PREDICT = (*(svbool_t *)SVE_SAFE_NAME(chBuffer)); \ + } while (0) + +#define SVT_PRINT_PRED(ma_PREDICT, ma_TYPE_T) \ + do { \ + printf("%8s\t[", #ma_PREDICT); \ + uint16_t SVE_SAFE_NAME(hwBuffer)[svlen(svundef_u64()) / 2]; \ + memset(SVE_SAFE_NAME(hwBuffer), /* This should NOT be SDL_memset() */ \ + 0, \ + sizeof(SVE_SAFE_NAME(hwBuffer))); \ + *(volatile svbool_t *)SVE_SAFE_NAME(hwBuffer) = (ma_PREDICT); \ + \ + uint_fast16_t SVE_SAFE_NAME(nTotalBits) = svlen(svundef_u8()); \ + uint_fast8_t SVE_SAFE_NAME(nElementBits) = sizeof(ma_TYPE_T); \ + \ + uint16_t *phwPred = SVE_SAFE_NAME(hwBuffer); \ + do { \ + uint16_t hwPred = *phwPred++; \ + \ + for (uint_fast8_t n = 0; \ + n < 16; \ + n += SVE_SAFE_NAME(nElementBits)) { \ + \ + if (hwPred & 0x01) { \ + printf("True "); \ + } else { \ + printf("False"); \ + } \ + printf("%*s\t", (int)sizeof(ma_TYPE_T) - 1, ""); \ + hwPred >>= SVE_SAFE_NAME(nElementBits); \ + } \ + \ + SVE_SAFE_NAME(nTotalBits) -= 16; \ + } while (SVE_SAFE_NAME(nTotalBits)); \ + \ + printf("]\r\n"); \ + } while (0) + +#define SVT_PRINT_BUFFER(ma_BUFF_PTR, ma_SIZE, ma_TYPE_T, ma_FMT_STR, ma_STRIDE) \ + do { \ + ma_TYPE_T *pBuffer = (ma_TYPE_T *)ma_BUFF_PTR; \ + size_t nElementCount = (ma_SIZE) / sizeof(ma_TYPE_T); \ + \ + size_t nStrideSize = (ma_STRIDE); \ + size_t nLineCount = 0; \ + \ + printf("%s\n\t", #ma_BUFF_PTR); \ + do { \ + \ + printf(ma_FMT_STR " ", *pBuffer++); \ + nLineCount++; \ + if (nLineCount >= nStrideSize) { \ + nLineCount = 0; \ + printf("\n\t"); \ + } \ + \ + } while (--nElementCount); \ + printf("\n"); \ + \ + } while (0) + +#endif /* SDL_SVE2_UTIL_H */ \ No newline at end of file diff --git a/test/testplatform.c b/test/testplatform.c index 4e79f6326c..d42c72d10f 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -414,6 +414,7 @@ static int TestCPUInfo(bool verbose) SDL_Log("NEON %s", SDL_HasNEON() ? "detected" : "not detected"); SDL_Log("LSX %s", SDL_HasLSX() ? "detected" : "not detected"); SDL_Log("LASX %s", SDL_HasLASX() ? "detected" : "not detected"); + SDL_Log("SVE2 %s", SDL_HasSVE2() ? "detected" : "not detected"); SDL_Log("System RAM %d MB", SDL_GetSystemRAM()); SDL_Log("System memory page size %d bytes", SDL_GetSystemPageSize()); } From a400a70484200c9108ceb8926c3e7955cb60de2b Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Thu, 14 May 2026 06:39:08 +0000 Subject: [PATCH 278/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_intrin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h index ecd8192941..e723b02c2d 100644 --- a/include/SDL3/SDL_intrin.h +++ b/include/SDL3/SDL_intrin.h @@ -88,8 +88,8 @@ /** * Defined if (and only if) the compiler supports ARM SVE2 intrinsics. * - * If this macro is defined, SDL will have already included `` - * as appropriate. + * If this macro is defined, SDL will have already included `` as + * appropriate. * * \since This macro is available since SDL 3.6.0. */ From b333c04cccd338a7d81fff46c07415b0b82e89ca Mon Sep 17 00:00:00 2001 From: Vlad-Florin Ilie <35900803+VladFlorinIlie@users.noreply.github.com> Date: Thu, 14 May 2026 09:40:55 +0300 Subject: [PATCH 279/407] Fix Steam Controller 2026 (triton) rumble (#15558) --- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index 812a9c4059..9d2b026eec 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -35,6 +35,9 @@ // Always 1kHz according to USB descriptor, but actually about 4 ms. #define TRITON_SENSOR_UPDATE_INTERVAL_US 4032 +// Steam Controller hardware safety timeout is around 50ms, so we resend rumble every 40ms +#define TRITON_RUMBLE_RESEND_INTERVAL_MS 40 + enum { SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM = 11, @@ -96,6 +99,9 @@ typedef struct Uint64 sensor_timestamp_ns; Uint64 last_button_state; Uint64 last_lizard_update; + Uint16 low_frequency_rumble; + Uint16 high_frequency_rumble; + Uint64 last_rumble_time; } SDL_DriverSteamTriton_Context; static bool IsProteusDongle(Uint16 product_id) @@ -354,6 +360,8 @@ static void HIDAPI_DriverSteamTriton_SetDevicePlayerIndex(SDL_HIDAPI_Device *dev { } +static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device) { SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; @@ -369,6 +377,12 @@ static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device) DisableSteamTritonLizardMode(device->dev); ctx->last_lizard_update = now; } + + if (ctx->low_frequency_rumble || ctx->high_frequency_rumble) { + if ((now - ctx->last_rumble_time) >= TRITON_RUMBLE_RESEND_INTERVAL_MS) { + HIDAPI_DriverSteamTriton_RumbleJoystick(device, joystick, ctx->low_frequency_rumble, ctx->high_frequency_rumble); + } + } } for (;;) { @@ -436,10 +450,14 @@ static bool HIDAPI_DriverSteamTriton_OpenJoystick(SDL_HIDAPI_Device *device, SDL static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { + SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; int rc; - //RKRK Not sure about size. Probably 64+1 is OK for ORs - Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES]; + ctx->low_frequency_rumble = low_frequency_rumble; + ctx->high_frequency_rumble = high_frequency_rumble; + ctx->last_rumble_time = SDL_GetTicks(); + + Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES] = { 0 }; OutputReportMsg *msg = (OutputReportMsg *)(buffer); msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE; @@ -450,9 +468,12 @@ static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, S msg->payload.hapticRumble.right.speed = high_frequency_rumble; msg->payload.hapticRumble.right.gain = 0; - rc = SDL_hid_write(device->dev, buffer, sizeof(buffer)); - if (rc != sizeof(buffer)) { + if (rc < 0) { + SDL_LogError(SDL_LOG_CATEGORY_INPUT, + "Steam Controller HID Write FAILED! rc: %d. SDL_Error: %s", + rc, SDL_GetError()); + return false; } return true; From 0defb4ddfc29c7201c57d5dc8cceb07e29e07f62 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 13 May 2026 10:01:50 -0700 Subject: [PATCH 280/407] Added controller sensor support for GameInput v3 Verified working with the DualSense controller --- src/joystick/gdk/SDL_gameinputjoystick.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index c1c57a43b3..5f41f2864f 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -34,11 +34,6 @@ #define SDL_GAMEINPUT_DEFAULT false #endif -// Enable sensor support in GameInput 2.0, once we have a device that can be used for testing -#if GAMEINPUT_API_VERSION >= 2 -//#define GAMEINPUT_SENSOR_SUPPORT -#endif - enum { SDL_GAMEPAD_BUTTON_GAMEINPUT_SHARE = 11 @@ -651,17 +646,17 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, true); } -#ifdef GAMEINPUT_SENSOR_SUPPORT +#if GAMEINPUT_API_VERSION >= 3 if (info->supportedInput & GameInputKindSensors) { - // FIXME: What's the sensor update rate? if (info->sensorsInfo->supportedSensors & GameInputSensorsGyrometer) { - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 60.0f); } if (info->sensorsInfo->supportedSensors & GameInputSensorsAccelerometer) { - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 60.0f); } } -#endif +#endif // GAMEINPUT_API_VERSION >= 3 + return true; } @@ -907,7 +902,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) GAMEINPUT_ControllerUpdate(joystick, reading, timestamp); } -#ifdef GAMEINPUT_SENSOR_SUPPORT +#if GAMEINPUT_API_VERSION >= 3 if (hwdata->report_sensors) { GameInputSensorsState sensor_state; @@ -930,7 +925,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) } } } -#endif // GAMEINPUT_SENSOR_SUPPORT +#endif // GAMEINPUT_API_VERSION >= 3 reading->Release(); From 006959ca87eb1406a3d1f7021b6852b01600bcb0 Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Wed, 13 May 2026 23:49:01 -0700 Subject: [PATCH 281/407] Add dual touchpad support to testcontroller (#15540) --- test/CMakeLists.txt | 3 +- test/gamepad_dual_touchpad.h | 57 +++++++++ test/gamepad_dual_touchpad.png | Bin 0 -> 643 bytes test/gamepadutils.c | 221 +++++++++++++++++++++------------ test/gamepadutils.h | 2 +- test/testcontroller.c | 68 ++++++---- test/testutils.c | 1 + 7 files changed, 244 insertions(+), 108 deletions(-) create mode 100644 test/gamepad_dual_touchpad.h create mode 100644 test/gamepad_dual_touchpad.png diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b6e7b724bf..895f885b13 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -89,7 +89,7 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.20) endif() if(DOS) - set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") + set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_dual_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") set(DOS83_SHORT "UNIFONT.HEX;UNIFONTL.TXT;PHYSADEV.PNG;LOGADEV.PNG;AUDIOFIL.PNG;SNDBRD.PNG;SNDLVL.PNG;TRASHCAN.PNG;MSDFFONT.PNG;MSDFFONT.CSV;GP_FRONT.PNG;GP_BACK.PNG;GP_FABXY.PNG;GP_FAXBY.PNG;GP_FBAYX.PNG;GP_FSONY.PNG;GP_BATT.PNG;GP_BATTX.PNG;GP_BATTW.PNG;GP_TOUCH.PNG;GP_BTN.PNG;GP_BTNSM.PNG;GP_BTNBG.PNG;GP_AXIS.PNG;GP_AXARW.PNG;GP_WIRED.PNG;GP_WLESS.PNG;SDLROUND.PNG") endif() @@ -296,6 +296,7 @@ files2headers(gamepad_image_headers gamepad_button_background.png gamepad_button.png gamepad_button_small.png + gamepad_dual_touchpad.png gamepad_face_abxy.png gamepad_face_axby.png gamepad_face_bayx.png diff --git a/test/gamepad_dual_touchpad.h b/test/gamepad_dual_touchpad.h new file mode 100644 index 0000000000..39909cc373 --- /dev/null +++ b/test/gamepad_dual_touchpad.h @@ -0,0 +1,57 @@ +unsigned char gamepad_dual_touchpad_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x9f, + 0x08, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x09, 0x91, 0x77, 0x00, 0x00, 0x00, + 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, + 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, + 0x00, 0x1e, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, + 0x25, 0x25, 0x25, 0x76, 0x76, 0x76, 0x86, 0x86, 0x86, 0xc3, 0xc3, 0xc3, + 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xff, 0xff, 0xff, + 0x6b, 0xf3, 0x50, 0x72, 0x00, 0x00, 0x01, 0xfb, 0x49, 0x44, 0x41, 0x54, + 0x78, 0xda, 0xec, 0xd5, 0x81, 0x71, 0x03, 0x21, 0x0c, 0x45, 0x41, 0x0e, + 0x01, 0x39, 0xf7, 0xdf, 0x70, 0xe2, 0x16, 0x32, 0x89, 0x2c, 0x5b, 0xfb, + 0x2a, 0xf8, 0xa3, 0x59, 0x86, 0xf1, 0x50, 0xeb, 0x86, 0x13, 0x00, 0x20, + 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, 0x40, 0x00, 0x08, 0x00, 0x01, + 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, 0x40, 0x00, 0x08, 0x00, + 0x01, 0x20, 0x00, 0x04, 0xc0, 0x6f, 0xba, 0x63, 0x24, 0x16, 0x77, 0xe7, + 0xd5, 0x15, 0x01, 0xc4, 0x1c, 0xfb, 0xdc, 0x49, 0x9d, 0x3d, 0x66, 0xf4, + 0x5d, 0x5d, 0x11, 0x40, 0xcc, 0xfd, 0x95, 0xda, 0xfe, 0x8b, 0x5b, 0xbe, + 0xe7, 0xea, 0x8a, 0x00, 0x76, 0xf6, 0x25, 0x9f, 0xb7, 0xdc, 0x3d, 0x57, + 0x97, 0x04, 0x10, 0xeb, 0x64, 0x9f, 0xf2, 0xac, 0xe8, 0xb9, 0xba, 0x24, + 0x80, 0xfc, 0xa7, 0xf4, 0x7c, 0x4c, 0x3d, 0x57, 0x97, 0x04, 0x30, 0x5e, + 0x71, 0xca, 0xd1, 0x73, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xd9, 0x7c, 0xc5, 0x29, 0x67, 0xcf, 0xd5, 0x25, 0x01, + 0xc4, 0xca, 0x3f, 0xe5, 0x8a, 0x9e, 0xab, 0x4b, 0x02, 0x58, 0x91, 0xfe, + 0x98, 0x76, 0xac, 0x9e, 0xab, 0x4b, 0x02, 0x78, 0xcc, 0x75, 0x72, 0x2f, + 0x79, 0xd6, 0xec, 0xba, 0xba, 0x24, 0x80, 0x7d, 0xc5, 0xbe, 0xf3, 0x0e, + 0x79, 0xef, 0xb8, 0x76, 0xd7, 0xd5, 0x25, 0x01, 0xfc, 0x7c, 0xa8, 0xd7, + 0x48, 0xec, 0x8a, 0xce, 0xab, 0x4b, 0x02, 0x50, 0xb9, 0x00, 0x00, 0x40, + 0x00, 0x08, 0x00, 0x01, 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, + 0x40, 0x00, 0x08, 0x00, 0x01, 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, + 0x02, 0x40, 0x00, 0x08, 0x00, 0x7d, 0x46, 0xdf, 0x02, 0x0c, 0x00, 0xeb, + 0x17, 0x39, 0xb7, 0x96, 0x32, 0x99, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +unsigned int gamepad_dual_touchpad_png_len = 643; diff --git a/test/gamepad_dual_touchpad.png b/test/gamepad_dual_touchpad.png new file mode 100644 index 0000000000000000000000000000000000000000..66cbc9da821c664c734644110377c83496822243 GIT binary patch literal 643 zcmeAS@N?(olHy`uVBq!ia0y~yU;;83=5sIu$sL>%%Yl?+iEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-*xM=$r%jyOLGJ%Aa2qWjrGD`;O;a+q5sSv4Rd~{!YF1uRD6*^H*IA zW#3fiZ@*(3KAlD2b;|rtYhLW!rPAETe|7Mh}0kJC1losh%UVF0(7<#ow_kHH8e7~dYI#BJOnibbQ-gKP< ostMT1z<@QL;4xV1cAtrd;kCHs_Gv~lK?#Pz)78&qol`;+02~XCo&W#< literal 0 HcmV?d00001 diff --git a/test/gamepadutils.c b/test/gamepadutils.c index 2f0fcc55eb..4da9522d16 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -22,6 +22,7 @@ #include "gamepad_battery.h" #include "gamepad_battery_wired.h" #include "gamepad_touchpad.h" +#include "gamepad_dual_touchpad.h" #include "gamepad_button.h" #include "gamepad_button_small.h" #include "gamepad_axis.h" @@ -323,10 +324,18 @@ static const struct { 400, 5, 180.0 }, /* SDL_GAMEPAD_ELEMENT_AXIS_RIGHT_TRIGGER */ }; -static SDL_FRect touchpad_area = { +#define MAX_TOUCHPADS 2 +#define MAX_FINGERS 2 + +static const SDL_FRect touchpad_area = { 148.0f, 20.0f, 216.0f, 118.0f }; +static const SDL_FRect dual_touchpad_area[MAX_TOUCHPADS] = { + {106.0f, 20.0f, 118.0f, 118.0f}, + {288.0f, 20.0f, 118.0f, 118.0f}, +}; + typedef struct { bool down; @@ -335,6 +344,13 @@ typedef struct float pressure; } GamepadTouchpadFinger; +typedef struct +{ + SDL_FRect area; + int num_fingers; + GamepadTouchpadFinger *fingers; +} GamepadTouchpad; + struct GamepadImage { SDL_Renderer *renderer; @@ -347,6 +363,7 @@ struct GamepadImage SDL_Texture *connection_texture[2]; SDL_Texture *battery_texture[2]; SDL_Texture *touchpad_texture; + SDL_Texture *dual_touchpad_texture; SDL_Texture *button_texture; SDL_Texture *axis_texture; float gamepad_width; @@ -359,6 +376,8 @@ struct GamepadImage float battery_height; float touchpad_width; float touchpad_height; + float dual_touchpad_width; + float dual_touchpad_height; float button_width; float button_height; float axis_width; @@ -378,8 +397,8 @@ struct GamepadImage SDL_PowerState battery_state; int battery_percent; - int num_fingers; - GamepadTouchpadFinger *fingers; + int num_touchpads; + GamepadTouchpad *touchpads; }; static SDL_Texture *CreateTexture(SDL_Renderer *renderer, unsigned char *data, unsigned int len) @@ -423,6 +442,9 @@ GamepadImage *CreateGamepadImage(SDL_Renderer *renderer) ctx->touchpad_texture = CreateTexture(renderer, gamepad_touchpad_png, gamepad_touchpad_png_len); SDL_GetTextureSize(ctx->touchpad_texture, &ctx->touchpad_width, &ctx->touchpad_height); + ctx->dual_touchpad_texture = CreateTexture(renderer, gamepad_dual_touchpad_png, gamepad_dual_touchpad_png_len); + SDL_GetTextureSize(ctx->dual_touchpad_texture, &ctx->dual_touchpad_width, &ctx->dual_touchpad_height); + ctx->button_texture = CreateTexture(renderer, gamepad_button_png, gamepad_button_png_len); SDL_GetTextureSize(ctx->button_texture, &ctx->button_width, &ctx->button_height); SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); @@ -462,17 +484,20 @@ void GetGamepadImageArea(GamepadImage *ctx, SDL_FRect *area) } } -void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area) +void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area, int touchpad) { + int i; + if (!ctx) { SDL_zerop(area); return; } - area->x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2 + touchpad_area.x; - area->y = ctx->y + ctx->gamepad_height + touchpad_area.y; - area->w = touchpad_area.w; - area->h = touchpad_area.h; + i = SDL_clamp(touchpad, 0, MAX_TOUCHPADS - 1); + area->x = ctx->x + (ctx->gamepad_width - ctx->dual_touchpad_width) / 2 + dual_touchpad_area[i].x; + area->y = ctx->y + ctx->gamepad_height + dual_touchpad_area[i].y; + area->w = dual_touchpad_area[i].w; + area->h = dual_touchpad_area[i].h; } void SetGamepadImageShowingFront(GamepadImage *ctx, bool showing_front) @@ -666,6 +691,18 @@ void SetGamepadImageElement(GamepadImage *ctx, int element, bool active) ctx->elements[element] = active; } +static void FreeTouchpads(GamepadImage *ctx) +{ + if (ctx->touchpads) { + for (int i = 0; i < ctx->num_touchpads; ++i) { + SDL_free(ctx->touchpads[i].fingers); + } + SDL_free(ctx->touchpads); + ctx->touchpads = NULL; + ctx->num_touchpads = 0; + } +} + void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) { int i; @@ -726,31 +763,39 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) ctx->connection_state = SDL_GetGamepadConnectionState(gamepad); ctx->battery_state = SDL_GetGamepadPowerInfo(gamepad, &ctx->battery_percent); - if (SDL_GetNumGamepadTouchpads(gamepad) > 0) { - int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0); - if (num_fingers != ctx->num_fingers) { - GamepadTouchpadFinger *fingers = (GamepadTouchpadFinger *)SDL_realloc(ctx->fingers, num_fingers * sizeof(*fingers)); - if (fingers) { - ctx->fingers = fingers; - ctx->num_fingers = num_fingers; - } else { - num_fingers = SDL_min(ctx->num_fingers, num_fingers); + FreeTouchpads(ctx); + ctx->num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); + ctx->num_touchpads = SDL_min(ctx->num_touchpads, MAX_TOUCHPADS); + if (ctx->num_touchpads > 0) { + ctx->touchpads = (GamepadTouchpad *)SDL_malloc(sizeof(*ctx->touchpads) * ctx->num_touchpads); + if (ctx->touchpads) { + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + touchpad->num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); + touchpad->num_fingers = SDL_min(touchpad->num_fingers, MAX_FINGERS); + if (touchpad->num_fingers > 0) { + touchpad->fingers = (GamepadTouchpadFinger *)SDL_malloc(sizeof(*touchpad->fingers) * touchpad->num_fingers); + if (touchpad->fingers) { + for (int j = 0; j < touchpad->num_fingers; ++j) { + GamepadTouchpadFinger *finger = &touchpad->fingers[j]; + SDL_GetGamepadTouchpadFinger(gamepad, i, j, &finger->down, &finger->x, &finger->y, &finger->pressure); + } + } else { + touchpad->num_fingers = 0; + } + } } + if (ctx->num_touchpads == 1) { + SDL_memcpy(&ctx->touchpads[0].area, &touchpad_area, sizeof(SDL_FRect)); + } else { + SDL_memcpy(&ctx->touchpads[0].area, &dual_touchpad_area[0], sizeof(SDL_FRect)); + SDL_memcpy(&ctx->touchpads[1].area, &dual_touchpad_area[1], sizeof(SDL_FRect)); + } + } else { + ctx->num_touchpads = 0; } - for (i = 0; i < num_fingers; ++i) { - GamepadTouchpadFinger *finger = &ctx->fingers[i]; - - SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &finger->down, &finger->x, &finger->y, &finger->pressure); - } - ctx->showing_touchpad = true; - } else { - if (ctx->fingers) { - SDL_free(ctx->fingers); - ctx->fingers = NULL; - ctx->num_fingers = 0; - } - ctx->showing_touchpad = false; } + ctx->showing_touchpad = (ctx->num_touchpads > 0); } void RenderGamepadImage(GamepadImage *ctx) @@ -883,27 +928,39 @@ void RenderGamepadImage(GamepadImage *ctx) } if (ctx->display_mode == CONTROLLER_MODE_TESTING && ctx->showing_touchpad) { - dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; - dst.y = ctx->y + ctx->gamepad_height; - dst.w = ctx->touchpad_width; - dst.h = ctx->touchpad_height; - SDL_RenderTexture(ctx->renderer, ctx->touchpad_texture, NULL, &dst); + float initial_dst_x; + if (ctx->num_touchpads == 1) { + dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.w = ctx->touchpad_width; + dst.h = ctx->touchpad_height; + SDL_RenderTexture(ctx->renderer, ctx->touchpad_texture, NULL, &dst); + } else { + dst.x = ctx->x + (ctx->gamepad_width - ctx->dual_touchpad_width) / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.w = ctx->dual_touchpad_width; + dst.h = ctx->dual_touchpad_height; + SDL_RenderTexture(ctx->renderer, ctx->dual_touchpad_texture, NULL, &dst); + } + initial_dst_x = dst.x; - for (i = 0; i < ctx->num_fingers; ++i) { - GamepadTouchpadFinger *finger = &ctx->fingers[i]; - - if (finger->down) { - dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; - dst.x += touchpad_area.x + finger->x * touchpad_area.w; - dst.x -= ctx->button_width / 2; - dst.y = ctx->y + ctx->gamepad_height; - dst.y += touchpad_area.y + finger->y * touchpad_area.h; - dst.y -= ctx->button_height / 2; - dst.w = ctx->button_width; - dst.h = ctx->button_height; - SDL_SetTextureAlphaMod(ctx->button_texture, (Uint8)(finger->pressure * SDL_ALPHA_OPAQUE)); - SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); - SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE); + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + for (int j = 0; j < touchpad->num_fingers; ++j) { + GamepadTouchpadFinger *finger = &touchpad->fingers[j]; + if (finger->down) { + dst.x = initial_dst_x; + dst.x += touchpad->area.x + finger->x * touchpad->area.w; + dst.x -= ctx->button_width / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.y += touchpad->area.y + finger->y * touchpad->area.h; + dst.y -= ctx->button_height / 2; + dst.w = ctx->button_width; + dst.h = ctx->button_height; + SDL_SetTextureAlphaMod(ctx->button_texture, (Uint8)(finger->pressure * SDL_ALPHA_OPAQUE)); + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE); + } } } } @@ -924,9 +981,10 @@ void DestroyGamepadImage(GamepadImage *ctx) SDL_DestroyTexture(ctx->battery_texture[i]); } SDL_DestroyTexture(ctx->touchpad_texture); + SDL_DestroyTexture(ctx->dual_touchpad_texture); SDL_DestroyTexture(ctx->button_texture); SDL_DestroyTexture(ctx->axis_texture); - SDL_free(ctx->fingers); + FreeTouchpads(ctx); SDL_free(ctx); } } @@ -1615,37 +1673,40 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad) } if (ctx->display_mode == CONTROLLER_MODE_TESTING) { - if (SDL_GetNumGamepadTouchpads(gamepad) > 0) { - int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0); - for (i = 0; i < num_fingers; ++i) { - bool down; - float finger_x, finger_y, finger_pressure; + int num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); + if (num_touchpads > 0) { + for (i = 0; i < num_touchpads; ++i) { + int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); + for (int j = 0; j < num_fingers; ++j) { + bool down; + float finger_x, finger_y, finger_pressure; - if (!SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &down, &finger_x, &finger_y, &finger_pressure)) { - continue; + if (!SDL_GetGamepadTouchpadFinger(gamepad, i, j, &down, &finger_x, &finger_y, &finger_pressure)) { + continue; + } + + SDL_snprintf(text, sizeof(text), "Pad %d Finger %d:", i, j); + SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text); + + if (down) { + SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); + } else { + SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255); + } + + dst.x = x + center + 2.0f; + dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2; + dst.w = ctx->button_width; + dst.h = ctx->button_height; + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + + if (down) { + SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y); + SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text); + } + + y += ctx->button_height + 2.0f; } - - SDL_snprintf(text, sizeof(text), "Touch finger %d:", i); - SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text); - - if (down) { - SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); - } else { - SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255); - } - - dst.x = x + center + 2.0f; - dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2; - dst.w = ctx->button_width; - dst.h = ctx->button_height; - SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); - - if (down) { - SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y); - SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text); - } - - y += ctx->button_height + 2.0f; } } diff --git a/test/gamepadutils.h b/test/gamepadutils.h index d2ee1a7758..503238afe1 100644 --- a/test/gamepadutils.h +++ b/test/gamepadutils.h @@ -69,7 +69,7 @@ enum extern GamepadImage *CreateGamepadImage(SDL_Renderer *renderer); extern void SetGamepadImagePosition(GamepadImage *ctx, float x, float y); extern void GetGamepadImageArea(GamepadImage *ctx, SDL_FRect *area); -extern void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area); +extern void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area, int touchpad); extern void SetGamepadImageShowingFront(GamepadImage *ctx, bool showing_front); extern SDL_GamepadType GetGamepadImageType(GamepadImage *ctx); extern void SetGamepadImageDisplayMode(GamepadImage *ctx, ControllerDisplayMode display_mode); diff --git a/test/testcontroller.c b/test/testcontroller.c index a0fee1c811..d6276d97e7 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -33,7 +33,7 @@ #define PANEL_SPACING 25.0f #define PANEL_WIDTH 250.0f #define GAMEPAD_WIDTH 512.0f -#define GAMEPAD_HEIGHT 560.0f +#define GAMEPAD_HEIGHT 596.0f #define BUTTON_MARGIN 16.0f #define SCREEN_WIDTH (PANEL_WIDTH + PANEL_SPACING + GAMEPAD_WIDTH + PANEL_SPACING + PANEL_WIDTH) #define SCREEN_HEIGHT (TITLE_HEIGHT + GAMEPAD_HEIGHT) @@ -378,9 +378,16 @@ static SDL_GamepadAxis virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID; static float virtual_axis_start_x; static float virtual_axis_start_y; static SDL_GamepadButton virtual_button_active = SDL_GAMEPAD_BUTTON_INVALID; -static bool virtual_touchpad_active = false; -static float virtual_touchpad_x; -static float virtual_touchpad_y; + +typedef struct +{ + bool active; + float x; + float y; +} VirtualTouchpad; + +#define MAX_VIRTUAL_TOUCHPADS 2 +static VirtualTouchpad virtual_touchpad[MAX_VIRTUAL_TOUCHPADS]; static int s_arrBindingOrder[] = { /* Standard sequence */ @@ -1585,7 +1592,10 @@ static bool SDLCALL VirtualGamepadSetLED(void *userdata, Uint8 red, Uint8 green, static void OpenVirtualGamepad(void) { - SDL_VirtualJoystickTouchpadDesc virtual_touchpad = { 1, { 0, 0, 0 } }; + SDL_VirtualJoystickTouchpadDesc virtual_touchpad_desc[MAX_VIRTUAL_TOUCHPADS] = { + { 1, { 0, 0, 0 } }, + { 1, { 0, 0, 0 } } + }; SDL_VirtualJoystickSensorDesc virtual_sensors[] = { { SDL_SENSOR_ACCEL, 0.0f }, { SDL_SENSOR_GYRO, 0.0f } @@ -1601,8 +1611,8 @@ static void OpenVirtualGamepad(void) desc.type = SDL_JOYSTICK_TYPE_GAMEPAD; desc.naxes = SDL_GAMEPAD_AXIS_COUNT; desc.nbuttons = SDL_GAMEPAD_BUTTON_COUNT; - desc.ntouchpads = 1; - desc.touchpads = &virtual_touchpad; + desc.ntouchpads = MAX_VIRTUAL_TOUCHPADS; + desc.touchpads = virtual_touchpad_desc; desc.nsensors = SDL_arraysize(virtual_sensors); desc.sensors = virtual_sensors; desc.SetPlayerIndex = VirtualGamepadSetPlayerIndex; @@ -1681,12 +1691,14 @@ static void VirtualGamepadMouseMotion(float x, float y) } } - if (virtual_touchpad_active) { - SDL_FRect touchpad; - GetGamepadTouchpadArea(image, &touchpad); - virtual_touchpad_x = (x - touchpad.x) / touchpad.w; - virtual_touchpad_y = (y - touchpad.y) / touchpad.h; - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, true, virtual_touchpad_x, virtual_touchpad_y, 1.0f); + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + if (virtual_touchpad[i].active) { + SDL_FRect touchpad; + GetGamepadTouchpadArea(image, &touchpad, i); + virtual_touchpad[i].x = (x - touchpad.x) / touchpad.w; + virtual_touchpad[i].y = (y - touchpad.y) / touchpad.h; + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, true, virtual_touchpad[i].x, virtual_touchpad[i].y, 1.0f); + } } } @@ -1695,16 +1707,18 @@ static void VirtualGamepadMouseDown(float x, float y) int element = GetGamepadImageElementAt(image, x, y); if (element == SDL_GAMEPAD_ELEMENT_INVALID) { - SDL_FPoint point; - point.x = x; - point.y = y; - SDL_FRect touchpad; - GetGamepadTouchpadArea(image, &touchpad); - if (SDL_PointInRectFloat(&point, &touchpad)) { - virtual_touchpad_active = true; - virtual_touchpad_x = (x - touchpad.x) / touchpad.w; - virtual_touchpad_y = (y - touchpad.y) / touchpad.h; - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, true, virtual_touchpad_x, virtual_touchpad_y, 1.0f); + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + SDL_FPoint point; + point.x = x; + point.y = y; + SDL_FRect touchpad; + GetGamepadTouchpadArea(image, &touchpad, i); + if (SDL_PointInRectFloat(&point, &touchpad)) { + virtual_touchpad[i].active = true; + virtual_touchpad[i].x = (x - touchpad.x) / touchpad.w; + virtual_touchpad[i].y = (y - touchpad.y) / touchpad.h; + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, true, virtual_touchpad[i].x, virtual_touchpad[i].y, 1.0f); + } } return; } @@ -1756,9 +1770,11 @@ static void VirtualGamepadMouseUp(float x, float y) virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID; } - if (virtual_touchpad_active) { - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, false, virtual_touchpad_x, virtual_touchpad_y, 0.0f); - virtual_touchpad_active = false; + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + if (virtual_touchpad[i].active) { + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, false, virtual_touchpad[i].x, virtual_touchpad[i].y, 0.0f); + virtual_touchpad[i].active = false; + } } } diff --git a/test/testutils.c b/test/testutils.c index d828bb49a5..99f18831e9 100644 --- a/test/testutils.c +++ b/test/testutils.c @@ -39,6 +39,7 @@ static const struct { "gamepad_battery_unknown.png", "GP_BATTX.PNG" }, { "gamepad_battery_wired.png", "GP_BATTW.PNG" }, { "gamepad_touchpad.png", "GP_TOUCH.PNG" }, + { "gamepad_dual_touchpad.png", "GP_DUALT.PNG" }, { "gamepad_button.png", "GP_BTN.PNG" }, { "gamepad_button_small.png", "GP_BTNSM.PNG" }, { "gamepad_button_background.png", "GP_BTNBG.PNG" }, From a3376acc2e2fc940a909659f3d95fb199a548194 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Thu, 14 May 2026 14:50:21 +0100 Subject: [PATCH 282/407] Replace custom NEON cast macros with vreinterpret_*_* --- src/video/SDL_stretch.c | 48 +++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/video/SDL_stretch.c b/src/video/SDL_stretch.c index d432c0fbbd..073f62c09c 100644 --- a/src/video/SDL_stretch.c +++ b/src/video/SDL_stretch.c @@ -375,20 +375,6 @@ static bool scale_mat(const Uint32 *src, int src_w, int src_h, int src_pitch, Ui return true; } -#ifdef SDL_NEON_INTRINSICS -#define CAST_uint8x8_t (uint8x8_t) -#define CAST_uint32x2_t (uint32x2_t) -#endif - -#if defined(_MSC_VER) -#ifdef SDL_NEON_INTRINSICS -#undef CAST_uint8x8_t -#undef CAST_uint32x2_t -#define CAST_uint8x8_t -#define CAST_uint32x2_t -#endif -#endif - #ifdef SDL_SSE2_INTRINSICS #if 0 @@ -587,8 +573,8 @@ static SDL_INLINE void INTERPOL_BILINEAR_NEON(const Uint32 *s0, const Uint32 *s1 uint16x8_t d0; uint8x8_t e0; - x_00_01 = CAST_uint8x8_t vld1_u32(s0); // Load 2 pixels - x_10_11 = CAST_uint8x8_t vld1_u32(s1); + x_00_01 = vreinterpret_u8_u32(vld1_u32(s0)); // Load 2 pixels + x_10_11 = vreinterpret_u8_u32(vld1_u32(s1)); /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ @@ -608,7 +594,7 @@ static SDL_INLINE void INTERPOL_BILINEAR_NEON(const Uint32 *s0, const Uint32 *s1 e0 = vmovn_u16(d0); // Store 1 pixel - *dst = vget_lane_u32(CAST_uint32x2_t e0, 0); + *dst = vget_lane_u32(vreinterpret_u32_u8(e0), 0); } static bool scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) @@ -672,14 +658,14 @@ static bool scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitc s_16_17 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_3); // Interpolation vertical - x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01); // Load 2 pixels - x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); - x_04_05 = CAST_uint8x8_t vld1_u32(s_04_05); - x_06_07 = CAST_uint8x8_t vld1_u32(s_06_07); - x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); - x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); - x_14_15 = CAST_uint8x8_t vld1_u32(s_14_15); - x_16_17 = CAST_uint8x8_t vld1_u32(s_16_17); + x_00_01 = vreinterpret_u8_u32(vld1_u32(s_00_01)); // Load 2 pixels + x_02_03 = vreinterpret_u8_u32(vld1_u32(s_02_03)); + x_04_05 = vreinterpret_u8_u32(vld1_u32(s_04_05)); + x_06_07 = vreinterpret_u8_u32(vld1_u32(s_06_07)); + x_10_11 = vreinterpret_u8_u32(vld1_u32(s_10_11)); + x_12_13 = vreinterpret_u8_u32(vld1_u32(s_12_13)); + x_14_15 = vreinterpret_u8_u32(vld1_u32(s_14_15)); + x_16_17 = vreinterpret_u8_u32(vld1_u32(s_16_17)); /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ @@ -729,7 +715,7 @@ static bool scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitc // Narrow again e1 = vmovn_u16(d1); - f0 = vcombine_u32(CAST_uint32x2_t e0, CAST_uint32x2_t e1); + f0 = vcombine_u32(vreinterpret_u32_u8(e0), vreinterpret_u32_u8(e1)); // Store 4 pixels vst1q_u32(dst, f0); @@ -768,10 +754,10 @@ static bool scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitc s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); // Interpolation vertical - x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01); // Load 2 pixels - x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); - x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); - x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); + x_00_01 = vreinterpret_u8_u32(vld1_u32(s_00_01)); // Load 2 pixels + x_02_03 = vreinterpret_u8_u32(vld1_u32(s_02_03)); + x_10_11 = vreinterpret_u8_u32(vld1_u32(s_10_11)); + x_12_13 = vreinterpret_u8_u32(vld1_u32(s_12_13)); /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ @@ -801,7 +787,7 @@ static bool scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitc e0 = vmovn_u16(d0); // Store 2 pixels - vst1_u32(dst, CAST_uint32x2_t e0); + vst1_u32(dst, vreinterpret_u32_u8(e0)); dst += 2; } From 2fa7ba1e4fe54918be75a9a466b9ae51fbe14d60 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 14 May 2026 17:36:57 +0200 Subject: [PATCH 283/407] stdinc: _Countof is only available in C mode --- include/SDL3/SDL_stdinc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index 3e2266dc8f..893f2052f7 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -256,7 +256,7 @@ void *alloca(size_t); #define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) /* or `_Countof(array)` on recent gcc and clang */ #else -#if (defined(__GNUC__) && __GNUC__ >= 16) || SDL_HAS_EXTENSION(c_countof) +#if !defined(__cplusplus) && ((defined(__GNUC__) && __GNUC__ >= 16) || SDL_HAS_EXTENSION(c_countof)) #define SDL_arraysize(array) _Countof(array) #else #define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) From 0f2c04319f3192c215bef62c25adf7b41ea8f926 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 14 May 2026 17:37:14 +0200 Subject: [PATCH 284/407] cmake: gameinput.h is a c++-only header --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 851e11add9..cf87671216 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ include(CheckIncludeFiles) include(CheckLanguage) include(CheckSymbolExists) include(CheckCSourceCompiles) +include(CheckCXXSourceCompiles) include(CheckCSourceRuns) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) @@ -2314,7 +2315,7 @@ elseif(WINDOWS) static __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2; int main(int argc, char **argv) { return 0; }" HAVE_WINDOWS_GAMING_INPUT_H ) - check_c_source_compiles(" + check_cxx_source_compiles(" #include #define COBJMACROS #include From 8122b8f2ac68fde8306bb78c1fa758b46a91a39a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 14 May 2026 17:38:30 +0200 Subject: [PATCH 285/407] gameinput.h emits a few Wundef warnings (WINAPI_PARTITION_* macros) --- src/core/windows/SDL_gameinput.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index 0d7b6f85e7..d283831ff1 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -25,8 +25,17 @@ #ifdef HAVE_GAMEINPUT_H +#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" +#endif + #include +#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic pop +#endif + #ifndef GAMEINPUT_API_VERSION #define GAMEINPUT_API_VERSION 0 #endif From d57c3b685c434d2ee0fa3d258f7e165b6e8d0cf6 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 14 May 2026 17:40:13 +0200 Subject: [PATCH 286/407] gameinputjoystick: %02hhX emits a -Wformat warning --- src/joystick/gdk/SDL_gameinputjoystick.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index 5f41f2864f..f05c62c487 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -280,7 +280,7 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) // Generate a device path for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) { - SDL_snprintf(tmp, SDL_arraysize(tmp), "%02hhX", info->deviceId.value[idx]); + SDL_snprintf(tmp, SDL_arraysize(tmp), "%02X", info->deviceId.value[idx]); SDL_strlcat(elem->path, tmp, SDL_arraysize(elem->path)); } From 2c4e6ed3585ec63adee2e9a680de3c52b4db3c0c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 14 May 2026 10:18:58 -0700 Subject: [PATCH 287/407] Enable GameInput v3 by default if it's available GameInput is now the most functional Windows API for handling XInput controllers. --- src/core/windows/SDL_gameinput.cpp | 5 +++ src/core/windows/SDL_gameinput.h | 1 + src/joystick/gdk/SDL_gameinputjoystick.cpp | 30 ++++++++++++----- src/joystick/gdk/SDL_gameinputjoystick_c.h | 33 +++++++++++++++++++ src/joystick/windows/SDL_dinputjoystick.c | 4 ++- src/joystick/windows/SDL_rawinputjoystick.c | 4 ++- .../windows/SDL_windows_gaming_input.c | 4 ++- src/joystick/windows/SDL_xinputjoystick.c | 8 ++++- 8 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 src/joystick/gdk/SDL_gameinputjoystick_c.h diff --git a/src/core/windows/SDL_gameinput.cpp b/src/core/windows/SDL_gameinput.cpp index baf7ed2165..7139a4c36d 100644 --- a/src/core/windows/SDL_gameinput.cpp +++ b/src/core/windows/SDL_gameinput.cpp @@ -77,6 +77,11 @@ bool SDL_InitGameInput(IGameInput **ppGameInput) return true; } +bool SDL_GameInputReady(void) +{ + return (g_pGameInput != NULL); +} + void SDL_QuitGameInput(void) { SDL_assert(g_nGameInputRefCount > 0); diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index d283831ff1..cf8a978a57 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -49,6 +49,7 @@ using namespace GameInput::v1; #endif extern bool SDL_InitGameInput(IGameInput **ppGameInput); +extern bool SDL_GameInputReady(void); extern void SDL_QuitGameInput(void); #endif // HAVE_GAMEINPUT_H diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index f05c62c487..7456190615 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +#include "SDL_gameinputjoystick_c.h" + #ifdef SDL_JOYSTICK_GAMEINPUT #include "../SDL_sysjoystick.h" @@ -28,7 +30,7 @@ #include "../../core/windows/SDL_gameinput.h" // Default value for SDL_HINT_JOYSTICK_GAMEINPUT -#if defined(SDL_PLATFORM_GDK) +#if defined(SDL_PLATFORM_GDK) || (GAMEINPUT_API_VERSION >= 3) #define SDL_GAMEINPUT_DEFAULT true #else #define SDL_GAMEINPUT_DEFAULT false @@ -81,10 +83,6 @@ static IGameInput *g_pGameInput = NULL; static GameInputCallbackToken g_GameInputCallbackToken = 0; static Uint64 g_GameInputTimestampOffset; -extern "C" -{ - extern bool SDL_XINPUT_Enabled(void); -} static bool GAMEINPUT_InternalIsGamepad(const GameInputDeviceInfo *info) { @@ -242,9 +240,9 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) #endif if (!GAMEINPUT_InternalIsGamepad(info) && raw_type == SDL_GAMEINPUT_RAWTYPE_NONE) { -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) - if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_DIRECTINPUT, true) || SDL_XINPUT_Enabled()) { - // Let other backends handle non-gamepad controllers to possibly avoid bugs and/or regressions. +#if defined(SDL_JOYSTICK_DINPUT) + // Let other backends handle non-gamepad controllers to possibly avoid bugs and/or regressions. + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_DIRECTINPUT, true)) { return true; } #endif @@ -1055,6 +1053,15 @@ static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap return true; } +bool SDL_UsingGameInputForXInputControllers(void) +{ + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT) && + SDL_GameInputReady()) { + return true; + } + return false; +} + SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = { @@ -1082,4 +1089,11 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = }; +#else + +bool SDL_UsingGameInputForXInputControllers(void) +{ + return false; +} + #endif // SDL_JOYSTICK_GAMEINPUT diff --git a/src/joystick/gdk/SDL_gameinputjoystick_c.h b/src/joystick/gdk/SDL_gameinputjoystick_c.h new file mode 100644 index 0000000000..814166b63f --- /dev/null +++ b/src/joystick/gdk/SDL_gameinputjoystick_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +// Set up for C function definitions, even when using C++ +#ifdef __cplusplus +extern "C" { +#endif + +extern bool SDL_UsingGameInputForXInputControllers(void); + +// Ends C function definitions when using C++ +#ifdef __cplusplus +} +#endif diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 62ffbb46ec..e9c818aa00 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -29,6 +29,7 @@ #include "SDL_rawinputjoystick_c.h" #include "SDL_xinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" #ifndef DIDFT_OPTIONAL #define DIDFT_OPTIONAL 0x80000000 @@ -238,11 +239,12 @@ static bool SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char * #if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT) SDL_GamepadType type; - // XInput and RawInput backends will pick up XInput-compatible devices + // Some other backends will pick up XInput-compatible devices if (!SDL_XINPUT_Enabled() #ifdef SDL_JOYSTICK_RAWINPUT && !RAWINPUT_IsEnabled() #endif + && !SDL_UsingGameInputForXInputControllers() ) { return false; } diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 7a69775e26..92c9e026a5 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -38,6 +38,7 @@ #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_hid.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" /* SDL_JOYSTICK_RAWINPUT_XINPUT is disabled because using XInput at the same time as raw input will turn off the Xbox Series X controller when it is connected via the @@ -1022,7 +1023,8 @@ static bool RAWINPUT_JoystickInit(void) { SDL_assert(!SDL_RAWINPUT_inited); - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false) || + SDL_UsingGameInputForXInputControllers()) { return true; } diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 6b74873a9c..f8840ac230 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -24,6 +24,7 @@ #include "../SDL_sysjoystick.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" #include "../../core/windows/SDL_windows.h" @@ -586,7 +587,8 @@ static bool WGI_JoystickInit(void) { HRESULT hr; - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false) || + SDL_UsingGameInputForXInputControllers()) { return true; } diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index d7a132e1d1..377defb07d 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -28,6 +28,7 @@ #include "SDL_xinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" // Set up for C function definitions, even when using C++ #ifdef __cplusplus @@ -46,7 +47,12 @@ bool SDL_XINPUT_Enabled(void) bool SDL_XINPUT_JoystickInit(void) { - bool enabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, true); + bool enabled = true; + + if (!SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, true) || + SDL_UsingGameInputForXInputControllers()) { + enabled = false; + } if (enabled && !WIN_LoadXInputDLL()) { enabled = false; // oh well. From 11745aad07bfae129253974df0a94f5a77c842db Mon Sep 17 00:00:00 2001 From: Sylvain Becker Date: Thu, 14 May 2026 20:17:53 +0200 Subject: [PATCH 288/407] Fix build with SVE2 (#15586) --- include/SDL3/SDL_intrin.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h index e723b02c2d..5f90a9c9e6 100644 --- a/include/SDL3/SDL_intrin.h +++ b/include/SDL3/SDL_intrin.h @@ -288,7 +288,9 @@ _m_prefetch(void *__P) # define __ARM_FEATURE_SVE2 1 /* Set __ARM_FEATURE_SVE2 so that it can be used elsewhere, at compile time */ # define __ARM_ARCH 8 # endif -# elif !defined(SDL_PLATFORM_MACOS) /* Apple has no AArch64 device supporting SVE2 */ +# elif defined(SDL_PLATFORM_MACOS) +/* Apple has no AArch64 device supporting SVE2 */ +# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) # define SDL_SVE2_INTRINSICS 1 # include # endif From de08751537b91dc805ad535b876818f825ea6cbd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 14 May 2026 11:42:54 -0700 Subject: [PATCH 289/407] Fixed build for older toolchains that don't have arm_sve.h --- include/SDL3/SDL_intrin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h index 5f90a9c9e6..05ae794c59 100644 --- a/include/SDL3/SDL_intrin.h +++ b/include/SDL3/SDL_intrin.h @@ -290,7 +290,8 @@ _m_prefetch(void *__P) # endif # elif defined(SDL_PLATFORM_MACOS) /* Apple has no AArch64 device supporting SVE2 */ -# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) && \ + defined(__has_include) && __has_include() # define SDL_SVE2_INTRINSICS 1 # include # endif From 439ffd13eb63e79c94df395effe9909d253074de Mon Sep 17 00:00:00 2001 From: crudelios Date: Wed, 13 May 2026 17:50:42 +0100 Subject: [PATCH 290/407] Android: Add support for folder dialogs --- .../main/java/org/libsdl/app/SDLActivity.java | 111 ++++++++++++++---- include/SDL3/SDL_hints.h | 18 +++ src/core/android/SDL_android.c | 36 +++++- src/core/android/SDL_android.h | 6 +- src/dialog/android/SDL_androiddialog.c | 19 +-- 5 files changed, 138 insertions(+), 52 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 9df90cd446..151224daad 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -26,6 +26,7 @@ import android.os.Handler; import android.os.LocaleList; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.provider.DocumentsContract; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; @@ -744,6 +745,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } } + // File dialog types + private static final int SDL_FILEDIALOG_OPENFILE = 0; + private static final int SDL_FILEDIALOG_SAVEFILE = 1; + private static final int SDL_FILEDIALOG_OPENFOLDER = 2; + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -752,7 +758,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh /* This is our file dialog */ String[] filelist = null; - if (data != null) { + if (data != null && resultCode == Activity.RESULT_OK) { Uri singleFileUri = data.getData(); if (singleFileUri == null) { @@ -767,6 +773,13 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh filelist[i] = uri; } } else { + /* If the user selected a directory and the persistent permission hint has been set, + make the permission persistable */ + if (mFileDialogState.type == SDL_FILEDIALOG_OPENFOLDER && mFileDialogState.persistable) { + mSingleton.getContentResolver().takePersistableUriPermission(singleFileUri, + Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } /* Only one file is selected. */ filelist = new String[]{singleFileUri.toString()}; } @@ -2099,19 +2112,16 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh /** * This method is called by SDL using JNI. */ - public static boolean showFileDialog(String[] filters, boolean allowMultiple, boolean forWrite, int requestCode) { + public static boolean showFileDialog(String[] filters, boolean allowMultiple, + int type, String initialPath, int requestCode) { if (mSingleton == null) { return false; } - if (forWrite) { - allowMultiple = false; - } - - /* Convert string list of extensions to their respective MIME types */ + /* Convert string list of extensions to their respective MIME types (not needed for folder selection) */ ArrayList mimes = new ArrayList<>(); MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); - if (filters != null) { + if (filters != null && type != SDL_FILEDIALOG_OPENFOLDER) { for (String pattern : filters) { String[] extensions = pattern.split(";"); @@ -2129,40 +2139,89 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } } - /* Display the file dialog */ - Intent intent = new Intent(forWrite ? Intent.ACTION_CREATE_DOCUMENT : Intent.ACTION_OPEN_DOCUMENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); - switch (mimes.size()) { - case 0: - intent.setType("*/*"); - break; - case 1: - intent.setType(mimes.get(0)); - break; - default: - intent.setType("*/*"); - intent.putExtra(Intent.EXTRA_MIME_TYPES, mimes.toArray(new String[]{})); + /* Handle the initial path, if set */ + Uri initialPathUri = null; + + if (initialPath != null && !initialPath.isEmpty()) { + try { + initialPathUri = Uri.parse(initialPath); + } catch (Exception e) { + Log.e(TAG, "Failed to parse initial path URI, ignoring initial path", e); + } } + boolean persistable = SDLActivity.nativeGetHintBoolean("SDL_ANDROID_ALLOW_PERSISTENT_FOLDER_ACCESS", false); + + /* Select the intent based on the type */ + String action; + switch (type) { + case SDL_FILEDIALOG_OPENFILE: + action = Intent.ACTION_OPEN_DOCUMENT; + break; + case SDL_FILEDIALOG_SAVEFILE: + action = Intent.ACTION_CREATE_DOCUMENT; + allowMultiple = false; + break; + case SDL_FILEDIALOG_OPENFOLDER: + action = Intent.ACTION_OPEN_DOCUMENT_TREE; + break; + default: + Log.e(TAG, "Unsupported file dialog type: " + type); + return false; + } + + /* Prepare the intent with the proper values */ + Intent intent = new Intent(action); + if (type != SDL_FILEDIALOG_OPENFOLDER) { + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); + switch (mimes.size()) { + case 0: + intent.setType("*/*"); + break; + case 1: + intent.setType(mimes.get(0)); + break; + default: + intent.setType("*/*"); + intent.putExtra(Intent.EXTRA_MIME_TYPES, mimes.toArray(new String[]{})); + } + } else { + int intent_flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION; + if (persistable) { + intent_flags |= Intent.FLAG_GRANT_PREFIX_URI_PERMISSION | + Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; + } + intent.addFlags(intent_flags); + } + + if (initialPathUri != null) { + intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialPathUri); + } + + /* Display the file/folder dialog */ try { mSingleton.startActivityForResult(intent, requestCode); } catch (ActivityNotFoundException e) { - Log.e(TAG, "Unable to open file dialog.", e); + Log.e(TAG, "Unable to open dialog.", e); return false; } /* Save current dialog state */ mFileDialogState = new SDLFileDialogState(); mFileDialogState.requestCode = requestCode; - mFileDialogState.multipleChoice = allowMultiple; + mFileDialogState.type = type; + mFileDialogState.persistable = persistable; + return true; } - /* Internal class used to track active open file dialog */ + /* Internal class used to track active file dialog */ static class SDLFileDialogState { int requestCode; - boolean multipleChoice; + int type; + boolean persistable; } /** diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 2e1991d4b4..d37c1405d4 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -140,6 +140,24 @@ extern "C" { */ #define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" +/** + * A variable to control whether we allow persistent folder access on Android when using the SDL select folder dialog. + * + * If set to `1`, the selected folder will be accessible persistently across app launches. + * That allows the user to only have to select the directory once, and then the app can access it again in the future + * without needing to ask the user to select it again. + * + * The variable can be set to the following values: + * + * - "0": Persistent folder access is not allowed. (default) + * - "1": Persistent folder access is allowed. + * + * This hint should be set before the SDL folder selection dialog is shown, and can be changed between dialog invocations. + * + * \since This hint is available since SDL 3.6.0. + */ +#define SDL_HINT_ANDROID_ALLOW_PERSISTENT_FOLDER_ACCESS "SDL_ANDROID_ALLOW_PERSISTENT_FOLDER_ACCESS" + /** * A variable setting the app ID string. * diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 27289bbba0..ef095fa0f8 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -688,7 +688,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIIII)Z"); midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z"); midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I"); - midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z"); + midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZILjava/lang/String;I)Z"); midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;"); if (!midClipboardGetText || @@ -3386,18 +3386,34 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeFileDialog)( } } -bool Android_JNI_OpenFileDialog( +bool Android_JNI_ShowFileDialog( SDL_DialogFileCallback callback, void *userdata, - const SDL_DialogFileFilter *filters, int nfilters, bool forwrite, - bool multiple) + const SDL_DialogFileFilter *filters, int nfilters, SDL_FileDialogType type, + bool multiple, const char *initialPath) { if (mAndroidFileDialogData.callback != NULL) { SDL_SetError("Only one file dialog can be run at a time."); return false; } - if (forwrite) { + // Setup type + int dialogType = 0; + + switch (type) { + case SDL_FILEDIALOG_OPENFILE: + dialogType = 0; + break; + case SDL_FILEDIALOG_SAVEFILE: multiple = false; + dialogType = 1; + break; + case SDL_FILEDIALOG_OPENFOLDER: + multiple = false; + dialogType = 2; + break; + default: + SDL_SetError("Invalid file dialog type"); + return false; } JNIEnv *env = Android_JNI_GetEnv(); @@ -3417,6 +3433,12 @@ bool Android_JNI_OpenFileDialog( } } + // Setup initial path + jstring initialPathString = NULL; + if (initialPath && *initialPath) { + initialPathString = (*env)->NewStringUTF(env, initialPath); + } + // Setup data static SDL_AtomicInt next_request_code; mAndroidFileDialogData.request_code = SDL_AddAtomicInt(&next_request_code, 1); @@ -3425,8 +3447,10 @@ bool Android_JNI_OpenFileDialog( // Invoke JNI jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, - midShowFileDialog, filtersArray, (jboolean) multiple, (jboolean) forwrite, mAndroidFileDialogData.request_code); + midShowFileDialog, filtersArray, (jboolean) multiple, + dialogType, initialPathString, mAndroidFileDialogData.request_code); (*env)->DeleteLocalRef(env, filtersArray); + (*env)->DeleteLocalRef(env, initialPathString); if (!success) { mAndroidFileDialogData.callback = NULL; SDL_AddAtomicInt(&next_request_code, -1); diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index fa646e763d..ec9d1dc863 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -154,9 +154,9 @@ bool SDL_IsAndroidTablet(void); bool SDL_IsAndroidTV(void); // File Dialogs -bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void *userdata, - const SDL_DialogFileFilter *filters, int nfilters, bool forwrite, - bool multiple); +bool Android_JNI_ShowFileDialog(SDL_DialogFileCallback callback, void *userdata, + const SDL_DialogFileFilter *filters, int nfilters, SDL_FileDialogType type, + bool multiple, const char *initialPath); // Ends C function definitions when using C++ #ifdef __cplusplus diff --git a/src/dialog/android/SDL_androiddialog.c b/src/dialog/android/SDL_androiddialog.c index 49b42420e1..2618855c09 100644 --- a/src/dialog/android/SDL_androiddialog.c +++ b/src/dialog/android/SDL_androiddialog.c @@ -28,7 +28,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil SDL_DialogFileFilter *filters = SDL_GetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, NULL); int nfilters = (int) SDL_GetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, 0); bool allow_many = SDL_GetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, false); - bool is_save; + const char *base_folder = SDL_GetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, NULL); if (SDL_GetHint(SDL_HINT_FILE_DIALOG_DRIVER) != NULL) { SDL_SetError("File dialog driver unsupported (don't set SDL_HINT_FILE_DIALOG_DRIVER)"); @@ -36,22 +36,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil return; } - switch (type) { - case SDL_FILEDIALOG_OPENFILE: - is_save = false; - break; - - case SDL_FILEDIALOG_SAVEFILE: - is_save = true; - break; - - case SDL_FILEDIALOG_OPENFOLDER: - SDL_Unsupported(); - callback(userdata, NULL, -1); - return; - } - - if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, is_save, allow_many)) { + if (!Android_JNI_ShowFileDialog(callback, userdata, filters, nfilters, type, allow_many, base_folder)) { // SDL_SetError is already called when it fails callback(userdata, NULL, -1); } From 9e07e0c21535859d85133c62064d97582d021a6d Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Thu, 14 May 2026 18:52:22 +0000 Subject: [PATCH 291/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_hints.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index d37c1405d4..225b0cc1b1 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -141,18 +141,21 @@ extern "C" { #define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" /** - * A variable to control whether we allow persistent folder access on Android when using the SDL select folder dialog. + * A variable to control whether we allow persistent folder access on Android + * when using the SDL select folder dialog. * - * If set to `1`, the selected folder will be accessible persistently across app launches. - * That allows the user to only have to select the directory once, and then the app can access it again in the future - * without needing to ask the user to select it again. + * If set to `1`, the selected folder will be accessible persistently across + * app launches. That allows the user to only have to select the directory + * once, and then the app can access it again in the future without needing to + * ask the user to select it again. * * The variable can be set to the following values: * * - "0": Persistent folder access is not allowed. (default) * - "1": Persistent folder access is allowed. * - * This hint should be set before the SDL folder selection dialog is shown, and can be changed between dialog invocations. + * This hint should be set before the SDL folder selection dialog is shown, + * and can be changed between dialog invocations. * * \since This hint is available since SDL 3.6.0. */ From fdfbbcefb2470d39726748d17696c577d37586a5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 14 May 2026 12:00:55 -0700 Subject: [PATCH 292/407] Fixed error: "SVE support not enabled" building on Android --- include/SDL3/SDL_intrin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h index 05ae794c59..289a356b7c 100644 --- a/include/SDL3/SDL_intrin.h +++ b/include/SDL3/SDL_intrin.h @@ -288,10 +288,10 @@ _m_prefetch(void *__P) # define __ARM_FEATURE_SVE2 1 /* Set __ARM_FEATURE_SVE2 so that it can be used elsewhere, at compile time */ # define __ARM_ARCH 8 # endif -# elif defined(SDL_PLATFORM_MACOS) +# elif defined(SDL_PLATFORM_APPLE) /* Apple has no AArch64 device supporting SVE2 */ # elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) && \ - defined(__has_include) && __has_include() + defined(__has_include) && __has_include() && defined(__ARM_FEATURE_SVE) # define SDL_SVE2_INTRINSICS 1 # include # endif From 0e07b7c5e20952c3ea6b8b490f81bc2ebc21a6fd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 14 May 2026 15:58:15 -0400 Subject: [PATCH 293/407] android: Comment out debug logging. Reference Issue #15587. --- src/core/android/SDL_android.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index ef095fa0f8..ad07f07ad1 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2262,7 +2262,7 @@ ioerr: static bool CreateAPKNodes(const char *path) { - SDL_Log("ANDROID: Parsing APK file '%s' ...", path); + //SDL_Log("ANDROID: Parsing APK file '%s' ...", path); SDL_IOStream *io = SDL_IOFromFile(path, "rb"); if (!io) { From 4d95a63fe3936389119794cf6dce1483465d3d5b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 14 May 2026 21:55:55 +0300 Subject: [PATCH 294/407] fix build after commit 2c4e6ed3585ec63adee2e9a680de3c52b4db3c0c: move SDL_UsingGameInputForXInputControllers() to core/windows/SDL_gameinput.cpp because joystick/gdk/SDL_gameinputjoystick.cpp isn't always added to build. --- src/core/windows/SDL_gameinput.cpp | 20 +++++++++-- src/core/windows/SDL_gameinput.h | 17 ++++++++++ src/joystick/gdk/SDL_gameinputjoystick.cpp | 26 --------------- src/joystick/gdk/SDL_gameinputjoystick_c.h | 33 ------------------- src/joystick/windows/SDL_dinputjoystick.c | 2 +- src/joystick/windows/SDL_rawinputjoystick.c | 2 +- .../windows/SDL_windows_gaming_input.c | 2 +- src/joystick/windows/SDL_xinputjoystick.c | 7 ++-- 8 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 src/joystick/gdk/SDL_gameinputjoystick_c.h diff --git a/src/core/windows/SDL_gameinput.cpp b/src/core/windows/SDL_gameinput.cpp index 7139a4c36d..f9996916a5 100644 --- a/src/core/windows/SDL_gameinput.cpp +++ b/src/core/windows/SDL_gameinput.cpp @@ -20,11 +20,11 @@ */ #include "SDL_internal.h" -#ifdef HAVE_GAMEINPUT_H - #include "SDL_windows.h" #include "SDL_gameinput.h" +#ifdef HAVE_GAMEINPUT_H + static SDL_SharedObject *g_hGameInputDLL; static IGameInput *g_pGameInput; static int g_nGameInputRefCount; @@ -99,4 +99,20 @@ void SDL_QuitGameInput(void) } } +bool SDL_UsingGameInputForXInputControllers(void) +{ + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT) && + SDL_GameInputReady()) { + return true; + } + return false; +} + +#else + +bool SDL_UsingGameInputForXInputControllers(void) +{ + return false; +} + #endif // HAVE_GAMEINPUT_H diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index cf8a978a57..6969ad0dd2 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -48,10 +48,27 @@ using namespace GameInput::v2; using namespace GameInput::v1; #endif +// Default value for SDL_HINT_JOYSTICK_GAMEINPUT +#if defined(SDL_PLATFORM_GDK) || (GAMEINPUT_API_VERSION >= 3) +#define SDL_GAMEINPUT_DEFAULT true +#else +#define SDL_GAMEINPUT_DEFAULT false +#endif + extern bool SDL_InitGameInput(IGameInput **ppGameInput); extern bool SDL_GameInputReady(void); extern void SDL_QuitGameInput(void); #endif // HAVE_GAMEINPUT_H +#ifdef __cplusplus +extern "C" { +#endif + +extern bool SDL_UsingGameInputForXInputControllers(void); + +#ifdef __cplusplus +} +#endif + #endif // SDL_gameinput_h_ diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index 7456190615..0c04592ac5 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -20,8 +20,6 @@ */ #include "SDL_internal.h" -#include "SDL_gameinputjoystick_c.h" - #ifdef SDL_JOYSTICK_GAMEINPUT #include "../SDL_sysjoystick.h" @@ -29,13 +27,6 @@ #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_gameinput.h" -// Default value for SDL_HINT_JOYSTICK_GAMEINPUT -#if defined(SDL_PLATFORM_GDK) || (GAMEINPUT_API_VERSION >= 3) -#define SDL_GAMEINPUT_DEFAULT true -#else -#define SDL_GAMEINPUT_DEFAULT false -#endif - enum { SDL_GAMEPAD_BUTTON_GAMEINPUT_SHARE = 11 @@ -1053,15 +1044,6 @@ static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap return true; } -bool SDL_UsingGameInputForXInputControllers(void) -{ - if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT) && - SDL_GameInputReady()) { - return true; - } - return false; -} - SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = { @@ -1088,12 +1070,4 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = GAMEINPUT_JoystickGetGamepadMapping }; - -#else - -bool SDL_UsingGameInputForXInputControllers(void) -{ - return false; -} - #endif // SDL_JOYSTICK_GAMEINPUT diff --git a/src/joystick/gdk/SDL_gameinputjoystick_c.h b/src/joystick/gdk/SDL_gameinputjoystick_c.h deleted file mode 100644 index 814166b63f..0000000000 --- a/src/joystick/gdk/SDL_gameinputjoystick_c.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2026 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "SDL_internal.h" - -// Set up for C function definitions, even when using C++ -#ifdef __cplusplus -extern "C" { -#endif - -extern bool SDL_UsingGameInputForXInputControllers(void); - -// Ends C function definitions when using C++ -#ifdef __cplusplus -} -#endif diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index e9c818aa00..b720288ef3 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -28,8 +28,8 @@ #include "SDL_dinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" #include "SDL_xinputjoystick_c.h" +#include "../../core/windows/SDL_gameinput.h" #include "../hidapi/SDL_hidapijoystick_c.h" -#include "../gdk/SDL_gameinputjoystick_c.h" #ifndef DIDFT_OPTIONAL #define DIDFT_OPTIONAL 0x80000000 diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 92c9e026a5..da557c5e86 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -37,8 +37,8 @@ #include "../SDL_sysjoystick.h" #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_hid.h" +#include "../../core/windows/SDL_gameinput.h" #include "../hidapi/SDL_hidapijoystick_c.h" -#include "../gdk/SDL_gameinputjoystick_c.h" /* SDL_JOYSTICK_RAWINPUT_XINPUT is disabled because using XInput at the same time as raw input will turn off the Xbox Series X controller when it is connected via the diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index f8840ac230..e08f568d91 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -24,7 +24,7 @@ #include "../SDL_sysjoystick.h" #include "../hidapi/SDL_hidapijoystick_c.h" -#include "../gdk/SDL_gameinputjoystick_c.h" +#include "../../core/windows/SDL_gameinput.h" #include "SDL_rawinputjoystick_c.h" #include "../../core/windows/SDL_windows.h" diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 377defb07d..32876fbfad 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -27,17 +27,16 @@ #include "SDL_windowsjoystick_c.h" #include "SDL_xinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" +#include "../../core/windows/SDL_gameinput.h" #include "../hidapi/SDL_hidapijoystick_c.h" -#include "../gdk/SDL_gameinputjoystick_c.h" // Set up for C function definitions, even when using C++ #ifdef __cplusplus extern "C" { #endif -/* - * Internal stuff. - */ +// Internal stuff + static bool s_bXInputEnabled = false; bool SDL_XINPUT_Enabled(void) From f3faf67c645023ecb26485781dd26e0948030800 Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Thu, 14 May 2026 16:26:26 -0700 Subject: [PATCH 295/407] Add Steam Controller touchpads, capacitive touch for sticks, and grip sense (#15528) --- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 79 +++++++++++++------ .../hidapi/steam/controller_structs.h | 8 +- 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index 9d2b026eec..f1c5881229 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -40,11 +40,17 @@ enum { - SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM = 11, - SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, - SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, - SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, - SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, + SDL_GAMEPAD_BUTTON_TRITON_QAM = 11, + SDL_GAMEPAD_BUTTON_TRITON_RIGHT_PADDLE1, + SDL_GAMEPAD_BUTTON_TRITON_LEFT_PADDLE1, + SDL_GAMEPAD_BUTTON_TRITON_RIGHT_PADDLE2, + SDL_GAMEPAD_BUTTON_TRITON_LEFT_PADDLE2, + SDL_GAMEPAD_BUTTON_TRITON_RIGHT_TOUCHPAD, + SDL_GAMEPAD_BUTTON_TRITON_LEFT_TOUCHPAD, + SDL_GAMEPAD_BUTTON_TRITON_RIGHT_JOYSTICK_TOUCH, + SDL_GAMEPAD_BUTTON_TRITON_LEFT_JOYSTICK_TOUCH, + SDL_GAMEPAD_BUTTON_TRITON_RIGHT_GRIP_TOUCH, + SDL_GAMEPAD_BUTTON_TRITON_LEFT_GRIP_TOUCH, SDL_GAMEPAD_NUM_TRITON_BUTTONS, }; @@ -76,19 +82,18 @@ typedef enum TRITON_LBUTTON_L5 = 0x00040000, TRITON_LBUTTON_L = 0x00080000, - /* - STEAM_RIGHTSTICK_FINGERDOWN_MASK, // Right Stick Touch 0x00100000 - STEAM_RIGHTPAD_FINGERDOWN_MASK, // Right Pad Touch 0x00200000 - STEAM_BUTTON_RIGHTPAD_CLICKED_MASK, // Right Pressure Click 0x00400000 - STEAM_RIGHT_TRIGGER_MASK, // Right Trigger Click 0x00800000 + TRITON_RIGHT_JOYSTICK_TOUCH = 0x00100000, + TRITON_RIGHT_TOUCHPAD_TOUCH = 0x00200000, + TRITON_RIGHT_TOUCHPAD_CLICK = 0x00400000, + TRITON_RIGHT_TRIGGER_CLICK = 0x00800000, - STEAM_LEFTSTICK_FINGERDOWN_MASK, // Left Stick Touch 0x01000000 - STEAM_LEFTPAD_FINGERDOWN_MASK, // Left Pad Touch 0x02000000 - STEAM_BUTTON_LEFTPAD_CLICKED_MASK, // Left Pressure Click 0x04000000 - STEAM_LEFT_TRIGGER_MASK, // Left Trigger Click 0x08000000 - STEAM_RIGHT_AUX_MASK, // Right Pinky Touch 0x10000000 - STEAM_LEFT_AUX_MASK, // Left Pinky Touch 0x20000000 - */ + TRITON_LEFT_JOYSTICK_TOUCH = 0x01000000, + TRITON_LEFT_TOUCHPAD_TOUCH = 0x02000000, + TRITON_LEFT_TOUCHPAD_CLICK = 0x04000000, + TRITON_LEFT_TRIGGER_CLICK = 0x08000000, + + TRITON_RIGHT_GRIP_TOUCH = 0x10000000, + TRITON_LEFT_GRIP_TOUCH = 0x20000000, } TritonButtons; typedef struct @@ -160,7 +165,7 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, ((pTritonReport->buttons & TRITON_LBUTTON_VIEW) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((pTritonReport->buttons & TRITON_LBUTTON_STEAM) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM, + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_QAM, ((pTritonReport->buttons & TRITON_HBUTTON_QAM) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, @@ -168,15 +173,30 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((pTritonReport->buttons & TRITON_LBUTTON_R3) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_PADDLE1, ((pTritonReport->buttons & TRITON_HBUTTON_R4) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_PADDLE1, ((pTritonReport->buttons & TRITON_HBUTTON_L4) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_PADDLE2, ((pTritonReport->buttons & TRITON_LBUTTON_R5) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_PADDLE2, ((pTritonReport->buttons & TRITON_LBUTTON_L5) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_TOUCHPAD, + ((pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_CLICK) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_TOUCHPAD, + ((pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_CLICK) != 0)); + + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_JOYSTICK_TOUCH, + ((pTritonReport->buttons & TRITON_RIGHT_JOYSTICK_TOUCH) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_JOYSTICK_TOUCH, + ((pTritonReport->buttons & TRITON_LEFT_JOYSTICK_TOUCH) != 0)); + + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_GRIP_TOUCH, + ((pTritonReport->buttons & TRITON_RIGHT_GRIP_TOUCH) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_GRIP_TOUCH, + ((pTritonReport->buttons & TRITON_LEFT_GRIP_TOUCH) != 0)); + if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_UP) { hat |= SDL_HAT_UP; } @@ -226,6 +246,18 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, ctx->last_sensor_tick = pTritonReport->imu.timestamp; } + + SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, + pTritonReport->sPressureLeft > 0, + pTritonReport->sLeftPadX / 65536.0f + 0.5f, + -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f, + pTritonReport->sPressureLeft / 32768.0f); + + SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, + pTritonReport->sPressureRight > 0, + pTritonReport->sRightPadX / 65536.0f + 0.5f, + -(float)pTritonReport->sRightPadY / 65536.0f + 0.5f, + pTritonReport->sPressureRight / 32768.0f); } static void HIDAPI_DriverSteamTriton_HandleBatteryStatus(SDL_HIDAPI_Device *device, @@ -445,6 +477,9 @@ static bool HIDAPI_DriverSteamTriton_OpenJoystick(SDL_HIDAPI_Device *device, SDL SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); + SDL_PrivateJoystickAddTouchpad(joystick, 1); + SDL_PrivateJoystickAddTouchpad(joystick, 1); + return true; } diff --git a/src/joystick/hidapi/steam/controller_structs.h b/src/joystick/hidapi/steam/controller_structs.h index e3a979427f..365bc73f9b 100644 --- a/src/joystick/hidapi/steam/controller_structs.h +++ b/src/joystick/hidapi/steam/controller_structs.h @@ -607,11 +607,11 @@ typedef struct short sLeftPadX; short sLeftPadY; - unsigned short ucPressureLeft; + unsigned short sPressureLeft; short sRightPadX; short sRightPadY; - unsigned short ucPressureRight; + unsigned short sPressureRight; TritonMTUIMU_t imu; } TritonMTUFull_t; @@ -628,11 +628,11 @@ typedef struct { short sLeftPadX; short sLeftPadY; - unsigned short ucPressureLeft; + unsigned short sPressureLeft; short sRightPadX; short sRightPadY; - unsigned short ucPressureRight; + unsigned short sPressureRight; TritonMTUIMUNoQuat_t imu; } TritonMTUNoQuat_t; From c9bb41bd9ca6fc2ebd1c8be150e41c52ab50e3c7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 14 May 2026 16:52:40 -0700 Subject: [PATCH 296/407] Fixed build when GameInput is enabled --- src/core/windows/SDL_gameinput.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index 6969ad0dd2..ea16b85dce 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -23,7 +23,7 @@ #ifndef SDL_gameinput_h_ #define SDL_gameinput_h_ -#ifdef HAVE_GAMEINPUT_H +#if defined(HAVE_GAMEINPUT_H) && defined(__cplusplus) #ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA #pragma GCC diagnostic push @@ -59,14 +59,16 @@ extern bool SDL_InitGameInput(IGameInput **ppGameInput); extern bool SDL_GameInputReady(void); extern void SDL_QuitGameInput(void); -#endif // HAVE_GAMEINPUT_H +#endif // HAVE_GAMEINPUT_H && __cplusplus +/* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus extern "C" { #endif extern bool SDL_UsingGameInputForXInputControllers(void); +/* Ends C function definitions when using C++ */ #ifdef __cplusplus } #endif From f286e420afd3ccb0dedc7ec77eb09d4bd2e5e102 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Thu, 14 May 2026 17:01:13 -0700 Subject: [PATCH 297/407] GPU: Refactor Vulkan barriers to fix defrag segfault (#15593) --- src/gpu/vulkan/SDL_gpu_vulkan.c | 159 +++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 53 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 56074c96ad..b7983859d8 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -641,6 +641,11 @@ struct VulkanTexture VkImageAspectFlags aspectFlags; Uint32 depth; // used for cleanup only + // used to avoid indirection on barriers + Uint32 levelCount; + Uint32 layerCount; + SDL_GPUTextureType type; + // FIXME: It'd be nice if we didn't have to have this on the texture... SDL_GPUTextureUsageFlags usage; // used for defrag transitions only. @@ -2723,12 +2728,16 @@ static void VULKAN_INTERNAL_BufferMemoryBarrier( buffer->transitioned = true; } -static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( +static void VULKAN_INTERNAL_TextureMemoryBarrier( VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer, VulkanTextureUsageMode sourceUsageMode, VulkanTextureUsageMode destinationUsageMode, - VulkanTextureSubresource *textureSubresource) + Uint32 baseLevel, + Uint32 levelCount, + Uint32 baseLayer, + Uint32 layerCount, + VulkanTexture *texture) { VkPipelineStageFlags srcStages = 0; VkPipelineStageFlags dstStages = 0; @@ -2742,21 +2751,12 @@ static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( memoryBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - memoryBarrier.image = textureSubresource->parent->image; - memoryBarrier.subresourceRange.aspectMask = textureSubresource->parent->aspectFlags; - memoryBarrier.subresourceRange.baseMipLevel = textureSubresource->level; - memoryBarrier.subresourceRange.levelCount = 1; - memoryBarrier.subresourceRange.baseArrayLayer = textureSubresource->layer; - memoryBarrier.subresourceRange.layerCount = 1; - - // VK_KHR_maintenance9 adds the ability to independently transition arbitrary subsets of slices in a 3D texture - // but otherwise it is not necessarily supported by the driver. - // As a workaround we have to transition the whole texture instead of just the subresource. - // If VK_KHR_maintenance9 becomes widely supported, this can be removed. - // See https://docs.vulkan.org/features/latest/features/proposals/VK_KHR_maintenance9.html#_barriers_with_2d_array_compatible_3d_images - if (textureSubresource->parent->container->header.info.type == SDL_GPU_TEXTURETYPE_3D) { - memoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; - } + memoryBarrier.image = texture->image; + memoryBarrier.subresourceRange.aspectMask = texture->aspectFlags; + memoryBarrier.subresourceRange.baseMipLevel = baseLevel; + memoryBarrier.subresourceRange.levelCount = levelCount; + memoryBarrier.subresourceRange.baseArrayLayer = baseLayer; + memoryBarrier.subresourceRange.layerCount = layerCount; if (sourceUsageMode == VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED) { srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; @@ -2853,6 +2853,56 @@ static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( &memoryBarrier); } +// Transitions the entire texture with a single barrier call. +static void VULKAN_INTERNAL_FullTextureMemoryBarrier( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanTextureUsageMode sourceUsageMode, + VulkanTextureUsageMode destinationUsageMode, + VulkanTexture *texture) +{ + VULKAN_INTERNAL_TextureMemoryBarrier( + renderer, + commandBuffer, + sourceUsageMode, + destinationUsageMode, + 0, + texture->levelCount, + 0, + texture->layerCount, + texture); +} + +static void VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanTextureUsageMode sourceUsageMode, + VulkanTextureUsageMode destinationUsageMode, + VulkanTextureSubresource *textureSubresource) +{ + Uint32 layerCount = 1; + + // VK_KHR_maintenance9 adds the ability to independently transition arbitrary subsets of slices in a 3D texture + // but otherwise it is not necessarily supported by the driver. + // As a workaround we have to transition the whole texture instead of just the subresource. + // If VK_KHR_maintenance9 becomes widely supported, this can be removed. + // See https://docs.vulkan.org/features/latest/features/proposals/VK_KHR_maintenance9.html#_barriers_with_2d_array_compatible_3d_images + if (textureSubresource->parent->type == SDL_GPU_TEXTURETYPE_3D) { + layerCount = VK_REMAINING_ARRAY_LAYERS; + } + + VULKAN_INTERNAL_TextureMemoryBarrier( + renderer, + commandBuffer, + sourceUsageMode, + destinationUsageMode, + textureSubresource->level, + 1, + textureSubresource->layer, + layerCount, + textureSubresource->parent); +} + static VulkanBufferUsageMode VULKAN_INTERNAL_DefaultBufferUsageMode( VulkanBuffer *buffer) { @@ -2950,13 +3000,12 @@ static void VULKAN_INTERNAL_TextureTransitionFromDefaultUsage( VulkanTextureUsageMode destinationUsageMode, VulkanTexture *texture) { - for (Uint32 i = 0; i < texture->subresourceCount; i += 1) { - VULKAN_INTERNAL_TextureSubresourceTransitionFromDefaultUsage( - renderer, - commandBuffer, - destinationUsageMode, - &texture->subresources[i]); - } + VULKAN_INTERNAL_FullTextureMemoryBarrier( + renderer, + commandBuffer, + VULKAN_INTERNAL_DefaultTextureUsageMode(texture), + destinationUsageMode, + texture); } static void VULKAN_INTERNAL_TextureSubresourceTransitionToDefaultUsage( @@ -2979,14 +3028,12 @@ static void VULKAN_INTERNAL_TextureTransitionToDefaultUsage( VulkanTextureUsageMode sourceUsageMode, VulkanTexture *texture) { - // FIXME: could optimize this barrier - for (Uint32 i = 0; i < texture->subresourceCount; i += 1) { - VULKAN_INTERNAL_TextureSubresourceTransitionToDefaultUsage( - renderer, - commandBuffer, - sourceUsageMode, - &texture->subresources[i]); - } + VULKAN_INTERNAL_FullTextureMemoryBarrier( + renderer, + commandBuffer, + sourceUsageMode, + VULKAN_INTERNAL_DefaultTextureUsageMode(texture), + texture); } // Resource Disposal @@ -5738,6 +5785,9 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture( texture->swizzle = SwizzleForSDLFormat(createinfo->format); texture->depth = depth; texture->usage = createinfo->usage; + texture->levelCount = createinfo->num_levels; + texture->layerCount = (createinfo->type == SDL_GPU_TEXTURETYPE_3D) ? 1 : createinfo->layer_count_or_depth; + texture->type = createinfo->type; SDL_SetAtomicInt(&texture->referenceCount, 0); if (IsDepthFormat(createinfo->format)) { @@ -6959,7 +7009,9 @@ static SDL_GPUTexture *VULKAN_CreateTexture( barrierCommandBuffer, VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, texture); + VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture); + if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) { VULKAN_ReleaseTexture((SDL_GPURenderer *)renderer, (SDL_GPUTexture *)container); return NULL; @@ -8402,7 +8454,6 @@ static void VULKAN_BindComputeStorageTextures( VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ, textureContainer->activeTexture); - VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); @@ -11119,24 +11170,26 @@ static bool VULKAN_INTERNAL_DefragmentMemory( } SDL_GPUTextureCreateInfo info = currentRegion->vulkanTexture->container->header.info; + + VULKAN_INTERNAL_TextureTransitionFromDefaultUsage( + renderer, + commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_COPY_SOURCE, + currentRegion->vulkanTexture); + + VULKAN_INTERNAL_FullTextureMemoryBarrier( + renderer, + commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, + VULKAN_TEXTURE_USAGE_MODE_COPY_DESTINATION, + newTexture + ); + + // Can only copy one mip level at a time for (Uint32 subresourceIndex = 0; subresourceIndex < currentRegion->vulkanTexture->subresourceCount; subresourceIndex += 1) { - // copy subresource if necessary VulkanTextureSubresource *srcSubresource = ¤tRegion->vulkanTexture->subresources[subresourceIndex]; VulkanTextureSubresource *dstSubresource = &newTexture->subresources[subresourceIndex]; - VULKAN_INTERNAL_TextureSubresourceTransitionFromDefaultUsage( - renderer, - commandBuffer, - VULKAN_TEXTURE_USAGE_MODE_COPY_SOURCE, - srcSubresource); - - VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( - renderer, - commandBuffer, - VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, - VULKAN_TEXTURE_USAGE_MODE_COPY_DESTINATION, - dstSubresource); - VkImageCopy imageCopy; imageCopy.srcOffset.x = 0; imageCopy.srcOffset.y = 0; @@ -11165,16 +11218,16 @@ static bool VULKAN_INTERNAL_DefragmentMemory( 1, &imageCopy); - VULKAN_INTERNAL_TextureSubresourceTransitionToDefaultUsage( - renderer, - commandBuffer, - VULKAN_TEXTURE_USAGE_MODE_COPY_DESTINATION, - dstSubresource); - VULKAN_INTERNAL_TrackTexture(commandBuffer, srcSubresource->parent); VULKAN_INTERNAL_TrackTexture(commandBuffer, dstSubresource->parent); } + VULKAN_INTERNAL_TextureTransitionToDefaultUsage( + renderer, + commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_COPY_DESTINATION, + newTexture); + // re-point original container to new texture newTexture->container = currentRegion->vulkanTexture->container; newTexture->containerIndex = currentRegion->vulkanTexture->containerIndex; From eb340388fc5bbe2240e7f221ac5e9ffb4bd57eec Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Thu, 14 May 2026 17:32:25 -0700 Subject: [PATCH 298/407] Fix HIDAPI support for Flydigi Vader 5 Pro (#15594) --- src/joystick/hidapi/SDL_hidapi_flydigi.c | 28 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_flydigi.c b/src/joystick/hidapi/SDL_hidapi_flydigi.c index a4958f6935..989609ca53 100644 --- a/src/joystick/hidapi/SDL_hidapi_flydigi.c +++ b/src/joystick/hidapi/SDL_hidapi_flydigi.c @@ -295,6 +295,24 @@ static void HIDAPI_DriverFlydigi_SetAvailable(SDL_HIDAPI_Device *device, bool av ctx->available = available; } +static int HIDAPI_DriverFlydigi_WritePacket(SDL_HIDAPI_Device *device, const Uint8 *data, size_t size) +{ + // We know that at the very least the Vader 5 now uses unnumbered reports for commands instead of FLYDIGI_V2_CMD_REPORT_ID. + // If other Flydigi things prove to do the same, we can tweak this check to be more general. + bool bUsesUnnumberedReports = (device->vendor_id == USB_VENDOR_FLYDIGI_V2 && device->product_id == USB_PRODUCT_FLYDIGI_V2_VADER); + + if (bUsesUnnumberedReports && data[0] == FLYDIGI_V2_CMD_REPORT_ID) { + // Zero out the report byte. + Uint8 output[USB_PACKET_LENGTH]; + SDL_memcpy(output, data, SDL_min(size, USB_PACKET_LENGTH)); + output[0] = 0; + return SDL_hid_write(device->dev, output, SDL_min(size, USB_PACKET_LENGTH)); + } + + return SDL_hid_write(device->dev, data, size); +} + + static bool HIDAPI_DriverFlydigi_InitControllerV1(SDL_HIDAPI_Device *device) { SDL_DriverFlydigi_Context *ctx = (SDL_DriverFlydigi_Context *)device->context; @@ -303,7 +321,7 @@ static bool HIDAPI_DriverFlydigi_InitControllerV1(SDL_HIDAPI_Device *device) for (int attempt = 0; ctx->deviceID == 0 && attempt < 30; ++attempt) { const Uint8 request[] = { FLYDIGI_V1_CMD_REPORT_ID, FLYDIGI_V1_GET_INFO_COMMAND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // This write will occasionally return -1, so ignore failure here and try again - (void)SDL_hid_write(device->dev, request, sizeof(request)); + (void)HIDAPI_DriverFlydigi_WritePacket(device, request, sizeof(request)); // Read the reply for (int i = 0; i < 100; ++i) { @@ -399,7 +417,8 @@ static bool SDL_HIDAPI_Flydigi_SendInfoRequest(SDL_HIDAPI_Device *device) 2, 0 }; - if (SDL_hid_write(device->dev, cmd, sizeof(cmd)) < 0) { + + if (HIDAPI_DriverFlydigi_WritePacket(device, cmd, sizeof(cmd)) < 0) { return SDL_SetError("Couldn't query controller info"); } return true; @@ -441,7 +460,8 @@ static bool SDL_HIDAPI_Flydigi_SendStatusRequest(SDL_HIDAPI_Device *device) FLYDIGI_V2_MAGIC2, FLYDIGI_V2_GET_STATUS_COMMAND }; - if (SDL_hid_write(device->dev, cmd, sizeof(cmd)) < 0) { + + if (HIDAPI_DriverFlydigi_WritePacket(device, cmd, sizeof(cmd)) < 0) { return SDL_SetError("Couldn't query controller status"); } return true; @@ -469,7 +489,7 @@ static bool SDL_HIDAPI_Flydigi_SendAcquireRequest(SDL_HIDAPI_Device *device, boo 'S', 'D', 'L', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (SDL_hid_write(device->dev, cmd, sizeof(cmd)) < 0) { + if (HIDAPI_DriverFlydigi_WritePacket(device, cmd, sizeof(cmd)) < 0) { return SDL_SetError("Couldn't send acquire command"); } return true; From 878789557545e161e048e1501c895d225c6c18b0 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Fri, 15 May 2026 02:29:37 +0200 Subject: [PATCH 299/407] SDL_video.h comment update --- include/SDL3/SDL_video.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 2076352980..3a3022c51a 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -453,10 +453,10 @@ typedef SDL_EGLint *(SDLCALL *SDL_EGLIntArrayCallback)(void *userdata, SDL_EGLDi /** * An enumeration of OpenGL configuration attributes. * - * While you can set most OpenGL attributes normally, the attributes listed - * above must be known before SDL creates the window that will be used with - * the OpenGL context. These attributes are set and read with - * SDL_GL_SetAttribute() and SDL_GL_GetAttribute(). + * While you can set most OpenGL attributes normally, they must be known before + * SDL creates the window that will be used with the OpenGL context. + * These attributes are set and read with SDL_GL_SetAttribute() and + * SDL_GL_GetAttribute(). * * In some cases, these attributes are minimum requests; the GL does not * promise to give you exactly what you asked for. It's possible to ask for a From ff98125cbd6ca94f0efa45288ec8d4a02fe12d79 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Fri, 15 May 2026 00:43:30 +0000 Subject: [PATCH 300/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_video.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 3a3022c51a..821c176101 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -453,8 +453,8 @@ typedef SDL_EGLint *(SDLCALL *SDL_EGLIntArrayCallback)(void *userdata, SDL_EGLDi /** * An enumeration of OpenGL configuration attributes. * - * While you can set most OpenGL attributes normally, they must be known before - * SDL creates the window that will be used with the OpenGL context. + * While you can set most OpenGL attributes normally, they must be known + * before SDL creates the window that will be used with the OpenGL context. * These attributes are set and read with SDL_GL_SetAttribute() and * SDL_GL_GetAttribute(). * From 6b26332785cb67a7380429ec4b8358c99c3773f1 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 14 May 2026 19:15:42 +0200 Subject: [PATCH 301/407] ci+release: build with gameinput support --- .github/workflows/create-test-plan.py | 9 ++++ .github/workflows/generic.yml | 8 +++ .github/workflows/release.yml | 6 +-- build-scripts/build-release.py | 54 +++++++++++++++++---- build-scripts/download-gameinput-headers.py | 44 +++++++++++++++++ build-scripts/release-info.json | 12 +++++ build-scripts/setup-gdk-desktop.py | 2 - 7 files changed, 120 insertions(+), 15 deletions(-) create mode 100755 build-scripts/download-gameinput-headers.py diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index c0e847c05f..8d5bdf621d 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -12,6 +12,7 @@ from typing import Optional logger = logging.getLogger(__name__) +WINDOWS_GAMEINPUT_VERSION = "v3.3.195.0 " class AppleArch(Enum): Aarch64 = "aarch64" @@ -217,6 +218,7 @@ class JobDetails: msys2_msystem: str = "" msys2_packages: list[str] = dataclasses.field(default_factory=list) werror: bool = True + microsoft_gameinput_version: str = "" msvc_vcvars_arch: str = "" msvc_vcvars_sdk: str = "" msvc_project: str = "" @@ -286,6 +288,7 @@ class JobDetails: "android-mk": self.android_mk, "werror": self.werror, "sudo": self.sudo, + "microsoft-gameinput-version": self.microsoft_gameinput_version, "msvc-vcvars-arch": self.msvc_vcvars_arch, "msvc-vcvars-sdk": self.msvc_vcvars_sdk, "msvc-project": self.msvc_project, @@ -437,6 +440,9 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args job.setup_libusb_arch = "x86" case MsvcArch.X64: job.setup_libusb_arch = "x64" + job.microsoft_gameinput_version = WINDOWS_GAMEINPUT_VERSION + job.cflags.append("-I$GAMEINPUT_INCLUDE") + job.cxxflags.append("-I$GAMEINPUT_INCLUDE") case SdlPlatform.Linux: if spec.name.startswith("Ubuntu"): assert spec.os.value.startswith("ubuntu-") @@ -764,6 +770,9 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args job.msys2_packages.append(f"{msys2_env}-clang-tools-extra") if job.ccache: job.msys2_packages.append(f"{msys2_env}-ccache") + job.microsoft_gameinput_version = WINDOWS_GAMEINPUT_VERSION + job.cflags.append("-I$GAMEINPUT_INCLUDE") + job.cxxflags.append("-I$GAMEINPUT_INCLUDE") case SdlPlatform.Riscos: job.ccache = False # FIXME: enable when container gets upgrade # FIXME: Enable SDL_WERROR diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 2ac0e30743..8250e50e72 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -167,6 +167,14 @@ jobs: echo '#error "System SDL headers must not be used by build system"' >"$dest" done done + - name: 'Set up Microsoft.GameInput headers' + if: ${{ matrix.platform.microsoft-gameinput-version != '' }} + run: | + python build-scripts/download-gameinput-headers.py \ + --version ${{ matrix.platform.microsoft-gameinput-version }} \ + -o $HOME/gameinput + echo "GAMEINPUT_INCLUDE=$(cygpath -w "$HOME/gameinput")" >>$GITHUB_ENV + echo "INCLUDE=$INCLUDE;$(cygpath -w "$HOME/gameinput")" >>$GITHUB_ENV - name: 'Calculate ccache key' if: ${{ matrix.platform.ccache }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6929f152d3..b619a514b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -345,7 +345,7 @@ jobs: id: releaser run: | python build-scripts/build-release.py ` - --actions msvc ` + --actions download msvc ` --commit ${{ inputs.commit }} ` --root "${{ steps.zip.outputs.path }}" ` --github ` @@ -507,7 +507,7 @@ jobs: id: releaser run: | python build-scripts/build-release.py \ - --actions mingw \ + --actions download mingw \ --commit ${{ inputs.commit }} \ --root "${{ steps.tar.outputs.path }}" \ --github \ @@ -619,7 +619,7 @@ jobs: id: releaser run: | python build-scripts/build-release.py \ - --actions android \ + --actions download android \ --android-api 21 \ --android-ndk-home "${{ steps.setup-ndk.outputs.ndk-path }}" \ --commit ${{ inputs.commit }} \ diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py index d3725382ce..4e153a1bf9 100755 --- a/build-scripts/build-release.py +++ b/build-scripts/build-release.py @@ -175,12 +175,15 @@ class VisualStudio: assert msbuild_path.is_file(), "MSBuild.exe does not exist" return msbuild_path - def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path]): + def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path], include_paths: list[str]): assert projects, "Need at least one project to build" vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}" msbuild_cmd_str = " && ".join([f"\"{self.msbuild}\" \"{project}\" /m /p:BuildInParallel=true /p:Platform={arch_platform.platform} /p:Configuration={arch_platform.configuration}" for project in projects]) - bat_contents = f"{vsdev_cmd_str} && {msbuild_cmd_str}\n" + include_contents = "%INCLUDE%" + if include_paths: + include_contents = f"{';'.join(str(p) for p in include_paths)};" + include_contents + bat_contents = textwrap.dedent(f"{vsdev_cmd_str} && set INCLUDE={include_contents} && {msbuild_cmd_str}") bat_path = Path(tempfile.gettempdir()) / "cmd.bat" with bat_path.open("w") as f: f.write(bat_contents) @@ -740,6 +743,12 @@ class Releaser: member.name = "/".join(Path(member.name).parts[1:]) return member for dep in self.release_info.get("dependencies", {}): + if "command" in self.release_info["dependencies"][dep]: + for arch, triplet in ARCH_TO_TRIPLET.items(): + shutil.copytree(self.deps_path / dep, str(mingw_deps_path / triplet), dirs_exist_ok=True) + (mingw_deps_path / triplet / "bin").mkdir(exist_ok=True) + (mingw_deps_path / triplet / "lib/pkgconfig").mkdir(exist_ok=True, parents=True) + continue extract_path = mingw_deps_path / f"extract-{dep}" extract_path.mkdir() with chdir(extract_path): @@ -856,8 +865,8 @@ class Releaser: f"cmake", f"-S", str(self.root), "-B", str(build_path), f"-DCMAKE_BUILD_TYPE={build_type}", - f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}" "-I{str(mingw_deps_path / triplet)}/include"''', + f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}" "-I{str(mingw_deps_path / triplet)}/include"''', f"-DCMAKE_PREFIX_PATH={mingw_deps_path / triplet}", f"-DCMAKE_INSTALL_PREFIX={install_path}", f"-DCMAKE_INSTALL_INCLUDEDIR=include", @@ -1129,6 +1138,15 @@ class Releaser: f.write(f"dep-path={self.deps_path.absolute()}\n") for dep, depinfo in self.release_info.get("dependencies", {}).items(): + if "command" in depinfo: + (self.deps_path / dep).mkdir(exist_ok=True, parents=True) + command_args = configure_text_list(shlex.split(depinfo["command"]), context=self.get_context(extra_context={ + "DEPS_PATH": str(self.deps_path / dep), + })) + if command_args[0].endswith(".py"): + command_args.insert(0, sys.executable) + self.executer.run(command_args) + continue startswith = depinfo["startswith"] dep_repo = depinfo["repo"] dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--exclude-pre-releases", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip() @@ -1143,6 +1161,10 @@ class Releaser: def verify_dependencies(self): for dep, depinfo in self.release_info.get("dependencies", {}).items(): + if "command" in depinfo: + command_matches = glob.glob(depinfo["artifact"], root_dir=self.deps_path) + assert len(command_matches) == 1, f"Exactly one archive matches command {dep} dependency: {command_matches}" + continue if "mingw" in self.release_info: mingw_matches = glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) assert len(mingw_matches) == 1, f"Exactly one archive matches mingw {dep} dependency: {mingw_matches}" @@ -1174,7 +1196,12 @@ class Releaser: deps_path = self.root / "msvc-deps" shutil.rmtree(deps_path, ignore_errors=True) dep_roots = [] - for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + dep_includes = [] + for dep in self.release_info.get("dependencies"): + if "command" in self.release_info["dependencies"][dep]: + dep_includes.append(self.deps_path / dep / "include") + continue + depinfo = self.release_info["msvc"]["dependencies"][dep] dep_extract_path = deps_path / f"extract-{dep}" msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] with zipfile.ZipFile(msvc_zip, "r") as zf: @@ -1184,13 +1211,18 @@ class Releaser: dep_roots.append(contents_msvc_zip[0]) for arch in self.release_info["msvc"].get("cmake", {}).get("archs", []): - self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots) + self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots, dep_includes=dep_includes) with self.section_printer.group("Create SDL VC development zip"): self._build_msvc_devel() def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): platform_context = self.get_context(arch_platform.extra_context()) - for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + include_paths = [] + for dep in self.release_info.get("dependencies", {}):#release_info["msvc"].get("dependencies", {}).items(): + if "command" in self.release_info["dependencies"][dep]: + include_paths.append(self.deps_path / dep / "include") + continue + depinfo = self.release_info["msvc"]["dependencies"][dep] msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] src_globs = [configure_text(instr["src"], context=platform_context) for instr in depinfo["copy"]] @@ -1238,7 +1270,7 @@ class Releaser: shutil.copy(src=src, dst=dir_b_props) with self.section_printer.group(f"Build {arch_platform.arch} VS binary"): - vs.build(arch_platform=arch_platform, projects=projects) + vs.build(arch_platform=arch_platform, projects=projects, include_paths=include_paths) if self.dry: for b in built_paths: @@ -1274,7 +1306,7 @@ class Releaser: def _arch_platform_to_install_path(self, arch_platform: VsArchPlatformConfig) -> Path: return self._arch_platform_to_build_path(arch_platform) / "prefix" - def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path]): + def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path], dep_includes: list[Path]): build_path = self._arch_platform_to_build_path(arch_platform) install_path = self._arch_platform_to_install_path(arch_platform) platform_context = self.get_context(extra_context=arch_platform.extra_context()) @@ -1290,7 +1322,7 @@ class Releaser: if not self.fast: for b in built_paths: b.unlink(missing_ok=True) - + cppflags = list(f"-I{inc}" for inc in dep_includes) shutil.rmtree(install_path, ignore_errors=True) build_path.mkdir(parents=True, exist_ok=True) with self.section_printer.group(f"Configure VC CMake project for {arch_platform.arch}"): @@ -1303,6 +1335,8 @@ class Releaser: "-DCMAKE_INSTALL_LIBDIR=lib", f"-DCMAKE_BUILD_TYPE={build_type}", f"-DCMAKE_INSTALL_PREFIX={install_path}", + f"-DCMAKE_C_FLAGS={shlex.join(cppflags)}", + f"-DCMAKE_CXX_FLAGS={shlex.join(cppflags)}", # MSVC debug information format flags are selected by an abstraction "-DCMAKE_POLICY_DEFAULT_CMP0141=NEW", # MSVC debug information format diff --git a/build-scripts/download-gameinput-headers.py b/build-scripts/download-gameinput-headers.py new file mode 100755 index 0000000000..13d50028c0 --- /dev/null +++ b/build-scripts/download-gameinput-headers.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import argparse +import logging +from pathlib import Path +import urllib.request + +logger = logging.getLogger(__name__) + +def download_headers(tag: str, lowercase: bool, output: Path): + base_url = f"https://raw.githubusercontent.com/microsoftconnect/GameInput/refs/tags/{tag}/" + url_relpaths = ( + "include/GameInput.h", + "include/v0/GameInput.h", + "include/v1/GameInput.h", + "include/v2/GameInput.h", + ) + remove_prefix = "include/" + for url_relpath in url_relpaths: + url = base_url + url_relpath + local_relpath = url_relpath.removeprefix(remove_prefix) + if lowercase: + local_relpath = local_relpath.lower() + local_path = output / local_relpath + + local_dirpath = local_path.parent + local_dirpath.mkdir(parents=False, exist_ok=True) + + logger.info("Downloading %s to %s...", url, local_path) + urllib.request.urlretrieve(url, local_path) + logger.info("... done") + +def main(): + logging.basicConfig(level=logging.INFO) + + parser = argparse.ArgumentParser(description="Download Microsoft.GameInput headers", allow_abbrev=False) + parser.add_argument("--version", required=True, help="GameInput release tag (see https://github.com/microsoftconnect/GameInput/tags)") + parser.add_argument("--no-lowercase", action="store_false", dest="lowercase", help="Don't lowercase downloaded headers") + parser.add_argument("-o", "--output", type=Path, default=Path.cwd(), help="Headers will be stored here (subdirectories created as ") + args = parser.parse_args() + download_headers(tag=args.version, lowercase=args.lowercase, output=args.output) + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json index 4847751414..e70683bc3a 100644 --- a/build-scripts/release-info.json +++ b/build-scripts/release-info.json @@ -1,6 +1,12 @@ { "name": "SDL3", "remote": "libsdl-org/SDL", + "dependencies": { + "gameinput": { + "command": "build-scripts/download-gameinput-headers.py -o @<@DEPS_PATH@>@/include --version v3.3.195.0", + "artifact": "gameinput/include/gameinput.h" + } + }, "version": { "file": "include/SDL3/SDL_version.h", "re_major": "^#define SDL_MAJOR_VERSION\\s+([0-9]+)$", @@ -54,6 +60,9 @@ "build-scripts/pkg-support/mingw/cmake/SDL3Config.cmake", "build-scripts/pkg-support/mingw/cmake/SDL3ConfigVersion.cmake" ] + }, + "dependencies": { + "gameinput": {} } }, "msvc": { @@ -129,6 +138,9 @@ "include/SDL3": [ "include/SDL3/*.h" ] + }, + "dependencies": { + "gameinput": {} } }, "android": { diff --git a/build-scripts/setup-gdk-desktop.py b/build-scripts/setup-gdk-desktop.py index d2309a0e31..8dc259d11b 100755 --- a/build-scripts/setup-gdk-desktop.py +++ b/build-scripts/setup-gdk-desktop.py @@ -262,8 +262,6 @@ def main(): parser.add_argument("--no-user-props", required=False, dest="user_props", action="store_false", help="Don't ") args = parser.parse_args() - logging.basicConfig(level=logging.INFO) - git_ref = None gdk_edition = None if args.ref_edition is not None: From d5af35e3fbb5bb6555ed00e69740d52af2a4e877 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 15 May 2026 03:47:28 +0200 Subject: [PATCH 302/407] surface: cannot set a palette to a non-indexed surface This fixes a UBSAN warning later in this function where it calculates (1 << SDL_BITSPERPIXEL(surface->format)). The bpp might be >= 32 and out of range for a bit shift. --- src/video/SDL_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 6a03fad732..ddd02fa657 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -423,7 +423,7 @@ SDL_Palette *SDL_CreateSurfacePalette(SDL_Surface *surface) bool SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette) { - CHECK_PARAM(!SDL_SurfaceValid(surface)) { + CHECK_PARAM(!SDL_SurfaceValid(surface) || !SDL_ISPIXELFORMAT_INDEXED(surface->format)) { return SDL_InvalidParamError("surface"); } From e1fa336ac4910b9e5b2096a5bc0f3c1b489364f4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 May 2026 10:25:40 -0400 Subject: [PATCH 303/407] android: Don't ever enumerate absolute paths from the assets tree. This could happen if opendir() failed for a reason other than the directory missing (for example, `opendir("/")` fails with EACCES. Reference Issue #15587. --- src/filesystem/posix/SDL_sysfsops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index 6183485b22..35ee29e246 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -97,9 +97,11 @@ bool SDL_SYS_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback DIR *dir = opendir(pathwithsep); if (!dir) { #ifdef SDL_PLATFORM_ANDROID // Maybe it's an asset... that didn't use an "assets://" URL? - const bool retval = Android_JNI_EnumerateAssetDirectory(pathwithsep + extralen, cb, userdata); - SDL_free(pathwithsep); - return retval; + if (*pathwithsep != '/') { // don't fall back to asset tree for absolute paths, in case opendir() failed for other reasons, like opendir("/") returning EACCES. + const bool retval = Android_JNI_EnumerateAssetDirectory(pathwithsep + extralen, cb, userdata); + SDL_free(pathwithsep); + return retval; + } #endif SDL_free(pathwithsep); return SDL_SetError("Can't open directory: %s", strerror(errno)); From be97a18d8244969877adf7530e874693a68cfbd7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 May 2026 10:34:30 -0400 Subject: [PATCH 304/407] android: Don't allow access to the asset tree with a path of "". Reference Issue #15587. --- src/core/android/SDL_android.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index ad07f07ad1..a4c56f92bc 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1902,6 +1902,11 @@ static APKNode *FindAPKChildNode(APKNode *parent, const char *child) static const APKNode *FindAPKNode(const char *constpath) { //SDL_Log("FindAPKNode('%s') ...", constpath); + + if (*constpath == '\0') { // don't allow paths of "". + return NULL; + } + if (SDL_strncmp(constpath, "assets://", 9) == 0) { constpath += 9; } From 6586bebfec42ed1418469d70dffa5216534bc635 Mon Sep 17 00:00:00 2001 From: stahta01 Date: Fri, 15 May 2026 11:48:24 -0400 Subject: [PATCH 305/407] Fix Cygwin building and add CI (#15566) Co-authored-by: TrueCat17 Co-authored-by: Anonymous Maarten Co-authored-by: Ozkan Sezer --- .github/workflows/create-test-plan.py | 23 ++++++++++++++ .github/workflows/generic.yml | 5 +++ CMakeLists.txt | 35 +++++++-------------- cmake/macros.cmake | 2 +- cmake/sdlplatform.cmake | 4 +++ include/SDL3/SDL_opengl.h | 2 +- include/SDL3/SDL_platform_defines.h | 4 +-- include/SDL3/SDL_stdinc.h | 10 +++--- include/SDL3/SDL_thread.h | 4 +-- src/SDL.c | 2 ++ src/audio/wasapi/SDL_wasapi.c | 2 +- src/core/windows/SDL_windows.h | 10 ++++++ src/dialog/windows/SDL_windowsdialog.c | 2 +- src/dynapi/SDL_dynapi.c | 6 ++-- src/gpu/d3d12/SDL_gpu_d3d12.c | 4 +-- src/hidapi/windows/hid.c | 2 +- src/io/SDL_iostream.c | 18 +++++------ src/io/SDL_iostream_c.h | 2 +- src/joystick/windows/SDL_rawinputjoystick.c | 6 ++-- src/time/windows/SDL_systime.c | 2 +- src/video/directx/SDL_d3d12.h | 7 +++++ src/video/windows/SDL_windowsrawinput.c | 2 +- src/video/windows/SDL_windowswindow.c | 28 ++++++++--------- test/CMakeLists.txt | 4 +-- test/childprocess.c | 4 +-- test/testautomation_stdlib.c | 4 ++- 26 files changed, 116 insertions(+), 78 deletions(-) diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py index 8d5bdf621d..03883289a3 100755 --- a/.github/workflows/create-test-plan.py +++ b/.github/workflows/create-test-plan.py @@ -43,6 +43,7 @@ class SdlPlatform(Enum): Haiku = "haiku" LoongArch64 = "loongarch64" Msys2 = "msys2" + Cygwin = "cygwin" Linux = "linux" MacOS = "macos" Ios = "ios" @@ -111,6 +112,7 @@ JOB_SPECS = { "msys2-mingw64": JobSpec(name="Windows (msys2, mingw64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64", msys2_platform=Msys2Platform.Mingw64, ), "msys2-clang64": JobSpec(name="Windows (msys2, clang64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64-clang", msys2_platform=Msys2Platform.Clang64, ), "msys2-ucrt64": JobSpec(name="Windows (msys2, ucrt64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64-ucrt", msys2_platform=Msys2Platform.Ucrt64, ), + "cygwin": JobSpec(name="Cygwin", os=JobOs.WindowsLatest, platform=SdlPlatform.Cygwin, artifact="SDL-cygwin", ), "msvc-x64": JobSpec(name="Windows (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x64", msvc_arch=MsvcArch.X64, msvc_project="VisualC/SDL.sln", ), "msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ), "msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ), @@ -162,6 +164,7 @@ class StaticLibType(Enum): class SharedLibType(Enum): WIN32 = "SDL3.dll" + CYGDLL = "cygSDL3.dll" SO_0 = "libSDL3.so.0" SO = "libSDL3.so" DYLIB = "libSDL3.0.dylib" @@ -217,6 +220,7 @@ class JobDetails: intel: bool = False msys2_msystem: str = "" msys2_packages: list[str] = dataclasses.field(default_factory=list) + cygwin_packages: list[str] = dataclasses.field(default_factory=list) werror: bool = True microsoft_gameinput_version: str = "" msvc_vcvars_arch: str = "" @@ -254,6 +258,7 @@ class JobDetails: "shell": self.shell, "msys2-msystem": self.msys2_msystem, "msys2-packages": my_shlex_join(self.msys2_packages), + "cygwin-packages": my_shlex_join(self.cygwin_packages), "android-ndk": self.android_ndk, "java": self.java, "intel": self.intel, @@ -773,6 +778,24 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args job.microsoft_gameinput_version = WINDOWS_GAMEINPUT_VERSION job.cflags.append("-I$GAMEINPUT_INCLUDE") job.cxxflags.append("-I$GAMEINPUT_INCLUDE") + case SdlPlatform.Cygwin: + job.ccache = False # Missing evict-older-than option + job.clang_tidy = False # error finding files [clang-diagnostic-error] cause might be space in command path + job.test_pkg_config = False # Linefeed issue in test_pkgconfig.sh + job.shell = "bash --noprofile --norc -eo pipefail -o igncr {0}" + job.shared_lib = SharedLibType.CYGDLL + job.static_lib = StaticLibType.A + job.cmake_arguments.append("-DSDLTEST_GDB=ON") + job.cygwin_packages.extend([ + "cmake", + "gcc-core", + "gcc-g++", + "gdb", + "ninja", + "pkg-config", + "perl", + "python", + ]) case SdlPlatform.Riscos: job.ccache = False # FIXME: enable when container gets upgrade # FIXME: Enable SDL_WERROR diff --git a/.github/workflows/generic.yml b/.github/workflows/generic.yml index 8250e50e72..be8180a20e 100644 --- a/.github/workflows/generic.yml +++ b/.github/workflows/generic.yml @@ -28,6 +28,11 @@ jobs: with: msystem: ${{ matrix.platform.msys2-msystem }} install: ${{ matrix.platform.msys2-packages }} + - name: 'Set up Cygwin' + if: ${{ matrix.platform.platform == 'cygwin' }} + uses: cygwin/cygwin-install-action@master + with: + packages: ${{ matrix.platform.cygwin-packages }} - name: 'About this job' run: | echo "key=${{ matrix.platform.key }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index cf87671216..824f82448a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -369,9 +369,9 @@ dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" O dep_option(SDL_RPI "Use Raspberry Pi video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF) dep_option(SDL_ROCKCHIP "Use ROCKCHIP Hardware Acceleration video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF) dep_option(SDL_COCOA "Use Cocoa video driver" ON "APPLE" OFF) -dep_option(SDL_DIRECTX "Use DirectX for Windows audio/video" ON "SDL_AUDIO OR SDL_VIDEO;WINDOWS" OFF) -dep_option(SDL_XINPUT "Use Xinput for Windows" ON "WINDOWS" OFF) -dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WINDOWS;SDL_AUDIO" OFF) +dep_option(SDL_DIRECTX "Use DirectX for Windows audio/video" ON "SDL_AUDIO OR SDL_VIDEO;WINDOWS OR CYGWIN" OFF) +dep_option(SDL_XINPUT "Use Xinput for Windows" ON "WINDOWS OR CYGWIN" OFF) +dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WINDOWS OR CYGWIN;SDL_AUDIO" OFF) dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) @@ -565,19 +565,6 @@ else() endif() endif() -if(CYGWIN) - # We build SDL on cygwin without the UNIX emulation layer - sdl_include_directories(PUBLIC SYSTEM "/usr/include/mingw") - cmake_push_check_state() - string(APPEND CMAKE_REQUIRED_FLAGS " -mno-cygwin") - check_c_source_compiles("int main(int argc, char **argv) { return 0; }" - HAVE_GCC_NO_CYGWIN) - cmake_pop_check_state() - if(HAVE_GCC_NO_CYGWIN) - sdl_shared_link_options("-mno-cygwin") - endif() -endif() - # General includes sdl_compile_definitions(PRIVATE "USING_GENERATED_CONFIG_H") sdl_include_directories( @@ -1165,7 +1152,7 @@ if(SDL_LIBC) vsnprintf vsscanf wcsnlen wcscmp wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr wcstol ) - if(WINDOWS) + if(WINDOWS OR CYGWIN) list(APPEND symbols_to_check _copysign _fseeki64 _strrev _ui64toa _uitoa _ultoa _wcsdup ) @@ -1444,7 +1431,7 @@ if(SDL_CAMERA) #endif() endif() -if(UNIX OR APPLE) +if((UNIX OR APPLE) AND NOT CYGWIN) # Relevant for Unix/Darwin only set(DYNAPI_NEEDS_DLOPEN 1) CheckDLOPEN() @@ -1843,7 +1830,7 @@ elseif(EMSCRIPTEN) CheckPTHREAD() CheckLibUnwind() -elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) +elseif(UNIX AND NOT (APPLE OR RISCOS OR HAIKU OR CYGWIN)) set(SDL_DISABLE_DLOPEN_NOTES TRUE) if(SDL_DLOPEN_NOTES) @@ -2234,7 +2221,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) set (HAVE_VSNPRINTF 0) set (USE_POSIX_SPAWN 1) endif() -elseif(WINDOWS) +elseif(WINDOWS OR CYGWIN) enable_language(CXX) check_c_source_compiles(" #include @@ -2268,7 +2255,7 @@ elseif(WINDOWS) if(DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700) set(USE_WINSDK_DIRECTX TRUE) endif() - if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) + if(NOT (MINGW OR CYGWIN) AND NOT USE_WINSDK_DIRECTX) if("$ENV{DXSDK_DIR}" STREQUAL "") message(FATAL_ERROR "DIRECTX requires the \$DXSDK_DIR environment variable to be set") endif() @@ -2287,7 +2274,7 @@ elseif(WINDOWS) cmake_pop_check_state() if(HAVE_D3D9_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H) set(HAVE_DIRECTX TRUE) - if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) + if(NOT (MINGW OR CYGWIN) AND NOT USE_WINSDK_DIRECTX) if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(PROCESSOR_ARCH "x64") else() @@ -4104,13 +4091,13 @@ if(SDL_SHARED) RESOURCE "${SDL_FRAMEWORK_RESOURCES}" ) endif() - elseif(UNIX AND NOT ANDROID) + elseif(UNIX AND NOT (ANDROID OR CYGWIN)) set_target_properties(SDL3-shared PROPERTIES VERSION "${SDL_SO_VERSION}" SOVERSION "${SDL_SO_VERSION_MAJOR}" ) else() - if(WINDOWS OR CYGWIN) + if(WINDOWS) set_target_properties(SDL3-shared PROPERTIES PREFIX "" ) diff --git a/cmake/macros.cmake b/cmake/macros.cmake index eb445b233d..afa0a3b597 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -425,7 +425,7 @@ function(SDL_PrintSummary) message(STATUS "") endif() - if(UNIX AND NOT (ANDROID OR APPLE OR EMSCRIPTEN OR HAIKU OR RISCOS OR DJGPP)) + if(UNIX AND NOT (ANDROID OR APPLE OR EMSCRIPTEN OR HAIKU OR RISCOS OR DJGPP OR CYGWIN)) if(NOT (HAVE_X11 OR HAVE_WAYLAND)) if(NOT SDL_UNIX_CONSOLE_BUILD) message(FATAL_ERROR diff --git a/cmake/sdlplatform.cmake b/cmake/sdlplatform.cmake index 6c60e0a2b3..14455f435e 100644 --- a/cmake/sdlplatform.cmake +++ b/cmake/sdlplatform.cmake @@ -4,6 +4,10 @@ function(SDL_DetectCMakePlatform) set(sdl_cmake_platform Windows) elseif(PSP) set(sdl_cmake_platform psp) + elseif(CYGWIN AND NOT MSYS) + set(sdl_cmake_platform Cygwin) + elseif(MSYS) + set(sdl_cmake_platform Msys) elseif(APPLE) if(CMAKE_SYSTEM_NAME MATCHES ".*(Darwin|MacOS).*") set(sdl_cmake_platform macOS) diff --git a/include/SDL3/SDL_opengl.h b/include/SDL3/SDL_opengl.h index 733f2b51a0..d76764b253 100644 --- a/include/SDL3/SDL_opengl.h +++ b/include/SDL3/SDL_opengl.h @@ -84,7 +84,7 @@ # else # define GLAPIENTRY __stdcall # endif -#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ +#elif defined(__CYGWIN__) /* && defined(USE_OPENGL32) */ /* use native windows opengl32 */ # define GLAPI extern # define GLAPIENTRY __stdcall #elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h index 23ff34ce10..71dbd53fec 100644 --- a/include/SDL3/SDL_platform_defines.h +++ b/include/SDL3/SDL_platform_defines.h @@ -317,7 +317,7 @@ #define SDL_PLATFORM_CYGWIN 1 #endif -#if (defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(__NGAGE__) +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(__NGAGE__) /** * A preprocessor macro that is only defined if compiling for Windows. @@ -417,7 +417,7 @@ #define SDL_PLATFORM_WIN32 1 #endif -#endif /* defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) */ +#endif /* (defined(_WIN32) || defined(__CYGWIN__)) && !defined(__NGAGE__) */ /* This is to support generic "any GDK" separate from a platform-specific GDK */ diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index 893f2052f7..3a7920abeb 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -739,7 +739,7 @@ typedef Sint64 SDL_Time; * should define these but this is not true all platforms. * (for example win32) */ #ifndef SDL_PRIs64 -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #define SDL_PRIs64 "I64d" #elif defined(PRId64) #define SDL_PRIs64 PRId64 @@ -750,7 +750,7 @@ typedef Sint64 SDL_Time; #endif #endif #ifndef SDL_PRIu64 -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #define SDL_PRIu64 "I64u" #elif defined(PRIu64) #define SDL_PRIu64 PRIu64 @@ -761,7 +761,7 @@ typedef Sint64 SDL_Time; #endif #endif #ifndef SDL_PRIx64 -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #define SDL_PRIx64 "I64x" #elif defined(PRIx64) #define SDL_PRIx64 PRIx64 @@ -772,7 +772,7 @@ typedef Sint64 SDL_Time; #endif #endif #ifndef SDL_PRIX64 -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #define SDL_PRIX64 "I64X" #elif defined(PRIX64) #define SDL_PRIX64 PRIX64 @@ -811,7 +811,7 @@ typedef Sint64 SDL_Time; #endif #endif /* Specifically for the `long long` -- SDL-specific. */ -#ifdef SDL_PLATFORM_WINDOWS +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #ifndef SDL_NOLONGLONG SDL_COMPILE_TIME_ASSERT(longlong_size64, sizeof(long long) == 8); /* using I64 for windows - make sure `long long` is 64 bits. */ #endif diff --git a/include/SDL3/SDL_thread.h b/include/SDL3/SDL_thread.h index 1842c035f7..83d11f90a2 100644 --- a/include/SDL3/SDL_thread.h +++ b/include/SDL3/SDL_thread.h @@ -48,7 +48,7 @@ /* Thread synchronization primitives */ #include -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #include /* _beginthreadex() and _endthreadex() */ #endif @@ -296,7 +296,7 @@ extern SDL_DECLSPEC SDL_Thread * SDLCALL SDL_CreateThreadWithProperties(SDL_Prop /* The real implementation, hidden from the wiki, so it can show this as real functions that don't have macro magic. */ #ifndef SDL_WIKI_DOCUMENTATION_SECTION -# if defined(SDL_PLATFORM_WINDOWS) +# if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) # ifndef SDL_BeginThreadFunction # define SDL_BeginThreadFunction _beginthreadex # endif diff --git a/src/SDL.c b/src/SDL.c index 350ca34b34..11b8872928 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -793,6 +793,8 @@ const char *SDL_GetPlatform(void) return "Solaris"; #elif defined(SDL_PLATFORM_WIN32) return "Windows"; +#elif defined(SDL_PLATFORM_CYGWIN) + return "Cygwin"; #elif defined(SDL_PLATFORM_WINGDK) return "WinGDK"; #elif defined(SDL_PLATFORM_XBOXONE) diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index c01f007ff1..2ef4de82fe 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -773,7 +773,7 @@ static bool mgmtthrtask_PrepDevice(void *userdata) ret = IAudioClient2_SetClientProperties(client2, &audioProps); if (FAILED(ret)) { // This isn't fatal, let's log it instead of failing - SDL_LogWarn(SDL_LOG_CATEGORY_AUDIO, "IAudioClient2_SetClientProperties failed: 0x%lx", ret); + SDL_LogWarn(SDL_LOG_CATEGORY_AUDIO, "IAudioClient2_SetClientProperties failed: 0x%" SDL_PRIxSLONG, ret); } IAudioClient2_Release(client2); } diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index 5317e30d08..62c1c3a9af 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -146,6 +146,16 @@ #define SDL_tcsstr SDL_strstr #endif +#if defined(__LP64__) +#define SDL_PRIdSLONG "d" +#define SDL_PRIuULONG "u" +#define SDL_PRIxSLONG "x" +#else +#define SDL_PRIdSLONG "ld" +#define SDL_PRIuULONG "lu" +#define SDL_PRIxSLONG "lx" +#endif + // Set up for C function definitions, even when using C++ #ifdef __cplusplus extern "C" { diff --git a/src/dialog/windows/SDL_windowsdialog.c b/src/dialog/windows/SDL_windowsdialog.c index 99a49384d6..a9f2c749bd 100644 --- a/src/dialog/windows/SDL_windowsdialog.c +++ b/src/dialog/windows/SDL_windowsdialog.c @@ -1035,7 +1035,7 @@ void windows_ShowFileDialog(void *ptr) const char *opts[1] = { NULL }; callback(userdata, opts, getFilterIndex(dialog.nFilterIndex)); } else { - SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError()); + SDL_SetError("Windows error, CommDlgExtendedError: %" SDL_PRIuULONG, pCommDlgExtendedError()); callback(userdata, NULL, -1); } } diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index a0135dca42..fcbbbd6d61 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -48,7 +48,7 @@ // These headers have system specific definitions, so aren't included above #include -#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif @@ -451,7 +451,7 @@ Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) // Obviously we can't use SDL_LoadObject() to load SDL. :) // Also obviously, we never close the loaded library, once we accept it. -#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) static HMODULE sdlapi_lib = NULL; // The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR static SDL_INLINE void unload_sdlapi_library(void) @@ -509,7 +509,7 @@ static void dynapi_warn(const char *msg) const char *caption = "SDL Dynamic API Failure!"; (void)caption; // SDL_ShowSimpleMessageBox() is a too heavy for here. -#if (defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) +#if (defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR); #elif defined(HAVE_STDIO_H) fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg); diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 3a1d651fdd..2b65006d21 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -9036,7 +9036,7 @@ static bool D3D12_INTERNAL_GetAdapterByLuid(LUID luid, IDXGIFactory1 *factory, I IDXGIAdapter1 *adapter; res = IDXGIFactory1_EnumAdapters1(factory, adapterIndex, &adapter); if (FAILED(res)) { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to get an adapter when iterating, i: %d, res: %ld", adapterIndex, res); + SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to get an adapter when iterating, i: %d, res: %" SDL_PRIdSLONG, adapterIndex, res); return false; } @@ -9044,7 +9044,7 @@ static bool D3D12_INTERNAL_GetAdapterByLuid(LUID luid, IDXGIFactory1 *factory, I res = IDXGIAdapter1_GetDesc1(adapter, &adapterDesc); if (FAILED(res)) { IDXGIAdapter1_Release(adapter); - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to get description of adapter, i: %d, res %ld", adapterIndex, res); + SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to get description of adapter, i: %d, res %" SDL_PRIdSLONG, adapterIndex, res); return false; } if (SDL_memcmp(&adapterDesc.AdapterLuid, &luid, sizeof(luid)) == 0) { diff --git a/src/hidapi/windows/hid.c b/src/hidapi/windows/hid.c index 49a53f9bb3..3d0b4d41d7 100644 --- a/src/hidapi/windows/hid.c +++ b/src/hidapi/windows/hid.c @@ -45,7 +45,7 @@ typedef LONG NTSTATUS; #define _WIN32_WINNT_WIN8 0x0602 #endif -#ifdef __CYGWIN__ +#if defined(__CYGWIN__) && !defined(HIDAPI_USING_SDL_RUNTIME) #include #include #define _wcsdup wcsdup diff --git a/src/io/SDL_iostream.c b/src/io/SDL_iostream.c index 6b19364678..9b5a0978f2 100644 --- a/src/io/SDL_iostream.c +++ b/src/io/SDL_iostream.c @@ -20,7 +20,7 @@ */ #include "SDL_internal.h" -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) #include "../core/windows/SDL_windows.h" #else #include @@ -62,7 +62,7 @@ struct SDL_IOStream #include "../core/android/SDL_android.h" #endif -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) typedef struct IOStreamWindowsData { @@ -478,9 +478,7 @@ SDL_IOStream *SDL_IOFromHandle(HANDLE handle, const char *mode, bool autoclose) return iostr; } -#endif // defined(SDL_PLATFORM_WINDOWS) - -#if !defined(SDL_PLATFORM_WINDOWS) +#else // Functions to read/write file descriptors. Not used for windows. @@ -672,9 +670,9 @@ SDL_IOStream *SDL_IOFromFD(int fd, bool autoclose) return iostr; } -#endif // !defined(SDL_PLATFORM_WINDOWS) +#endif // SDL_PLATFORM_WINDOWS && !SDL_PLATFORM_CYGWIN -#if defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINDOWS) +#if defined(HAVE_STDIO_H) && !(defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN)) // Functions to read/write stdio file pointers. Not used for windows. @@ -871,7 +869,7 @@ SDL_IOStream *SDL_IOFromFP(FILE *fp, bool autoclose) return iostr; } -#endif // !HAVE_STDIO_H && !defined(SDL_PLATFORM_WINDOWS) +#endif // HAVE_STDIO_H && !SDL_PLATFORM_WINDOWS && !SDL_PLATFORM_CYGWIN // Functions to read/write memory pointers @@ -965,7 +963,7 @@ static bool SDLCALL mem_close(void *userdata) // Functions to create SDL_IOStream structures from various data sources // private platforms might define SKIP_STDIO_DIR_TEST in their build configs, too. -#if defined(SDL_PLATFORM_WINDOWS) || defined(SDL_PLATFORM_EMSCRIPTEN) +#if (defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN)) || defined(SDL_PLATFORM_EMSCRIPTEN) #define SKIP_STDIO_DIR_TEST 1 #endif @@ -1101,7 +1099,7 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode) iostr = SDL_IOFromFP(fp, true); } -#elif defined(SDL_PLATFORM_WINDOWS) +#elif defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) HANDLE handle = windows_file_open(file, mode); if (handle != INVALID_HANDLE_VALUE) { iostr = SDL_IOFromHandle(handle, mode, true); diff --git a/src/io/SDL_iostream_c.h b/src/io/SDL_iostream_c.h index fadb98bcb6..be955e89ad 100644 --- a/src/io/SDL_iostream_c.h +++ b/src/io/SDL_iostream_c.h @@ -23,7 +23,7 @@ #ifndef SDL_iostream_c_h_ #define SDL_iostream_c_h_ -#if defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) SDL_IOStream *SDL_IOFromHandle(HANDLE handle, const char *mode, bool autoclose); #else #if defined(HAVE_STDIO_H) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index da557c5e86..8c660c3d23 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -706,12 +706,12 @@ static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadAdded(wgi_state.gamepad_statics, &gamepad_added.iface, &wgi_state.gamepad_added_token); if (!SUCCEEDED(hr)) { - SDL_SetError("add_GamepadAdded() failed: 0x%lx", hr); + SDL_SetError("add_GamepadAdded() failed: 0x%" SDL_PRIxSLONG, hr); } hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadRemoved(wgi_state.gamepad_statics, &gamepad_removed.iface, &wgi_state.gamepad_removed_token); if (!SUCCEEDED(hr)) { - SDL_SetError("add_GamepadRemoved() failed: 0x%lx", hr); + SDL_SetError("add_GamepadRemoved() failed: 0x%" SDL_PRIxSLONG, hr); } } } @@ -1508,7 +1508,7 @@ static bool RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_ WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, ctx->vibration); if (!SUCCEEDED(hr)) { - return SDL_SetError("Setting vibration failed: 0x%lx", hr); + return SDL_SetError("Setting vibration failed: 0x%" SDL_PRIxSLONG, hr); } ctx->triggers_rumbling = (left_rumble > 0 || right_rumble > 0); return true; diff --git a/src/time/windows/SDL_systime.c b/src/time/windows/SDL_systime.c index a35ae7286a..e36ad01841 100644 --- a/src/time/windows/SDL_systime.c +++ b/src/time/windows/SDL_systime.c @@ -151,7 +151,7 @@ bool SDL_TimeToDateTime(SDL_Time ticks, SDL_DateTime *dt, bool localTime) } } - return SDL_SetError("SDL_DateTime conversion failed (%lu)", GetLastError()); + return SDL_SetError("SDL_DateTime conversion failed (%" SDL_PRIuULONG ")", GetLastError()); } #endif // SDL_TIME_WINDOWS diff --git a/src/video/directx/SDL_d3d12.h b/src/video/directx/SDL_d3d12.h index 2dfe672209..1d7a7e8070 100644 --- a/src/video/directx/SDL_d3d12.h +++ b/src/video/directx/SDL_d3d12.h @@ -37,8 +37,15 @@ #define WINAPI_PARTITION_GAMES 0 #endif // WINAPI_PARTITION_GAMES +#ifdef __CYGWIN__ + // generated header d3d12.h wants to see _WIN32 defined in order to believe it's targeting windows + #define _WIN32 1 +#endif #define COBJMACROS #include "d3d12.h" +#ifdef __CYGWIN__ + #undef _WIN32 +#endif #include #include diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index e9b4aad3d9..497e8007bc 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -78,7 +78,7 @@ static RawInputIterateResult IterateRawInputThread(void) } else if (wait_status == WAIT_INPUT) { return RINP_CONTINUE; } else { - SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Raw input thread exiting, unexpected wait result: %lu", wait_status); + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Raw input thread exiting, unexpected wait result: %" SDL_PRIuULONG, wait_status); return RINP_QUIT; } } diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 506fdc1ae5..bf9c394457 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -1771,16 +1771,16 @@ static STDMETHODIMP SDLDropTarget_DragEnter(SDLDropTarget *target, POINTL pt, DWORD *pdwEffect) { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragEnter at %ld, %ld", pt.x, pt.y); + ". In DragEnter at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG, pt.x, pt.y); *pdwEffect = DROPEFFECT_COPY; POINT pnt = { pt.x, pt.y }; if (ScreenToClient(target->hwnd, &pnt)) { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragEnter at %ld, %ld => window %u at %ld, %ld", pt.x, pt.y, target->window->id, pnt.x, pnt.y); + ". In DragEnter at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => window %u at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG, pt.x, pt.y, target->window->id, pnt.x, pnt.y); SDL_SendDropPosition(target->window, pnt.x, pnt.y); } else { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragEnter at %ld, %ld => nil, nil", pt.x, pt.y); + ". In DragEnter at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => nil, nil", pt.x, pt.y); } return S_OK; } @@ -1790,16 +1790,16 @@ static STDMETHODIMP SDLDropTarget_DragOver(SDLDropTarget *target, POINTL pt, DWORD *pdwEffect) { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragOver at %ld, %ld", pt.x, pt.y); + ". In DragOver at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG, pt.x, pt.y); *pdwEffect = DROPEFFECT_COPY; POINT pnt = { pt.x, pt.y }; if (ScreenToClient(target->hwnd, &pnt)) { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragOver at %ld, %ld => window %u at %ld, %ld", pt.x, pt.y, target->window->id, pnt.x, pnt.y); + ". In DragOver at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => window %u at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG, pt.x, pt.y, target->window->id, pnt.x, pnt.y); SDL_SendDropPosition(target->window, pnt.x, pnt.y); } else { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In DragOver at %ld, %ld => nil, nil", pt.x, pt.y); + ". In DragOver at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => nil, nil", pt.x, pt.y); } return S_OK; } @@ -1820,11 +1820,11 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, POINT pnt = { pt.x, pt.y }; if (ScreenToClient(target->hwnd, &pnt)) { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop at %ld, %ld => window %u at %ld, %ld", pt.x, pt.y, target->window->id, pnt.x, pnt.y); + ". In Drop at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => window %u at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG, pt.x, pt.y, target->window->id, pnt.x, pnt.y); SDL_SendDropPosition(target->window, pnt.x, pnt.y); } else { SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop at %ld, %ld => nil, nil", pt.x, pt.y); + ". In Drop at %" SDL_PRIdSLONG ", %" SDL_PRIdSLONG " => nil, nil", pt.x, pt.y); } { @@ -1832,7 +1832,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, HRESULT hres; hres = pDataObject->lpVtbl->EnumFormatEtc(pDataObject, DATADIR_GET, &pEnumFormatEtc); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop for EnumFormatEtc, HRESULT is %08lx", hres); + ". In Drop for EnumFormatEtc, HRESULT is %08" SDL_PRIxSLONG, hres); if (hres == S_OK) { FORMATETC fetc; while (pEnumFormatEtc->lpVtbl->Next(pEnumFormatEtc, 1, &fetc, NULL) == S_OK) { @@ -1864,7 +1864,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, STGMEDIUM med; HRESULT hres = pDataObject->lpVtbl->GetData(pDataObject, &fetc, &med); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop File for GetData, format %08x '%s', HRESULT is %08lx", + ". In Drop File for GetData, format %08x '%s', HRESULT is %08" SDL_PRIxSLONG, fetc.cfFormat, format_mime, hres); if (SUCCEEDED(hres)) { const size_t bsize = GlobalSize(med.hGlobal); @@ -1912,7 +1912,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, STGMEDIUM med; HRESULT hres = pDataObject->lpVtbl->GetData(pDataObject, &fetc, &med); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop Text for GetData, format %08x '%s', HRESULT is %08lx", + ". In Drop Text for GetData, format %08x '%s', HRESULT is %08" SDL_PRIxSLONG, fetc.cfFormat, format_mime, hres); if (SUCCEEDED(hres)) { const size_t bsize = GlobalSize(med.hGlobal); @@ -1958,7 +1958,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, STGMEDIUM med; HRESULT hres = pDataObject->lpVtbl->GetData(pDataObject, &fetc, &med); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop Text for GetData, format %08x '%s', HRESULT is %08lx", + ". In Drop Text for GetData, format %08x '%s', HRESULT is %08" SDL_PRIxSLONG, fetc.cfFormat, format_mime, hres); if (SUCCEEDED(hres)) { const size_t bsize = GlobalSize(med.hGlobal); @@ -2012,7 +2012,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, STGMEDIUM med; HRESULT hres = pDataObject->lpVtbl->GetData(pDataObject, &fetc, &med); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop Text for GetData, format %08x '%s', HRESULT is %08lx", + ". In Drop Text for GetData, format %08x '%s', HRESULT is %08" SDL_PRIxSLONG, fetc.cfFormat, format_mime, hres); if (SUCCEEDED(hres)) { const size_t bsize = GlobalSize(med.hGlobal); @@ -2058,7 +2058,7 @@ static STDMETHODIMP SDLDropTarget_Drop(SDLDropTarget *target, STGMEDIUM med; HRESULT hres = pDataObject->lpVtbl->GetData(pDataObject, &fetc, &med); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In Drop File for GetData, format %08x '%s', HRESULT is %08lx", + ". In Drop File for GetData, format %08x '%s', HRESULT is %08" SDL_PRIxSLONG, fetc.cfFormat, format_mime, hres); if (SUCCEEDED(hres)) { const size_t bsize = GlobalSize(med.hGlobal); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 895f885b13..654ff18874 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -374,7 +374,7 @@ if(MACOS) testnativecocoa.m testnativex11.c ) -elseif(WINDOWS) +elseif(WINDOWS OR CYGWIN) add_sdl_test_executable(testnative BUILD_DEPENDENT NEEDS_RESOURCES TESTUTILS SOURCES testnative.c testnativew32.c) elseif(HAVE_X11 OR HAVE_WAYLAND) add_sdl_test_executable(testnative BUILD_DEPENDENT NEEDS_RESOURCES TESTUTILS SOURCES testnative.c) @@ -671,7 +671,7 @@ function(add_sdl_test TEST TARGET) COMMAND ${command} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.27") + if((WIN32 OR CYGWIN) AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.27") set_property(TEST ${TEST} APPEND PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$") endif() if(NOT notrackmem) diff --git a/test/childprocess.c b/test/childprocess.c index 69a7cea2da..ccce2e8622 100644 --- a/test/childprocess.c +++ b/test/childprocess.c @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { if (print_arguments) { int print_i; -#ifdef SDL_PLATFORM_WINDOWS +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) /* reopen stdout as binary to prevent newline conversion */ _setmode(_fileno(stdout), _O_BINARY); #endif @@ -145,7 +145,7 @@ int main(int argc, char *argv[]) { continue; } -#ifdef SDL_PLATFORM_WINDOWS +#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_CYGWIN) if (strerror_s(error, sizeof(error), errno) != 0) { SDL_strlcpy(error, "Unknown error", sizeof(error)); } diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c index 4d1c6ea5db..d3f5c54cd8 100644 --- a/test/testautomation_stdlib.c +++ b/test/testautomation_stdlib.c @@ -934,7 +934,9 @@ static int SDLCALL stdlib_sscanf(void *arg) #pragma GCC diagnostic pop #endif -#ifdef _WIN64 +#if defined(SDL_PLATFORM_CYGWIN) +#define SIZE_FORMAT "zu" +#elif defined(_WIN64) #define SIZE_FORMAT "I64u" #elif defined(SDL_PLATFORM_WIN32) #define SIZE_FORMAT "I32u" From bd146867e45bd5c8121c866d64161e70d9bf58c6 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 15 May 2026 16:55:50 +0100 Subject: [PATCH 306/407] Update showFileDialog in proguard-rules.pro to match changes in 439ffd1 --- android-project/app/proguard-rules.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-project/app/proguard-rules.pro b/android-project/app/proguard-rules.pro index 66ecc43f14..a13768966c 100644 --- a/android-project/app/proguard-rules.pro +++ b/android-project/app/proguard-rules.pro @@ -48,7 +48,7 @@ boolean showTextInput(int, int, int, int, int); boolean supportsRelativeMouse(); int openFileDescriptor(java.lang.String, java.lang.String); - boolean showFileDialog(java.lang.String[], boolean, boolean, int); + boolean showFileDialog(java.lang.String[], boolean, int, java.lang.String, int); java.lang.String getPreferredLocales(); java.lang.String formatLocale(java.util.Locale); } From d1d54b8c56aa1025c663655d8f00e84eaa7a5ef3 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 15 May 2026 02:35:10 +0200 Subject: [PATCH 307/407] test: build testsprite as c++ application --- test/CMakeLists.txt | 9 +++++++++ test/testsprite.cpp | 1 + test/testutils.h | 14 +++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/testsprite.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 654ff18874..4c5a416e61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,10 +13,16 @@ set(SDL3_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake") include(CheckIncludeFile) +include(CheckLanguage) include(CheckStructHasMember) include(CMakePushCheckState) include(sdlcompilers) +check_language(CXX) +if(CMAKE_CXX_COMPILER) + enable_language(CXX) +endif() + find_package(Python3 COMPONENTS Interpreter) if(NOT PYTHON3_EXECUTABLE) set(PYTHON3_EXECUTABLE "python3") @@ -449,6 +455,9 @@ add_sdl_test_executable(testsoftwaretransparent SOURCES testsoftwaretransparent. add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c NAME83 sprite) add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 spritmin) add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_png_header} DEPENDS generate-icon_png_header NAME83 spritsrf) +if(CMAKE_CXX_COMPILER) + add_sdl_test_executable(testspritecxx MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.cpp NAME83 spritexx) +endif() add_sdl_test_executable(testpalette SOURCES testpalette.c NAME83 palette) add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c NAME83 timer) add_sdl_test_executable(testurl SOURCES testurl.c NAME83 url) diff --git a/test/testsprite.cpp b/test/testsprite.cpp new file mode 100644 index 0000000000..17b537c23b --- /dev/null +++ b/test/testsprite.cpp @@ -0,0 +1 @@ +#include "testsprite.c" diff --git a/test/testutils.h b/test/testutils.h index 25b326b35b..83d7c295a3 100644 --- a/test/testutils.h +++ b/test/testutils.h @@ -16,8 +16,16 @@ #include -SDL_Texture *LoadTexture(SDL_Renderer *renderer, const char *file, bool transparent); -char *GetNearbyFilename(const char *file); -char *GetResourceFilename(const char *user_specified, const char *def); +#ifdef __cplusplus +extern "C" { +#endif + +extern SDL_Texture *LoadTexture(SDL_Renderer *renderer, const char *file, bool transparent); +extern char *GetNearbyFilename(const char *file); +extern char *GetResourceFilename(const char *user_specified, const char *def); + +#ifdef __cplusplus +} +#endif #endif From a95ce7e734f8f8b5fa5740a8e40a93cf670db8db Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 May 2026 10:13:15 -0700 Subject: [PATCH 308/407] Detect the GameSir Super Nova in Xbox 360 mode --- .../app/src/main/java/org/libsdl/app/HIDDeviceManager.java | 1 + src/hidapi/libusb/hid.c | 1 + src/joystick/hidapi/SDL_hidapijoystick.c | 1 + 3 files changed, 3 insertions(+) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java index b00c905df6..4b1fa5186d 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -256,6 +256,7 @@ public class HIDDeviceManager { 0x24c6, // PowerA 0x2c22, // Qanba 0x2dc8, // 8BitDo + 0x3537, // GameSir 0x37d7, // Flydigi 0x9886, // ASTRO Gaming }; diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c index 956e982b1a..c5e68d7e19 100644 --- a/src/hidapi/libusb/hid.c +++ b/src/hidapi/libusb/hid.c @@ -853,6 +853,7 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de 0x24c6, /* PowerA */ 0x2c22, /* Qanba */ 0x2dc8, /* 8BitDo */ + 0x3537, /* GameSir */ 0x37d7, /* Flydigi */ 0x9886, /* ASTRO Gaming */ }; diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 81587b0a33..c8bca941aa 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -288,6 +288,7 @@ static SDL_GamepadType SDL_GetJoystickGameControllerProtocol(const char *name, U 0x24c6, // PowerA 0x2c22, // Qanba 0x2dc8, // 8BitDo + 0x3537, // GameSir 0x37d7, // Flydigi 0x9886, // ASTRO Gaming }; From aeacf42e0659e3fee1e00730193f63125dc41594 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 May 2026 11:00:11 -0700 Subject: [PATCH 309/407] gameinput: only add the share button for known Xbox Series X controllers The HID descriptor for the latest firmware always includes the share button, and GameInput will report it as always available, so double check against our list of classic Xbox One controllers and don't include the button on controllers that don't have it. --- src/joystick/gdk/SDL_gameinputjoystick.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index 0c04592ac5..1c099236c8 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -49,6 +49,8 @@ typedef struct GAMEINPUT_InternalDevice SDL_GUID guid; // generated by SDL SDL_JoystickID device_instance; // generated by SDL const GameInputDeviceInfo *info; + Uint16 vendor; + Uint16 product; int raw_type; int steam_virtual_gamepad_slot; bool isAdded; @@ -279,6 +281,8 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, NULL, product_string, driver_signature, subtype); elem->device_instance = SDL_GetNextObjectID(); elem->info = info; + elem->vendor = vendor; + elem->product = product; elem->raw_type = raw_type; #if GAMEINPUT_API_VERSION >= 1 elem->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(info->pnpPath); @@ -609,11 +613,15 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) #if GAMEINPUT_API_VERSION >= 1 if (info->supportedSystemButtons != GameInputSystemButtonNone) { - if (info->supportedSystemButtons & GameInputSystemButtonShare) { + GameInputSystemButtons buttons = GameInputSystemButtonGuide; + + if (SDL_IsJoystickXboxSeriesX(elem->vendor, elem->product) && + (info->supportedSystemButtons & GameInputSystemButtonShare)) { ++joystick->nbuttons; + buttons |= GameInputSystemButtonShare; } - g_pGameInput->RegisterSystemButtonCallback(elem->device, (GameInputSystemButtonGuide | GameInputSystemButtonShare), joystick, GAMEINPUT_InternalSystemButtonCallback, &hwdata->system_button_callback_token); + g_pGameInput->RegisterSystemButtonCallback(elem->device, buttons, joystick, GAMEINPUT_InternalSystemButtonCallback, &hwdata->system_button_callback_token); } #endif // GAMEINPUT_API_VERSION >= 1 } else { @@ -990,7 +998,8 @@ static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap out->guide.target = SDL_GAMEPAD_BUTTON_GUIDE; } - if (elem->info->supportedSystemButtons & GameInputSystemButtonShare) { + if (SDL_IsJoystickXboxSeriesX(elem->vendor, elem->product) && + (elem->info->supportedSystemButtons & GameInputSystemButtonShare)) { out->misc1.kind = EMappingKind_Button; out->misc1.target = SDL_GAMEPAD_BUTTON_GAMEINPUT_SHARE; } From 86296ac8f01597076979630667472a846b04ce46 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+thatcosmonaut@users.noreply.github.com> Date: Fri, 15 May 2026 11:43:57 -0700 Subject: [PATCH 310/407] GPU: Set missing fields on Vulkan swapchain texture (#15606) --- src/gpu/vulkan/SDL_gpu_vulkan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index b7983859d8..3b9efe5c45 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -4900,6 +4900,9 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain( windowData->textureContainers[i].activeTexture->aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; windowData->textureContainers[i].activeTexture->depth = 1; windowData->textureContainers[i].activeTexture->usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET; + windowData->textureContainers[i].activeTexture->levelCount = 1; + windowData->textureContainers[i].activeTexture->layerCount = 1; + windowData->textureContainers[i].activeTexture->type = SDL_GPU_TEXTURETYPE_2D; windowData->textureContainers[i].activeTexture->container = &windowData->textureContainers[i]; SDL_SetAtomicInt(&windowData->textureContainers[i].activeTexture->referenceCount, 0); From d83e7bf79edfd686020c8ce4a467dfca7a66be6a Mon Sep 17 00:00:00 2001 From: Rachel Blackman Date: Fri, 15 May 2026 13:10:44 -0700 Subject: [PATCH 311/407] Add Gamesir Supernova in Xinput mode to controller list --- src/joystick/controller_list.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index c1d0da9b9f..4c6b54ce02 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -354,6 +354,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x24c6, 0xfafb ), k_eControllerType_XBox360Controller, NULL }, // Aplay Controller { MAKE_CONTROLLER_ID( 0x24c6, 0xfafc ), k_eControllerType_XBox360Controller, NULL }, // Afterglow Gamepad 1 { MAKE_CONTROLLER_ID( 0x24c6, 0xfafd ), k_eControllerType_XBox360Controller, NULL }, // Afterglow Gamepad 3 + { MAKE_CONTROLLER_ID( 0x3537, 0x103e ), k_eControllerType_XBox360Controller, "Gamesir Xbox Controller" }, // Gamesir dongle for Supernova (and maybe others) in Xinput mode { MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller, NULL }, // Rock Candy Gamepad for Xbox 360 { MAKE_CONTROLLER_ID( 0x3651, 0x1000 ), k_eControllerType_XBox360Controller, NULL }, // CRKD Guitar { MAKE_CONTROLLER_ID( 0x3651, 0x6000 ), k_eControllerType_XBox360Controller, NULL }, // CRKD Guitar From 0ffb0bdd87499af6472a20c80728467d11c5826f Mon Sep 17 00:00:00 2001 From: John Schoenick Date: Fri, 15 May 2026 15:29:16 -0700 Subject: [PATCH 312/407] unix: Fix infinite looping in SDL_FriBidi_Process if len > 127 start/end should be FriBidiStrIndex here -- using FriBidiLevel makes them `signed char` and the loop here will become infinite if `end` is > 127. --- src/core/unix/SDL_fribidi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/unix/SDL_fribidi.c b/src/core/unix/SDL_fribidi.c index 4a55133023..4599c974dd 100644 --- a/src/core/unix/SDL_fribidi.c +++ b/src/core/unix/SDL_fribidi.c @@ -84,8 +84,8 @@ char *SDL_FriBidi_Process(SDL_FriBidi *fribidi, char *utf8, ssize_t utf8_len, bo char *result; FriBidiStrIndex len; FriBidiLevel max_level; - FriBidiLevel start; - FriBidiLevel end; + FriBidiStrIndex start; + FriBidiStrIndex end; FriBidiParType direction; FriBidiParType str_direction; unsigned int i; From c00d7b4bf5580462924de5794da50a98fce09b2c Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Fri, 15 May 2026 19:18:38 -0700 Subject: [PATCH 313/407] Add Steam Controller mapping (#15601) Also fixed Hori QAM button mapping --- src/joystick/SDL_gamepad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 319ccc1c73..b88f30e409 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1254,7 +1254,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b12,", sizeof(mapping_string)); } else if (SDL_IsJoystickSteamTriton(vendor, product)) { // Second generation Steam controllers have 4 back paddle buttons - SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18,misc5:b21,misc6:b20", sizeof(mapping_string)); } else if (SDL_IsJoystickNintendoSwitchPro(vendor, product) || SDL_IsJoystickNintendoSwitchProInputOnly(vendor, product)) { // Nintendo Switch Pro controllers have a screenshot button @@ -1278,7 +1278,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) } } else if (SDL_IsJoystickHoriSteamController(vendor, product)) { /* The Wireless HORIPad for Steam has QAM, Steam, Capsense L/R Sticks, 2 rear buttons, and 2 misc buttons */ - SDL_strlcat(mapping_string, "paddle1:b13,paddle2:b12,paddle3:b15,paddle4:b14,misc2:b11,misc3:b16,misc4:b17", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "paddle1:b13,paddle2:b12,paddle3:b15,paddle4:b14,misc1:b11,misc3:b16,misc4:b17", sizeof(mapping_string)); } else if (SDL_IsJoystickFlydigiController(vendor, product)) { SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b12,paddle3:b13,paddle4:b14,", sizeof(mapping_string)); if (guid.data[15] >= SDL_FLYDIGI_VADER2) { From e1d623505edafd7a01523ab39910a3900dd682dc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 May 2026 14:34:41 -0400 Subject: [PATCH 314/407] android: Remove call to mktime() in APK entry parsing. --- src/core/android/SDL_android.c | 41 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index a4c56f92bc..2b90ff03e8 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2027,27 +2027,30 @@ static APKNode *AddAPKDirs(char *path, APKNode *parent) static SDL_Time ZipDosTimeToSDLTime(Uint32 dostime) { - Uint32 dosdate; - struct tm unixtime; - SDL_zero(unixtime); + // Note that DOS-style datetimes in a zip don't have timezone info, etc, + // so these are treated as UTC for lack of a better option. Also, they have + // 2-second precision and the year bits are going to roll over in 2108. + // There are possibly better timestamps in extended fields (!!! FIXME: add + // support for those), but this field is guaranteed to exist with all its + // flaws and is probably Good Enough anyhow. + const Uint32 dosdate = (Uint32) ((dostime >> 16) & 0xFFFF); + const Uint32 dostime16 = dostime & 0xFFFF; - dosdate = (Uint32) ((dostime >> 16) & 0xFFFF); - dostime &= 0xFFFF; + const int m = (int) ((dosdate >> 5) & 0x0F); + const int d = (int) ((dosdate >> 0) & 0x1F) + 1; + const int y = (int) (((dosdate >> 9) & 0x7F) + 1980) - (m <= 2 ? 1 : 0); + const int hour = (int) ((dostime16 >> 11) & 0x1F); + const int minute = (int) ((dostime16 >> 5) & 0x3F); + const int sec = (int) ((dostime16 << 1) & 0x3E); - /* dissect date */ - unixtime.tm_year = ((dosdate >> 9) & 0x7F) + 80; - unixtime.tm_mon = ((dosdate >> 5) & 0x0F) - 1; - unixtime.tm_mday = ((dosdate ) & 0x1F); - - /* dissect time */ - unixtime.tm_hour = ((dostime >> 11) & 0x1F); - unixtime.tm_min = ((dostime >> 5) & 0x3F); - unixtime.tm_sec = ((dostime << 1) & 0x3E); - - /* let mktime calculate daylight savings time. */ - unixtime.tm_isdst = -1; - - return ((SDL_Time) mktime(&unixtime)); + // days since 1/1/1970: https://howardhinnant.github.io/date_algorithms.html#days_from_civil + const int era = ((y >= 0) ? y : (y - 399)) / 400; + const unsigned int yoe = (unsigned int) (y - era * 400); // [0, 399] + const unsigned int doy = (((153 * ((m > 2) ? (m - 3) : (m + 9))) + 2) / 5) + (d - 1); // [0, 365] + const unsigned int doe = (yoe * 365) + (yoe / 4) - (yoe / 100) + doy; // [0, 146096] + const int days = (era * 146097) + ((int) doe) - 719468; + const int seconds = (hour * (60 * 60)) + (minute * 60) + (sec); + return (SDL_Time) (((Sint64) days) * 86400) + seconds; } From 37af10db4d2058a43f44cd35906f8852571e8e11 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 May 2026 14:35:56 -0400 Subject: [PATCH 315/407] android: Support "." and ".." in asset tree paths. Reference Issue #15587. --- src/core/android/SDL_android.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 2b90ff03e8..c8eff1c3d4 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1873,6 +1873,7 @@ typedef struct APKNode { char *name; SDL_PathInfo info; + struct APKNode *parent; struct APKNode *children; struct APKNode *next_sibling; } APKNode; @@ -1891,6 +1892,12 @@ static void FreeAPKNode(APKNode *node) static APKNode *FindAPKChildNode(APKNode *parent, const char *child) { + if ((child[0] == '.') && (child[1] == '\0')) { // "." paths just return the current dir. + return parent; + } else if ((child[0] == '.') && (child[1] == '.') && (child[2] == '\0')) { // ".." paths return the parent dir (or the current dir if at the root). + return parent->parent ? parent->parent : parent; + } + for (APKNode *node = parent->children; node != NULL; node = node->next_sibling) { if (SDL_strcmp(child, node->name) == 0) { return node; @@ -1979,6 +1986,7 @@ static APKNode *AddAPKChildNode(APKNode *parent, const char *child) SDL_copyp(&node->info, &parent->info); // you probably need to update this afterwards. + node->parent = parent; node->next_sibling = parent->children; parent->children = node; } @@ -2009,6 +2017,12 @@ static APKNode *AddAPKDirs(char *path, APKNode *parent) break; // last thing is either an empty string (we ended with a '/'), or an actual file's name, so drop it. } + if ((path[0] == '.') && ((path[1] == '\0') || ((path[1] == '.') ||(path[2] == '\0')))) + // whoa, there's a "." or ".." subdir in a zip entry's path? Fail! + SDL_SetError("bogus file path in APK file entry"); + return NULL; + } + *ptr = '\0'; // terminate on the end of this subdir's name. APKNode *node = AddAPKChildNode(parent, path); *ptr = '/'; From 4910498820a9f6399857a6f0d757bbf287116801 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 May 2026 00:48:00 -0400 Subject: [PATCH 316/407] android: EnumerateDirectory and GetPathInfo should fail for a path of "". Otherwise, this will get appended to the internal storage path, etc, making a real directory when it shouldn't. Reference Issue #15587. --- src/filesystem/posix/SDL_sysfsops.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index 35ee29e246..41dbf63344 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -45,7 +45,9 @@ bool SDL_SYS_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback char *apath = NULL; // absolute path (for Android, iOS, etc). Overrides `path`. #if defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_IOS) - if (*path != '/') { + if (*path == '\0') { + return SDL_SetError("No such file or directory"); + } else if (*path != '/') { #ifdef SDL_PLATFORM_ANDROID if (SDL_strncmp(path, "assets://", 9) == 0) { char *pathwithsep = NULL; @@ -348,7 +350,9 @@ bool SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info) int rc; #ifdef SDL_PLATFORM_ANDROID - if (*path == '/') { + if (*path == '\0') { + return SDL_SetError("No such file or directory"); + } else if (*path == '/') { rc = stat(path, &statbuf); } else if (SDL_strncmp(path, "assets://", 9) == 0) { return Android_JNI_GetAssetPathInfo(path, info); From e972e6a01ba308c90f17ecf111485b762c450efe Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 09:08:08 +0300 Subject: [PATCH 317/407] core/android/SDL_android.c (AddAPKDirs): add missing opening brace fixes build errors --- src/core/android/SDL_android.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index c8eff1c3d4..5b886b0ff3 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2017,7 +2017,7 @@ static APKNode *AddAPKDirs(char *path, APKNode *parent) break; // last thing is either an empty string (we ended with a '/'), or an actual file's name, so drop it. } - if ((path[0] == '.') && ((path[1] == '\0') || ((path[1] == '.') ||(path[2] == '\0')))) + if ((path[0] == '.') && ((path[1] == '\0') || ((path[1] == '.') ||(path[2] == '\0')))) { // whoa, there's a "." or ".." subdir in a zip entry's path? Fail! SDL_SetError("bogus file path in APK file entry"); return NULL; From 880ddb9ca3f8e78e257cf0e534d5245fad4d47e3 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 08:44:40 +0300 Subject: [PATCH 318/407] SDL_dinputhaptic.c, SDL_dinputjoystick.c: replace %lu usage with new cygwin-friendly macros. --- src/haptic/windows/SDL_dinputhaptic.c | 2 +- src/joystick/windows/SDL_dinputjoystick.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haptic/windows/SDL_dinputhaptic.c b/src/haptic/windows/SDL_dinputhaptic.c index fa374e4301..ce0bd30969 100644 --- a/src/haptic/windows/SDL_dinputhaptic.c +++ b/src/haptic/windows/SDL_dinputhaptic.c @@ -90,7 +90,7 @@ bool SDL_DINPUT_HapticInit(void) instance = GetModuleHandle(NULL); if (!instance) { SDL_SYS_HapticQuit(); - return SDL_SetError("GetModuleHandle() failed with error code %lu.", + return SDL_SetError("GetModuleHandle() failed with error code %" SDL_PRIuULONG ".", GetLastError()); } ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index b720288ef3..e9a8527807 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -431,7 +431,7 @@ bool SDL_DINPUT_JoystickInit(void) if (!instance) { IDirectInput8_Release(dinput); dinput = NULL; - return SDL_SetError("GetModuleHandle() failed with error code %lu.", GetLastError()); + return SDL_SetError("GetModuleHandle() failed with error code %" SDL_PRIuULONG ".", GetLastError()); } result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); From 774506c2b7ba6067c2b2cf29514f8b55cf925ee1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 08:44:56 +0300 Subject: [PATCH 319/407] SDL_opengl.h: clean-up SDL's cygwin customization. --- include/SDL3/SDL_opengl.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_opengl.h b/include/SDL3/SDL_opengl.h index d76764b253..baff172466 100644 --- a/include/SDL3/SDL_opengl.h +++ b/include/SDL3/SDL_opengl.h @@ -31,6 +31,10 @@ #include +#if defined(SDL_PLATFORM_CYGWIN) && !defined(USE_OPENGL32) +#define USE_OPENGL32 1 /* use native windows opengl32 */ +#endif + #ifndef SDL_PLATFORM_IOS /* No OpenGL on iOS. */ /* @@ -84,7 +88,7 @@ # else # define GLAPIENTRY __stdcall # endif -#elif defined(__CYGWIN__) /* && defined(USE_OPENGL32) */ /* use native windows opengl32 */ +#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ # define GLAPI extern # define GLAPIENTRY __stdcall #elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) From 3ba4b6b28eef3a5c8c6daa4c98061833efc8d35d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 14:55:50 +0300 Subject: [PATCH 320/407] SDL_gpu_d3d12.c: fix cygwin -Wformat-warnings --- src/gpu/d3d12/SDL_gpu_d3d12.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 2b65006d21..e7fefa3e81 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -135,6 +135,8 @@ #ifdef _WIN32 #define HRESULT_FMT "(0x%08lX)" +#elif defined(__CYGWIN__) && !defined(_LP64) +#define HRESULT_FMT "(0x%08lX)" #else #define HRESULT_FMT "(0x%08X)" #endif From 072b2b74c793eb0e5d7925ad0fcdeb3afd712949 Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Fri, 24 Apr 2026 11:08:40 -0400 Subject: [PATCH 321/407] fix tooltips not showing on KDE --- src/tray/unix/SDL_dbustray.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tray/unix/SDL_dbustray.c b/src/tray/unix/SDL_dbustray.c index 3a015d55d7..6ce7faa310 100644 --- a/src/tray/unix/SDL_dbustray.c +++ b/src/tray/unix/SDL_dbustray.c @@ -211,8 +211,8 @@ static DBusHandlerResult TrayHandleGetAllProps(SDL_Tray *tray, SDL_TrayDBus *tra driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(iiay)", &array_iter); driver->dbus->message_iter_close_container(&struct_iter, &array_iter); - driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &tray_dbus->tooltip); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_close_container(&variant_iter, &struct_iter); driver->dbus->message_iter_close_container(&entry_iter, &variant_iter); driver->dbus->message_iter_close_container(&dict_iter, &entry_iter); @@ -311,8 +311,8 @@ static DBusHandlerResult TrayHandleGetProp(SDL_Tray *tray, SDL_TrayDBus *tray_db driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(iiay)", &array_iter); driver->dbus->message_iter_close_container(&struct_iter, &array_iter); - driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &tray_dbus->tooltip); + driver->dbus->message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &empty); driver->dbus->message_iter_close_container(&variant_iter, &struct_iter); driver->dbus->message_iter_close_container(&iter, &variant_iter); } else if (!SDL_strcmp(property, "WindowId")) { From 2ebf23014f8e170ae7df48c51bb72a3644eec16b Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Sat, 16 May 2026 09:04:20 -0700 Subject: [PATCH 322/407] Add Steam Deck capacitive touch sticks, trackpad clicks, and mapping (#15612) --- src/joystick/SDL_gamepad.c | 3 +++ src/joystick/SDL_gamepad_db.h | 2 +- src/joystick/hidapi/SDL_hidapi_steamdeck.c | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index b88f30e409..3b0b86fdfb 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1252,6 +1252,9 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) if (SDL_IsJoystickSteamController(vendor, product)) { // Steam controllers have 2 back paddle buttons SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b12,", sizeof(mapping_string)); + } else if (SDL_IsJoystickSteamDeck(vendor, product)) { + // The Steam Deck's built-in controller has QAM, 4 back buttons, L/R trackpads, and L/R capacitive touch sticks + SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18", sizeof(mapping_string)); } else if (SDL_IsJoystickSteamTriton(vendor, product)) { // Second generation Steam controllers have 4 back paddle buttons SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18,misc5:b21,misc6:b20", sizeof(mapping_string)); diff --git a/src/joystick/SDL_gamepad_db.h b/src/joystick/SDL_gamepad_db.h index 5d52ca9d33..5859e6d373 100644 --- a/src/joystick/SDL_gamepad_db.h +++ b/src/joystick/SDL_gamepad_db.h @@ -723,7 +723,7 @@ static const char *s_GamepadMappings[] = { "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", - "03000000de2800000512000000016800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000de2800000512000000016800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,", "03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", diff --git a/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/src/joystick/hidapi/SDL_hidapi_steamdeck.c index 018ce00d91..92ca8402a9 100644 --- a/src/joystick/hidapi/SDL_hidapi_steamdeck.c +++ b/src/joystick/hidapi/SDL_hidapi_steamdeck.c @@ -39,6 +39,10 @@ enum SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, + SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_TOUCHPAD, + SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_TOUCHPAD, + SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_JOYSTICK_TOUCH, + SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_JOYSTICK_TOUCH, SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS, }; @@ -68,6 +72,8 @@ typedef enum STEAMDECK_HBUTTON_L4 = 0x00000200, STEAMDECK_HBUTTON_R4 = 0x00000400, + STEAMDECK_HBUTTON_LSTICK_TOUCH = 0x00004000, + STEAMDECK_HBUTTON_RSTICK_TOUCH = 0x00008000, STEAMDECK_HBUTTON_QAM = 0x00040000, } SteamDeckButtons; @@ -191,6 +197,16 @@ static void HIDAPI_DriverSteamDeck_HandleState(SDL_HIDAPI_Device *device, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_TOUCHPAD, + ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_RIGHT_PAD) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_TOUCHPAD, + ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_LEFT_PAD) != 0)); + + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_JOYSTICK_TOUCH, + ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_RSTICK_TOUCH) != 0)); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_JOYSTICK_TOUCH, + ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_LSTICK_TOUCH) != 0)); + if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) { hat |= SDL_HAT_UP; } From 497b2118ba68019fd4c105129b7cf4888a46386d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 May 2026 15:26:47 -0400 Subject: [PATCH 323/407] android: Don't forbid paths of "" in the APK assets tree. This would make `SDL_EnumerateDirectory("assets://")` fail. We check for empty strings at the higher level already, before we strip out the "assets://" prefix to pass through the tree. --- src/core/android/SDL_android.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 5b886b0ff3..7e97794cb3 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1910,10 +1910,6 @@ static const APKNode *FindAPKNode(const char *constpath) { //SDL_Log("FindAPKNode('%s') ...", constpath); - if (*constpath == '\0') { // don't allow paths of "". - return NULL; - } - if (SDL_strncmp(constpath, "assets://", 9) == 0) { constpath += 9; } From 5e483dc16626b937f24bc10c90dedf8e1e92003e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 May 2026 15:29:46 -0400 Subject: [PATCH 324/407] android: Build the APK asset tree in the same order its listed in the file. This tends to get you enumerations in alphabetical order, instead of them being reverse-alphabetical. Reference Issue #15587. --- src/core/android/SDL_android.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 7e97794cb3..aada458481 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1875,6 +1875,7 @@ typedef struct APKNode SDL_PathInfo info; struct APKNode *parent; struct APKNode *children; + struct APKNode *children_tail; struct APKNode *next_sibling; } APKNode; @@ -1983,8 +1984,12 @@ static APKNode *AddAPKChildNode(APKNode *parent, const char *child) SDL_copyp(&node->info, &parent->info); // you probably need to update this afterwards. node->parent = parent; - node->next_sibling = parent->children; - parent->children = node; + if (parent->children_tail) { // APKs tend to be sorted alphabetically, so insert new nodes at the end of the list to maintain this order. + parent->children_tail->next_sibling = node; + } else { + parent->children = node; + } + parent->children_tail = node; } return node; } From 060b74a6647229991d9d4ec310e827782dc4ae28 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 16 May 2026 17:07:56 -0500 Subject: [PATCH 325/407] mouse: Restrict GCMouse to macOS Sonoma and later --- docs/README-macos.md | 4 ++-- src/video/cocoa/SDL_cocoamouse.m | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/README-macos.md b/docs/README-macos.md index 79b3a4f868..ea8d14a9d9 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -253,14 +253,14 @@ Functionality may be added in the future to help this. ## Raw Mouse Input -On macOS 11.0 (Big Sur) and later, SDL uses the Game Controller framework's +On macOS 14.0 (Sonoma) and later, SDL uses the Game Controller framework's GCMouse API to provide raw, unaccelerated mouse input in relative mode. This is ideal for games and applications requiring precise 1:1 mouse movement. On older macOS versions, SDL falls back to NSEvent-based mouse input, which includes system mouse acceleration. -To use accelerated (system-scaled) mouse movement on macOS 11.0+, set the hint: +To use accelerated (system-scaled) mouse movement on macOS 14.0+, set the hint: ```c SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "1"); diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 1cfd23ad3f..21a4f03f0f 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -452,7 +452,10 @@ static void Cocoa_OnGCMouseDisconnected(GCMouse *mouse) void Cocoa_InitGCMouse(void) { @autoreleasepool { - if (@available(macOS 11.0, *)) { + // These APIs are available starting in macOS Big Sur, but we don't enable + // GCMouse until Sonoma due to broken motion and button events on MacBooks + // running Monterey and Ventura. + if (@available(macOS 14.0, *)) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; cocoa_mouse_connect_observer = [center @@ -494,7 +497,7 @@ bool Cocoa_HasGCMouse(void) void Cocoa_QuitGCMouse(void) { @autoreleasepool { - if (@available(macOS 11.0, *)) { + if (@available(macOS 14.0, *)) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; if (cocoa_mouse_connect_observer) { From db7ac820f9c95dd75c7b71e6d37231534b6c13c5 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 16 May 2026 14:21:31 -0700 Subject: [PATCH 326/407] emscripten: Fix crash on Safari when probing gamepad rumble support Safari's older Gamepad API exposes `vibrationActuator` with `playEffect` and `reset` but no `effects` enumeration array. The probe added in 651136ac7 dereferences `vibrationActuator['effects']['includes']` unconditionally, throwing `TypeError: undefined is not an object` on every Safari client that opens a connected gamepad. Add the missing `['effects']` null check so the probe returns false on Safari instead of aborting. --- src/joystick/emscripten/SDL_sysjoystick.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index adf471a199..627a329594 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -506,7 +506,7 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) item->rumble_available = MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; - return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects']['includes']('dual-rumble'); + return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects'] && gamepad['vibrationActuator']['effects']['includes']('dual-rumble'); }, item->index); if (item->rumble_available) { @@ -515,7 +515,7 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) item->trigger_rumble_available = MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; - return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects']['includes']('trigger-rumble'); + return gamepad && gamepad['vibrationActuator'] && gamepad['vibrationActuator']['effects'] && gamepad['vibrationActuator']['effects']['includes']('trigger-rumble'); }, item->index); if (item->trigger_rumble_available) { From 203800565765caec4359d1e5b63c61a980b45c72 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 5 May 2026 19:00:45 +0200 Subject: [PATCH 327/407] video: don't use NEON blitters when SDL_HasNEON returns false --- src/video/SDL_blit_A.c | 10 ++++------ src/video/SDL_blit_N.c | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 0dcd25d885..ea94d6affc 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1533,17 +1533,15 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) } #endif #if defined(SDL_NEON_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) - // To prevent "unused function" compiler warnings/errors - (void)Blit8888to8888PixelAlpha; - (void)Blit8888to8888PixelAlphaSwizzle; - return Blit8888to8888PixelAlphaSwizzleNEON; -#else + if (SDL_HasNEON()) { + return Blit8888to8888PixelAlphaSwizzleNEON; + } +#endif if (sf->format == df->format) { return Blit8888to8888PixelAlpha; } else { return Blit8888to8888PixelAlphaSwizzle; } -#endif } return BlitNtoNPixelAlpha; diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index b014d4233a..5958374c8f 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -3127,7 +3127,9 @@ SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface) } #endif #if defined(SDL_NEON_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) - return Blit8888to8888PixelSwizzleNEON; + if (SDL_HasNEON()) { + return Blit8888to8888PixelSwizzleNEON; + } #endif } #if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) From 71979477c7cb584f2bfa0bd87e9b2db4bbca25fb Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sun, 17 May 2026 04:24:50 +0200 Subject: [PATCH 328/407] include: add sve2 to documentation of SDL_HINT_CPU_FEATURE_MASK --- include/SDL3/SDL_hints.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 225b0cc1b1..82f04e6d85 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -675,6 +675,7 @@ extern "C" { * - "avx512f" * - "arm-simd" * - "neon" + * - "sve2" * - "lsx" * - "lasx" * From 2cd5cd2a42318fe97c8a99d6141cdb59d398875f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 14:56:32 +0300 Subject: [PATCH 329/407] cygwin: patch egl/opengles headers for EGLAPIENTRY --- include/SDL3/SDL_egl.h | 2 ++ src/video/khronos/KHR/khrplatform.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/SDL3/SDL_egl.h b/include/SDL3/SDL_egl.h index 1371c4d012..2690e9c21c 100644 --- a/include/SDL3/SDL_egl.h +++ b/include/SDL3/SDL_egl.h @@ -164,6 +164,8 @@ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall +#elif defined(__CYGWIN__) /* __CYGWIN__ added by SDL */ +# define KHRONOS_APIENTRY __stdcall #else # define KHRONOS_APIENTRY #endif diff --git a/src/video/khronos/KHR/khrplatform.h b/src/video/khronos/KHR/khrplatform.h index 01646449ca..ce63eee076 100644 --- a/src/video/khronos/KHR/khrplatform.h +++ b/src/video/khronos/KHR/khrplatform.h @@ -122,6 +122,8 @@ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall +#elif defined(__CYGWIN__) /* __CYGWIN__ added by SDL */ +# define KHRONOS_APIENTRY __stdcall #else # define KHRONOS_APIENTRY #endif From b24feafaa2c7fb6078783113bae1488dd4104fde Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 14:56:40 +0300 Subject: [PATCH 330/407] cygwin: patch vulkan headers for VKAPI_CALL and enable vulkan in cmake --- CMakeLists.txt | 2 +- src/video/khronos/vulkan/vk_platform.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 824f82448a..d38f667724 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,7 +378,7 @@ dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SD dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF) dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF) dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF) -dep_option(SDL_VULKAN "Enable Vulkan support" "${SDL_VULKAN_DEFAULT}" "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS" OFF) +dep_option(SDL_VULKAN "Enable Vulkan support" "${SDL_VULKAN_DEFAULT}" "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR OPENBSD OR WINDOWS OR CYGWIN" OFF) dep_option(SDL_RENDER_VULKAN "Enable the Vulkan render driver" ON "SDL_RENDER;SDL_VULKAN" OFF) dep_option(SDL_METAL "Enable Metal support" ON "APPLE" OFF) set_option(SDL_OPENVR "Use OpenVR video driver" OFF) diff --git a/src/video/khronos/vulkan/vk_platform.h b/src/video/khronos/vulkan/vk_platform.h index 0ecd4f6471..7d3ecfd277 100644 --- a/src/video/khronos/vulkan/vk_platform.h +++ b/src/video/khronos/vulkan/vk_platform.h @@ -36,7 +36,7 @@ extern "C" * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); */ -#if defined(_WIN32) +#if defined(_WIN32) || defined(__CYGWIN__) /* __CYGWIN__ added by SDL */ // On Windows, Vulkan commands use the stdcall convention #define VKAPI_ATTR #define VKAPI_CALL __stdcall From a34b35a382bffcd430465e273264021fb0f2fab1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 16 May 2026 22:11:28 +0300 Subject: [PATCH 331/407] cygwin, test/cmake: hard-code opengl as native opengl32. FindOpenGL from cmake >= 3.19, or cygwin-provided cmake versions don't test for native windows opengl32, but we want native windows opengl32. --- test/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c5a416e61..5166688ae9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,12 +35,19 @@ else() endif() set(HAVE_TESTS_LINK_SHARED "${SDL_TESTS_LINK_SHARED}" PARENT_SCOPE) +if(CYGWIN) +# FindOpenGL from cmake >= 3.19 or cygwin-provided cmake versions don't +# test for native windows opengl32, but we want native windows opengl32. + set(OPENGL_gl_LIBRARY opengl32) + set(OPENGL_FOUND TRUE) +else() # CMake incorrectly detects opengl32.lib being present on MSVC ARM64 if(NOT (MSVC AND SDL_CPU_ARM64)) # Prefer GLVND, if present set(OpenGL_GL_PREFERENCE GLVND) find_package(OpenGL) endif() +endif() add_library(sdltests_utils OBJECT testutils.c From d4fa4b46346b973014bb54f60f6c8067b03251e7 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 11:50:10 +0300 Subject: [PATCH 332/407] SDL_opengles2_khrplatform.h: add cygwin bit missed in commit 2cd5cd2a. --- include/SDL3/SDL_opengles2_khrplatform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/SDL3/SDL_opengles2_khrplatform.h b/include/SDL3/SDL_opengles2_khrplatform.h index 01646449ca..ce63eee076 100644 --- a/include/SDL3/SDL_opengles2_khrplatform.h +++ b/include/SDL3/SDL_opengles2_khrplatform.h @@ -122,6 +122,8 @@ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall +#elif defined(__CYGWIN__) /* __CYGWIN__ added by SDL */ +# define KHRONOS_APIENTRY __stdcall #else # define KHRONOS_APIENTRY #endif From 1f7a42a7b91dc4cbd5879d6ac52f84fc4d5710c3 Mon Sep 17 00:00:00 2001 From: Tap Date: Sun, 17 May 2026 12:04:45 +1000 Subject: [PATCH 333/407] Correct steam triton haptic commands The listed report IDs are incorrect - there is no skipped ID --- src/joystick/hidapi/steam/controller_structs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/hidapi/steam/controller_structs.h b/src/joystick/hidapi/steam/controller_structs.h index 365bc73f9b..b0f86ea32b 100644 --- a/src/joystick/hidapi/steam/controller_structs.h +++ b/src/joystick/hidapi/steam/controller_structs.h @@ -228,8 +228,8 @@ typedef enum ID_OUT_REPORT_HAPTIC_PULSE = 0x81, ID_OUT_REPORT_HAPTIC_COMMAND = 0x82, ID_OUT_REPORT_HAPTIC_LFO_TONE = 0x83, - ID_OUT_REPORT_HAPTIC_LOG_SWEEP = 0x85, - ID_OUT_REPORT_HAPTIC_SCRIPT = 0x86, + ID_OUT_REPORT_HAPTIC_LOG_SWEEP = 0x84, + ID_OUT_REPORT_HAPTIC_SCRIPT = 0x85, } ValveTritonOutReportMessageIDs; typedef struct From 75c94e9b3189a40615b74f6484cb226fc0c4a72d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 11:55:40 +0300 Subject: [PATCH 334/407] SDL_opengl_glext.h, src/video/directx/d3d12.h: revert unintended changes from commit d70578b9aac --- include/SDL3/SDL_opengl_glext.h | 40 +++++++++++----------- src/video/directx/SDL_d3d12_xbox_cmacros.h | 4 +-- src/video/directx/d3d12.h | 10 +++--- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/SDL3/SDL_opengl_glext.h b/include/SDL3/SDL_opengl_glext.h index fa0f6c2a5b..ff6ad12cef 100644 --- a/include/SDL3/SDL_opengl_glext.h +++ b/include/SDL3/SDL_opengl_glext.h @@ -9807,15 +9807,15 @@ typedef void (APIENTRYP PFNGLUPLOADGPUMASKNVXPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC) (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); typedef void (APIENTRYP PFNGLMULTICASTSCISSORARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLint *v); -typedef GLuint (APIENTRYP PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGPU, GLbitfield writeGPUMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); -typedef GLuint (APIENTRYP PFNGLASYNCCOPYIMAGESUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGPU, GLbitfield dstGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +typedef GLuint (APIENTRYP PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +typedef GLuint (APIENTRYP PFNGLASYNCCOPYIMAGESUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUploadGPUMaskNVX (GLbitfield mask); +GLAPI void APIENTRY glUploadGpuMaskNVX (GLbitfield mask); GLAPI void APIENTRY glMulticastViewportArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glMulticastViewportPositionWScaleNVX (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); GLAPI void APIENTRY glMulticastScissorArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLint *v); -GLAPI GLuint APIENTRY glAsyncCopyBufferSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGPU, GLbitfield writeGPUMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); -GLAPI GLuint APIENTRY glAsyncCopyImageSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGPU, GLbitfield dstGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +GLAPI GLuint APIENTRY glAsyncCopyBufferSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +GLAPI GLuint APIENTRY glAsyncCopyImageSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); #endif #endif /* GL_NVX_gpu_multicast2 */ @@ -9824,11 +9824,11 @@ GLAPI GLuint APIENTRY glAsyncCopyImageSubDataNVX (GLsizei waitSemaphoreCount, co #define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 #define GL_MAX_LGPU_GPUS_NVX 0x92BA typedef void (APIENTRYP PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGPU, GLbitfield destinationGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLLGPUINTERLOCKNVXPROC) (void); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLGPUNamedBufferSubDataNVX (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glLGPUCopyImageSubDataNVX (GLuint sourceGPU, GLbitfield destinationGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glLGPUCopyImageSubDataNVX (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glLGPUInterlockNVX (void); #endif #endif /* GL_NVX_linked_gpu_multicast */ @@ -9836,13 +9836,13 @@ GLAPI void APIENTRY glLGPUInterlockNVX (void); #ifndef GL_NVX_progress_fence #define GL_NVX_progress_fence 1 typedef GLuint (APIENTRYP PFNGLCREATEPROGRESSFENCENVXPROC) (void); -typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREUI64NVXPROC) (GLuint signalGPU, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); -typedef void (APIENTRYP PFNGLWAITSEMAPHOREUI64NVXPROC) (GLuint waitGPU, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREUI64NVXPROC) (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +typedef void (APIENTRYP PFNGLWAITSEMAPHOREUI64NVXPROC) (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); typedef void (APIENTRYP PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC) (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glCreateProgressFenceNVX (void); -GLAPI void APIENTRY glSignalSemaphoreui64NVX (GLuint signalGPU, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); -GLAPI void APIENTRY glWaitSemaphoreui64NVX (GLuint waitGPU, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +GLAPI void APIENTRY glSignalSemaphoreui64NVX (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +GLAPI void APIENTRY glWaitSemaphoreui64NVX (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); GLAPI void APIENTRY glClientWaitSemaphoreui64NVX (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); #endif #endif /* GL_NVX_progress_fence */ @@ -10433,25 +10433,25 @@ GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachmen #define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 typedef void (APIENTRYP PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGPU, GLbitfield writeGPUMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGPU, GLbitfield dstGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -typedef void (APIENTRYP PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGPU, GLuint dstGPU, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef void (APIENTRYP PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTICASTBARRIERNVPROC) (void); -typedef void (APIENTRYP PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGPU, GLbitfield waitGPUMask); +typedef void (APIENTRYP PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask); typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderGPUMaskNV (GLbitfield mask); +GLAPI void APIENTRY glRenderGpuMaskNV (GLbitfield mask); GLAPI void APIENTRY glMulticastBufferSubDataNV (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glMulticastCopyBufferSubDataNV (GLuint readGPU, GLbitfield writeGPUMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glMulticastCopyImageSubDataNV (GLuint srcGPU, GLbitfield dstGPUMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -GLAPI void APIENTRY glMulticastBlitFramebufferNV (GLuint srcGPU, GLuint dstGPU, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glMulticastCopyBufferSubDataNV (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glMulticastCopyImageSubDataNV (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glMulticastBlitFramebufferNV (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); GLAPI void APIENTRY glMulticastFramebufferSampleLocationsfvNV (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glMulticastBarrierNV (void); -GLAPI void APIENTRY glMulticastWaitSyncNV (GLuint signalGPU, GLbitfield waitGPUMask); +GLAPI void APIENTRY glMulticastWaitSyncNV (GLuint signalGpu, GLbitfield waitGpuMask); GLAPI void APIENTRY glMulticastGetQueryObjectivNV (GLuint gpu, GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glMulticastGetQueryObjectuivNV (GLuint gpu, GLuint id, GLenum pname, GLuint *params); GLAPI void APIENTRY glMulticastGetQueryObjecti64vNV (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); diff --git a/src/video/directx/SDL_d3d12_xbox_cmacros.h b/src/video/directx/SDL_d3d12_xbox_cmacros.h index fc6df35eba..aa9e4ce2b9 100644 --- a/src/video/directx/SDL_d3d12_xbox_cmacros.h +++ b/src/video/directx/SDL_d3d12_xbox_cmacros.h @@ -691,8 +691,8 @@ ( (This)->Wait(pFence,Value) ) #define ID3D12CommandQueue_GetTimestampFrequency(This,pFrequency) \ ( (This)->GetTimestampFrequency(pFrequency) ) -#define ID3D12CommandQueue_GetClockCalibration(This,pGPUTimestamp,pCpuTimestamp) \ - ( (This)->GetClockCalibration(pGPUTimestamp,pCpuTimestamp) ) +#define ID3D12CommandQueue_GetClockCalibration(This,pGpuTimestamp,pCpuTimestamp) \ + ( (This)->GetClockCalibration(pGpuTimestamp,pCpuTimestamp) ) #define ID3D12Device_QueryInterface(This,riid,ppvObject) \ ( (This)->QueryInterface(riid,ppvObject) ) #define ID3D12Device_AddRef(This) \ diff --git a/src/video/directx/d3d12.h b/src/video/directx/d3d12.h index eac7fbbf3f..e670c3cd46 100644 --- a/src/video/directx/d3d12.h +++ b/src/video/directx/d3d12.h @@ -8670,7 +8670,7 @@ EXTERN_C const IID IID_ID3D12CommandQueue; _Out_ UINT64 *pFrequency) = 0; virtual HRESULT STDMETHODCALLTYPE GetClockCalibration( - _Out_ UINT64 *pGPUTimestamp, + _Out_ UINT64 *pGpuTimestamp, _Out_ UINT64 *pCpuTimestamp) = 0; #if defined(_MSC_VER) || !defined(_WIN32) @@ -8802,7 +8802,7 @@ EXTERN_C const IID IID_ID3D12CommandQueue; DECLSPEC_XFGVIRT(ID3D12CommandQueue, GetClockCalibration) HRESULT ( STDMETHODCALLTYPE *GetClockCalibration )( ID3D12CommandQueue * This, - _Out_ UINT64 *pGPUTimestamp, + _Out_ UINT64 *pGpuTimestamp, _Out_ UINT64 *pCpuTimestamp); DECLSPEC_XFGVIRT(ID3D12CommandQueue, GetDesc) @@ -8885,8 +8885,8 @@ EXTERN_C const IID IID_ID3D12CommandQueue; #define ID3D12CommandQueue_GetTimestampFrequency(This,pFrequency) \ ( (This)->lpVtbl -> GetTimestampFrequency(This,pFrequency) ) -#define ID3D12CommandQueue_GetClockCalibration(This,pGPUTimestamp,pCpuTimestamp) \ - ( (This)->lpVtbl -> GetClockCalibration(This,pGPUTimestamp,pCpuTimestamp) ) +#define ID3D12CommandQueue_GetClockCalibration(This,pGpuTimestamp,pCpuTimestamp) \ + ( (This)->lpVtbl -> GetClockCalibration(This,pGpuTimestamp,pCpuTimestamp) ) #if !defined(_WIN32) #define ID3D12CommandQueue_GetDesc(This) \ @@ -29176,7 +29176,7 @@ DEFINE_ENUM_FLAG_OPERATORS( D3D12_DEVICE_FLAGS ) typedef struct D3D12_DEVICE_CONFIGURATION_DESC { D3D12_DEVICE_FLAGS Flags; - UINT GPUBasedValidationFlags; + UINT GpuBasedValidationFlags; UINT SDKVersion; UINT NumEnabledExperimentalFeatures; } D3D12_DEVICE_CONFIGURATION_DESC; From 968b0c6910b622bf63253d2847e67bc7fd30516d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 11:55:50 +0300 Subject: [PATCH 335/407] update gl/egl headers from khronos. --- include/SDL3/SDL_egl.h | 63 ++++++++- include/SDL3/SDL_opengl_glext.h | 198 ++++++++++++++++++++++++---- include/SDL3/SDL_opengles2_gl2.h | 4 +- include/SDL3/SDL_opengles2_gl2ext.h | 191 ++++++++++++++++++++++++++- src/video/khronos/EGL/egl.h | 4 +- src/video/khronos/EGL/eglext.h | 27 +++- src/video/khronos/GLES2/gl2.h | 4 +- src/video/khronos/GLES2/gl2ext.h | 119 ++++++++++++++++- src/video/khronos/GLES3/gl3.h | 4 +- src/video/khronos/GLES3/gl31.h | 20 +-- src/video/khronos/GLES3/gl32.h | 20 +-- 11 files changed, 591 insertions(+), 63 deletions(-) diff --git a/include/SDL3/SDL_egl.h b/include/SDL3/SDL_egl.h index 2690e9c21c..60c0f15e9a 100644 --- a/include/SDL3/SDL_egl.h +++ b/include/SDL3/SDL_egl.h @@ -421,7 +421,13 @@ typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; -#elif defined(SDL_PLATFORM_EMSCRIPTEN) +#elif defined(__QNX__) + +typedef khronos_uintptr_t EGLNativeDisplayType; +typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */ +typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */ + +#elif defined(__EMSCRIPTEN__) typedef int EGLNativeDisplayType; typedef int EGLNativePixmapType; @@ -542,7 +548,7 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $ +** Khronos $Git commit SHA1: e80a2e0050 $ on $Git commit date: 2026-03-19 06:21:49 +0100 $ */ /*#include */ @@ -551,7 +557,7 @@ extern "C" { #define EGL_EGL_PROTOTYPES 1 #endif -/* Generated on date 20220525 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: egl @@ -886,12 +892,12 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $ +** Khronos $Git commit SHA1: e80a2e0050 $ on $Git commit date: 2026-03-19 06:21:49 +0100 $ */ /*#include */ -#define EGL_EGLEXT_VERSION 20220525 +#define EGL_EGLEXT_VERSION 20260319 /* Generated C header for: * API: egl @@ -1423,6 +1429,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSur #define EGL_RECORDABLE_ANDROID 0x3142 #endif /* EGL_ANDROID_recordable */ +#ifndef EGL_ANDROID_telemetry_hint +#define EGL_ANDROID_telemetry_hint 1 +#define EGL_TELEMETRY_HINT_ANDROID 0x3570 +#endif /* EGL_ANDROID_telemetry_hint */ + #ifndef EGL_ANGLE_d3d_share_handle_client_buffer #define EGL_ANGLE_d3d_share_handle_client_buffer 1 #define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 @@ -1595,10 +1606,33 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLi #define EGL_RENDERER_EXT 0x335F #endif /* EGL_EXT_device_query_name */ +#ifndef EGL_EXT_device_type +#define EGL_EXT_device_type 1 +#define EGL_DEVICE_TYPE_EXT 0x3590 +#define EGL_DEVICE_TYPE_OTHER_EXT 0x3591 +#define EGL_DEVICE_TYPE_INTEGRATED_GPU_EXT 0x3592 +#define EGL_DEVICE_TYPE_DISCRETE_GPU_EXT 0x3593 +#define EGL_DEVICE_TYPE_CPU_EXT 0x3594 +#endif /* EGL_EXT_device_type */ + +#ifndef EGL_EXT_display_alloc +#define EGL_EXT_display_alloc 1 +#define EGL_ALLOC_NEW_DISPLAY_EXT 0x3379 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYDISPLAYEXTPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyDisplayEXT (EGLDisplay dpy); +#endif +#endif /* EGL_EXT_display_alloc */ + #ifndef EGL_EXT_explicit_device #define EGL_EXT_explicit_device 1 #endif /* EGL_EXT_explicit_device */ +#ifndef EGL_EXT_gl_colorspace_bt2020_hlg +#define EGL_EXT_gl_colorspace_bt2020_hlg 1 +#define EGL_GL_COLORSPACE_BT2020_HLG_EXT 0x3540 +#endif /* EGL_EXT_gl_colorspace_bt2020_hlg */ + #ifndef EGL_EXT_gl_colorspace_bt2020_linear #define EGL_EXT_gl_colorspace_bt2020_linear 1 #define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F @@ -1795,6 +1829,10 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_EXT_protected_surface 1 #endif /* EGL_EXT_protected_surface */ +#ifndef EGL_EXT_query_reset_notification_strategy +#define EGL_EXT_query_reset_notification_strategy 1 +#endif /* EGL_EXT_query_reset_notification_strategy */ + #ifndef EGL_EXT_stream_consumer_egloutput #define EGL_EXT_stream_consumer_egloutput 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); @@ -2095,6 +2133,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStream #endif #endif /* EGL_NV_stream_consumer_eglimage */ +#ifndef EGL_NV_stream_consumer_eglimage_use_scanout_attrib +#define EGL_NV_stream_consumer_eglimage_use_scanout_attrib 1 +#define EGL_STREAM_CONSUMER_IMAGE_USE_SCANOUT_NV 0x3378 +#endif /* EGL_NV_stream_consumer_eglimage_use_scanout_attrib */ + #ifndef EGL_NV_stream_consumer_gltexture_yuv #define EGL_NV_stream_consumer_gltexture_yuv 1 #define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C @@ -2304,6 +2347,16 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_TRIPLE_BUFFER_NV 0x3230 #endif /* EGL_NV_triple_buffer */ +#ifndef EGL_QNX_image_native_buffer +#define EGL_QNX_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_QNX 0x3551 +#endif /* EGL_QNX_image_native_buffer */ + +#ifndef EGL_QNX_platform_screen +#define EGL_QNX_platform_screen 1 +#define EGL_PLATFORM_SCREEN_QNX 0x3550 +#endif /* EGL_QNX_platform_screen */ + #ifndef EGL_TIZEN_image_native_buffer #define EGL_TIZEN_image_native_buffer 1 #define EGL_NATIVE_BUFFER_TIZEN 0x32A0 diff --git a/include/SDL3/SDL_opengl_glext.h b/include/SDL3/SDL_opengl_glext.h index ff6ad12cef..e09862592f 100644 --- a/include/SDL3/SDL_opengl_glext.h +++ b/include/SDL3/SDL_opengl_glext.h @@ -10,7 +10,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -36,7 +36,7 @@ extern "C" { #define GLAPI extern #endif -#define GL_GLEXT_VERSION 20220530 +#define GL_GLEXT_VERSION 20260319 /*#include */ #ifndef __khrplatform_h_ @@ -5712,12 +5712,12 @@ typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severi typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufSize, GLenum *categories, GLenum *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufSize, GLenum *categories, GLenum *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #endif #endif /* GL_AMD_debug_output */ @@ -7673,6 +7673,47 @@ GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const voi #endif #endif /* GL_EXT_fog_coord */ +#ifndef GL_EXT_fragment_shading_rate +#define GL_EXT_fragment_shading_rate 1 +#define GL_SHADING_RATE_1X1_PIXELS_EXT 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_EXT 0x96A7 +#define GL_SHADING_RATE_2X1_PIXELS_EXT 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_EXT 0x96A9 +#define GL_SHADING_RATE_1X4_PIXELS_EXT 0x96AA +#define GL_SHADING_RATE_4X1_PIXELS_EXT 0x96AB +#define GL_SHADING_RATE_4X2_PIXELS_EXT 0x96AC +#define GL_SHADING_RATE_2X4_PIXELS_EXT 0x96AD +#define GL_SHADING_RATE_4X4_PIXELS_EXT 0x96AE +#define GL_SHADING_RATE_EXT 0x96D0 +#define GL_SHADING_RATE_ATTACHMENT_EXT 0x96D1 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT 0x96D2 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT 0x96D3 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT 0x96D4 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT 0x96D5 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT 0x96D6 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D7 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D8 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96D9 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96DA +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT 0x96DB +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT 0x96DC +#define GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT 0x96DD +#define GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT 0x96DE +#define GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT 0x96DF +#define GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT 0x8F6F +#define GL_FRAGMENT_SHADING_RATE_PRIMITIVE_RATE_WITH_MULTI_VIEWPORT_SUPPORTED_EXT 0x9780 +typedef void (APIENTRYP PFNGLGETFRAGMENTSHADINGRATESEXTPROC) (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +typedef void (APIENTRYP PFNGLSHADINGRATEEXTPROC) (GLenum rate); +typedef void (APIENTRYP PFNGLSHADINGRATECOMBINEROPSEXTPROC) (GLenum combinerOp0, GLenum combinerOp1); +typedef void (APIENTRYP PFNGLFRAMEBUFFERSHADINGRATEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetFragmentShadingRatesEXT (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +GLAPI void APIENTRY glShadingRateEXT (GLenum rate); +GLAPI void APIENTRY glShadingRateCombinerOpsEXT (GLenum combinerOp0, GLenum combinerOp1); +GLAPI void APIENTRY glFramebufferShadingRateEXT (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#endif +#endif /* GL_EXT_fragment_shading_rate */ + #ifndef GL_EXT_framebuffer_blit #define GL_EXT_framebuffer_blit 1 #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 @@ -7685,6 +7726,16 @@ GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, #endif #endif /* GL_EXT_framebuffer_blit */ +#ifndef GL_EXT_framebuffer_blit_layers +#define GL_EXT_framebuffer_blit_layers 1 +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERLAYERSEXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERLAYEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferLayersEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glBlitFramebufferLayerEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit_layers */ + #ifndef GL_EXT_framebuffer_multisample #define GL_EXT_framebuffer_multisample 1 #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB @@ -8121,6 +8172,86 @@ GLAPI void APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GL #endif #endif /* GL_EXT_memory_object_win32 */ +#ifndef GL_EXT_mesh_shader +#define GL_EXT_mesh_shader 1 +#define GL_MESH_SHADER_EXT 0x9559 +#define GL_TASK_SHADER_EXT 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_EXT 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_EXT 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_EXT 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_EXT 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_EXT 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_EXT 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_EXT 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_EXT 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_EXT 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_EXT 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_EXT 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_EXT 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_EXT 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_EXT 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_EXT 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_EXT 0x8E6F +#define GL_MAX_TASK_WORK_GROUP_TOTAL_COUNT_EXT 0x9740 +#define GL_MAX_MESH_WORK_GROUP_TOTAL_COUNT_EXT 0x9741 +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_EXT 0x9757 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_EXT 0x9759 +#define GL_MAX_TASK_PAYLOAD_SIZE_EXT 0x9742 +#define GL_MAX_TASK_SHARED_MEMORY_SIZE_EXT 0x9743 +#define GL_MAX_MESH_SHARED_MEMORY_SIZE_EXT 0x9744 +#define GL_MAX_TASK_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9745 +#define GL_MAX_MESH_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9746 +#define GL_MAX_MESH_OUTPUT_MEMORY_SIZE_EXT 0x9747 +#define GL_MAX_MESH_PAYLOAD_AND_OUTPUT_MEMORY_SIZE_EXT 0x9748 +#define GL_MAX_MESH_OUTPUT_VERTICES_EXT 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT 0x9756 +#define GL_MAX_MESH_OUTPUT_COMPONENTS_EXT 0x9749 +#define GL_MAX_MESH_OUTPUT_LAYERS_EXT 0x974A +#define GL_MAX_MESH_MULTIVIEW_VIEW_COUNT_EXT 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_EXT 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_EXT 0x9543 +#define GL_MAX_PREFERRED_TASK_WORK_GROUP_INVOCATIONS_EXT 0x974B +#define GL_MAX_PREFERRED_MESH_WORK_GROUP_INVOCATIONS_EXT 0x974C +#define GL_MESH_PREFERS_LOCAL_INVOCATION_VERTEX_OUTPUT_EXT 0x974D +#define GL_MESH_PREFERS_LOCAL_INVOCATION_PRIMITIVE_OUTPUT_EXT 0x974E +#define GL_MESH_PREFERS_COMPACT_VERTEX_OUTPUT_EXT 0x974F +#define GL_MESH_PREFERS_COMPACT_PRIMITIVE_OUTPUT_EXT 0x9750 +#define GL_MAX_TASK_WORK_GROUP_COUNT_EXT 0x9751 +#define GL_MAX_MESH_WORK_GROUP_COUNT_EXT 0x9752 +#define GL_MAX_MESH_WORK_GROUP_SIZE_EXT 0x9758 +#define GL_MAX_TASK_WORK_GROUP_SIZE_EXT 0x975A +#define GL_MESH_WORK_GROUP_SIZE_EXT 0x953E +#define GL_TASK_WORK_GROUP_SIZE_EXT 0x953F +#define GL_MESH_VERTICES_OUT_EXT 0x9579 +#define GL_MESH_PRIMITIVES_OUT_EXT 0x957A +#define GL_MESH_OUTPUT_TYPE_EXT 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_EXT 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_EXT 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_EXT 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_EXT 0x95A1 +#define GL_TASK_SHADER_INVOCATIONS_EXT 0x9753 +#define GL_MESH_SHADER_INVOCATIONS_EXT 0x9754 +#define GL_MESH_PRIMITIVES_GENERATED_EXT 0x9755 +#define GL_MESH_SHADER_BIT_EXT 0x00000040 +#define GL_TASK_SHADER_BIT_EXT 0x00000080 +#define GL_MESH_SUBROUTINE_EXT 0x957C +#define GL_TASK_SUBROUTINE_EXT 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_EXT 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_EXT 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_EXT 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_EXT 0x959F +typedef void (APIENTRYP PFNGLDRAWMESHTASKSEXTPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect); +typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTEXTPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshTasksEXT (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GLAPI void APIENTRY glDrawMeshTasksIndirectEXT (GLintptr indirect); +GLAPI void APIENTRY glMultiDrawMeshTasksIndirectEXT (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountEXT (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_EXT_mesh_shader */ + #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif /* GL_EXT_misc_attribute */ @@ -8882,18 +9013,18 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); #define GL_SRGB8_EXT 0x8C41 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 #define GL_COMPRESSED_SRGB_EXT 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #endif /* GL_EXT_texture_sRGB */ #ifndef GL_EXT_texture_sRGB_R8 @@ -9687,6 +9818,18 @@ GLAPI void APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname #define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD #endif /* GL_MESA_framebuffer_swap_xy */ +#ifndef GL_MESA_map_buffer_client_pointer +#define GL_MESA_map_buffer_client_pointer 1 +#define GL_MAP_CLIENT_POINTER_BIT_MESA 0x4000 +#define GL_BUFFER_CLIENT_POINTER_SIZE_MESA 0x9790 +typedef void (APIENTRYP PFNGLADDCLIENTPOINTERRANGEMESAPROC) (GLvoid *addr, GLsizeiptr size); +typedef void* (APIENTRYP PFNGLRELEASECLIENTPOINTERRANGEMESAPROC) (GLsizeiptr *size); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAddClientPointerRangeMESA (GLvoid *addr, GLsizeiptr size); +GLAPI void* APIENTRY glReleaseClientPointerRangeMESA (GLsizeiptr *size); +#endif +#endif /* GL_MESA_map_buffer_client_pointer */ + #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert 1 #define GL_PACK_INVERT_MESA 0x8758 @@ -9709,6 +9852,11 @@ GLAPI void APIENTRY glResizeBuffersMESA (void); #define GL_MESA_shader_integer_functions 1 #endif /* GL_MESA_shader_integer_functions */ +#ifndef GL_MESA_texture_const_bandwidth +#define GL_MESA_texture_const_bandwidth 1 +#define GL_CONST_BW_TILING_MESA 0x8BBE +#endif /* GL_MESA_texture_const_bandwidth */ + #ifndef GL_MESA_tile_raster_order #define GL_MESA_tile_raster_order 1 #define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8 @@ -10563,12 +10711,6 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); @@ -10581,6 +10723,12 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, c typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); @@ -10610,12 +10758,6 @@ GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); @@ -10628,6 +10770,12 @@ GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfN GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); #endif #endif /* GL_NV_half_float */ @@ -11764,6 +11912,10 @@ GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); #endif #endif /* GL_NV_transform_feedback2 */ +#ifndef GL_NV_uniform_buffer_std430_layout +#define GL_NV_uniform_buffer_std430_layout 1 +#endif /* GL_NV_uniform_buffer_std430_layout */ + #ifndef GL_NV_uniform_buffer_unified_memory #define GL_NV_uniform_buffer_unified_memory 1 #define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E @@ -12279,8 +12431,10 @@ GLAPI void APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum s #define GL_MAX_VIEWS_OVR 0x9631 #define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +GLAPI void APIENTRY glNamedFramebufferTextureMultiviewOVR (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #endif #endif /* GL_OVR_multiview */ diff --git a/include/SDL3/SDL_opengles2_gl2.h b/include/SDL3/SDL_opengles2_gl2.h index d13622aae9..43c9b6ffb5 100644 --- a/include/SDL3/SDL_opengles2_gl2.h +++ b/include/SDL3/SDL_opengles2_gl2.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -25,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20220530 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: gles2 diff --git a/include/SDL3/SDL_opengles2_gl2ext.h b/include/SDL3/SDL_opengles2_gl2ext.h index 9448ce09fc..96e8be78e0 100644 --- a/include/SDL3/SDL_opengles2_gl2ext.h +++ b/include/SDL3/SDL_opengles2_gl2ext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -19,7 +19,7 @@ extern "C" { #define GL_APIENTRYP GL_APIENTRY* #endif -/* Generated on date 20220530 */ +#define GL_GLEXT_VERSION 20260319 /* Generated C header for: * API: gles2 @@ -1052,6 +1052,21 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei #define GL_ARM_rgba8 1 #endif /* GL_ARM_rgba8 */ +#ifndef GL_ARM_shader_core_properties +#define GL_ARM_shader_core_properties 1 +#define GL_SHADER_CORE_COUNT_ARM 0x96F0 +#define GL_SHADER_CORE_ACTIVE_COUNT_ARM 0x96F1 +#define GL_SHADER_CORE_PRESENT_MASK_ARM 0x96F2 +#define GL_SHADER_CORE_MAX_WARP_COUNT_ARM 0x96F3 +#define GL_SHADER_CORE_PIXEL_RATE_ARM 0x96F4 +#define GL_SHADER_CORE_TEXEL_RATE_ARM 0x96F5 +#define GL_SHADER_CORE_FMA_RATE_ARM 0x96F6 +typedef void (GL_APIENTRYP PFNGLMAXACTIVESHADERCORESARMPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMaxActiveShaderCoresARM (GLuint count); +#endif +#endif /* GL_ARM_shader_core_properties */ + #ifndef GL_ARM_shader_framebuffer_fetch #define GL_ARM_shader_framebuffer_fetch 1 #define GL_FETCH_PER_SAMPLE_ARM 0x8F65 @@ -1459,6 +1474,16 @@ GL_APICALL void GL_APIENTRY glFramebufferShadingRateEXT (GLenum target, GLenum a #endif #endif /* GL_EXT_fragment_shading_rate */ +#ifndef GL_EXT_framebuffer_blit_layers +#define GL_EXT_framebuffer_blit_layers 1 +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERLAYERSEXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERLAYEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferLayersEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glBlitFramebufferLayerEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit_layers */ + #ifndef GL_EXT_geometry_point_size #define GL_EXT_geometry_point_size 1 #endif /* GL_EXT_geometry_point_size */ @@ -1612,6 +1637,86 @@ GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 #endif #endif /* GL_EXT_memory_object_win32 */ +#ifndef GL_EXT_mesh_shader +#define GL_EXT_mesh_shader 1 +#define GL_MESH_SHADER_EXT 0x9559 +#define GL_TASK_SHADER_EXT 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_EXT 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_EXT 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_EXT 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_EXT 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_EXT 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_EXT 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_EXT 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_EXT 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_EXT 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_EXT 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_EXT 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_EXT 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_EXT 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_EXT 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_EXT 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_EXT 0x8E6F +#define GL_MAX_TASK_WORK_GROUP_TOTAL_COUNT_EXT 0x9740 +#define GL_MAX_MESH_WORK_GROUP_TOTAL_COUNT_EXT 0x9741 +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_EXT 0x9757 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_EXT 0x9759 +#define GL_MAX_TASK_PAYLOAD_SIZE_EXT 0x9742 +#define GL_MAX_TASK_SHARED_MEMORY_SIZE_EXT 0x9743 +#define GL_MAX_MESH_SHARED_MEMORY_SIZE_EXT 0x9744 +#define GL_MAX_TASK_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9745 +#define GL_MAX_MESH_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9746 +#define GL_MAX_MESH_OUTPUT_MEMORY_SIZE_EXT 0x9747 +#define GL_MAX_MESH_PAYLOAD_AND_OUTPUT_MEMORY_SIZE_EXT 0x9748 +#define GL_MAX_MESH_OUTPUT_VERTICES_EXT 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT 0x9756 +#define GL_MAX_MESH_OUTPUT_COMPONENTS_EXT 0x9749 +#define GL_MAX_MESH_OUTPUT_LAYERS_EXT 0x974A +#define GL_MAX_MESH_MULTIVIEW_VIEW_COUNT_EXT 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_EXT 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_EXT 0x9543 +#define GL_MAX_PREFERRED_TASK_WORK_GROUP_INVOCATIONS_EXT 0x974B +#define GL_MAX_PREFERRED_MESH_WORK_GROUP_INVOCATIONS_EXT 0x974C +#define GL_MESH_PREFERS_LOCAL_INVOCATION_VERTEX_OUTPUT_EXT 0x974D +#define GL_MESH_PREFERS_LOCAL_INVOCATION_PRIMITIVE_OUTPUT_EXT 0x974E +#define GL_MESH_PREFERS_COMPACT_VERTEX_OUTPUT_EXT 0x974F +#define GL_MESH_PREFERS_COMPACT_PRIMITIVE_OUTPUT_EXT 0x9750 +#define GL_MAX_TASK_WORK_GROUP_COUNT_EXT 0x9751 +#define GL_MAX_MESH_WORK_GROUP_COUNT_EXT 0x9752 +#define GL_MAX_MESH_WORK_GROUP_SIZE_EXT 0x9758 +#define GL_MAX_TASK_WORK_GROUP_SIZE_EXT 0x975A +#define GL_MESH_WORK_GROUP_SIZE_EXT 0x953E +#define GL_TASK_WORK_GROUP_SIZE_EXT 0x953F +#define GL_MESH_VERTICES_OUT_EXT 0x9579 +#define GL_MESH_PRIMITIVES_OUT_EXT 0x957A +#define GL_MESH_OUTPUT_TYPE_EXT 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_EXT 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_EXT 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_EXT 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_EXT 0x95A1 +#define GL_TASK_SHADER_INVOCATIONS_EXT 0x9753 +#define GL_MESH_SHADER_INVOCATIONS_EXT 0x9754 +#define GL_MESH_PRIMITIVES_GENERATED_EXT 0x9755 +#define GL_MESH_SHADER_BIT_EXT 0x00000040 +#define GL_TASK_SHADER_BIT_EXT 0x00000080 +#define GL_MESH_SUBROUTINE_EXT 0x957C +#define GL_TASK_SUBROUTINE_EXT 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_EXT 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_EXT 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_EXT 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_EXT 0x959F +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSEXTPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTEXTPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawMeshTasksEXT (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDrawMeshTasksIndirectEXT (GLintptr indirect); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectEXT (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectCountEXT (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_EXT_mesh_shader */ + #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); @@ -1856,7 +1961,7 @@ GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLe #define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar *const*strings); typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); @@ -1901,7 +2006,7 @@ typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint progra #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); -GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar *const*strings); GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); @@ -2009,6 +2114,10 @@ GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsiz #define GL_EXT_shader_texture_lod 1 #endif /* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_samples +#define GL_EXT_shader_texture_samples 1 +#endif /* GL_EXT_shader_texture_samples */ + #ifndef GL_EXT_shadow_samplers #define GL_EXT_shadow_samplers 1 #define GL_TEXTURE_COMPARE_MODE_EXT 0x884C @@ -2375,6 +2484,16 @@ GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, c #define GL_GCCSO_SHADER_BINARY_FJ 0x9260 #endif /* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_HUAWEI_program_binary +#define GL_HUAWEI_program_binary 1 +#define GL_PROGRAM_BINARY_HUAWEI 0x9771 +#endif /* GL_HUAWEI_program_binary */ + +#ifndef GL_HUAWEI_shader_binary +#define GL_HUAWEI_shader_binary 1 +#define GL_SHADER_BINARY_HUAWEI 0x9770 +#endif /* GL_HUAWEI_shader_binary */ + #ifndef GL_IMG_bindless_texture #define GL_IMG_bindless_texture 1 typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture); @@ -2553,10 +2672,42 @@ GL_APICALL void GL_APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLen #define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F #endif /* GL_MESA_program_binary_formats */ +#ifndef GL_MESA_sampler_objects +#define GL_MESA_sampler_objects 1 +#define GL_SAMPLER_BINDING 0x8919 +typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +#endif +#endif /* GL_MESA_sampler_objects */ + #ifndef GL_MESA_shader_integer_functions #define GL_MESA_shader_integer_functions 1 #endif /* GL_MESA_shader_integer_functions */ +#ifndef GL_MESA_texture_const_bandwidth +#define GL_MESA_texture_const_bandwidth 1 +#define GL_CONST_BW_TILING_MESA 0x8BBE +#endif /* GL_MESA_texture_const_bandwidth */ + #ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers #define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 #endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ @@ -3186,6 +3337,13 @@ GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei coun #endif #endif /* GL_NV_non_square_matrices */ +#ifndef GL_NV_pack_subimage +#define GL_NV_pack_subimage 1 +#define GL_PACK_ROW_LENGTH_NV 0x0D02 +#define GL_PACK_SKIP_ROWS_NV 0x0D03 +#define GL_PACK_SKIP_PIXELS_NV 0x0D04 +#endif /* GL_NV_pack_subimage */ + #ifndef GL_NV_path_rendering #define GL_NV_path_rendering 1 typedef double GLdouble; @@ -3683,6 +3841,14 @@ GL_APICALL void GL_APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuin #define GL_NV_stereo_view_rendering 1 #endif /* GL_NV_stereo_view_rendering */ +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 +typedef void (GL_APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureBarrierNV (void); +#endif +#endif /* GL_NV_texture_barrier */ + #ifndef GL_NV_texture_border_clamp #define GL_NV_texture_border_clamp 1 #define GL_TEXTURE_BORDER_COLOR_NV 0x1004 @@ -3779,8 +3945,10 @@ GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, #define GL_MAX_VIEWS_OVR 0x9631 #define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +GL_APICALL void GL_APIENTRY glNamedFramebufferTextureMultiviewOVR (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #endif #endif /* GL_OVR_multiview */ @@ -3917,6 +4085,10 @@ GL_APICALL void GL_APIENTRY glTexEstimateMotionRegionsQCOM (GLuint ref, GLuint t #define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 #endif /* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_render_sRGB_R8_RG8 +#define GL_QCOM_render_sRGB_R8_RG8 1 +#endif /* GL_QCOM_render_sRGB_R8_RG8 */ + #ifndef GL_QCOM_render_shared_exponent #define GL_QCOM_render_shared_exponent 1 #endif /* GL_QCOM_render_shared_exponent */ @@ -3974,6 +4146,11 @@ GL_APICALL void GL_APIENTRY glTextureFoveationParametersQCOM (GLuint texture, GL #define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1 #endif /* GL_QCOM_texture_foveated_subsampled_layout */ +#ifndef GL_QCOM_texture_lod_bias +#define GL_QCOM_texture_lod_bias 1 +#define GL_TEXTURE_LOD_BIAS_QCOM 0x8C96 +#endif /* GL_QCOM_texture_lod_bias */ + #ifndef GL_QCOM_tiled_rendering #define GL_QCOM_tiled_rendering 1 #define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 @@ -4021,6 +4198,12 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); #define GL_WRITEONLY_RENDERING_QCOM 0x8823 #endif /* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_ycbcr_degamma +#define GL_QCOM_ycbcr_degamma 1 +#define GL_TEXTURE_Y_DEGAMMA_QCOM 0x9710 +#define GL_TEXTURE_CBCR_DEGAMMA_QCOM 0x9711 +#endif /* GL_QCOM_ycbcr_degamma */ + #ifndef GL_VIV_shader_binary #define GL_VIV_shader_binary 1 #define GL_SHADER_BINARY_VIV 0x8FC4 diff --git a/src/video/khronos/EGL/egl.h b/src/video/khronos/EGL/egl.h index c58f552bf5..314ef43f87 100644 --- a/src/video/khronos/EGL/egl.h +++ b/src/video/khronos/EGL/egl.h @@ -14,7 +14,7 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: f4cc936b88 $ on $Git commit date: 2023-12-16 01:21:49 -0500 $ +** Khronos $Git commit SHA1: e80a2e0050 $ on $Git commit date: 2026-03-19 06:21:49 +0100 $ */ #include @@ -23,7 +23,7 @@ extern "C" { #define EGL_EGL_PROTOTYPES 1 #endif -/* Generated on date 20231215 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: egl diff --git a/src/video/khronos/EGL/eglext.h b/src/video/khronos/EGL/eglext.h index 9932ebeec5..c3639e4cc1 100644 --- a/src/video/khronos/EGL/eglext.h +++ b/src/video/khronos/EGL/eglext.h @@ -14,12 +14,12 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: f4cc936b88 $ on $Git commit date: 2023-12-16 01:21:49 -0500 $ +** Khronos $Git commit SHA1: e80a2e0050 $ on $Git commit date: 2026-03-19 06:21:49 +0100 $ */ #include -#define EGL_EGLEXT_VERSION 20231215 +#define EGL_EGLEXT_VERSION 20260319 /* Generated C header for: * API: egl @@ -551,6 +551,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSur #define EGL_RECORDABLE_ANDROID 0x3142 #endif /* EGL_ANDROID_recordable */ +#ifndef EGL_ANDROID_telemetry_hint +#define EGL_ANDROID_telemetry_hint 1 +#define EGL_TELEMETRY_HINT_ANDROID 0x3570 +#endif /* EGL_ANDROID_telemetry_hint */ + #ifndef EGL_ANGLE_d3d_share_handle_client_buffer #define EGL_ANGLE_d3d_share_handle_client_buffer 1 #define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 @@ -723,6 +728,24 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLi #define EGL_RENDERER_EXT 0x335F #endif /* EGL_EXT_device_query_name */ +#ifndef EGL_EXT_device_type +#define EGL_EXT_device_type 1 +#define EGL_DEVICE_TYPE_EXT 0x3590 +#define EGL_DEVICE_TYPE_OTHER_EXT 0x3591 +#define EGL_DEVICE_TYPE_INTEGRATED_GPU_EXT 0x3592 +#define EGL_DEVICE_TYPE_DISCRETE_GPU_EXT 0x3593 +#define EGL_DEVICE_TYPE_CPU_EXT 0x3594 +#endif /* EGL_EXT_device_type */ + +#ifndef EGL_EXT_display_alloc +#define EGL_EXT_display_alloc 1 +#define EGL_ALLOC_NEW_DISPLAY_EXT 0x3379 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYDISPLAYEXTPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyDisplayEXT (EGLDisplay dpy); +#endif +#endif /* EGL_EXT_display_alloc */ + #ifndef EGL_EXT_explicit_device #define EGL_EXT_explicit_device 1 #endif /* EGL_EXT_explicit_device */ diff --git a/src/video/khronos/GLES2/gl2.h b/src/video/khronos/GLES2/gl2.h index 6be4e3637b..fdc46fc951 100644 --- a/src/video/khronos/GLES2/gl2.h +++ b/src/video/khronos/GLES2/gl2.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -25,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20231129 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: gles2 diff --git a/src/video/khronos/GLES2/gl2ext.h b/src/video/khronos/GLES2/gl2ext.h index 63b530b4b7..96e8be78e0 100644 --- a/src/video/khronos/GLES2/gl2ext.h +++ b/src/video/khronos/GLES2/gl2ext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -19,7 +19,7 @@ extern "C" { #define GL_APIENTRYP GL_APIENTRY* #endif -/* Generated on date 20231129 */ +#define GL_GLEXT_VERSION 20260319 /* Generated C header for: * API: gles2 @@ -1637,6 +1637,86 @@ GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 #endif #endif /* GL_EXT_memory_object_win32 */ +#ifndef GL_EXT_mesh_shader +#define GL_EXT_mesh_shader 1 +#define GL_MESH_SHADER_EXT 0x9559 +#define GL_TASK_SHADER_EXT 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_EXT 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_EXT 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_EXT 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_EXT 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_EXT 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_EXT 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_EXT 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_EXT 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_EXT 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_EXT 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_EXT 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_EXT 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_EXT 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_EXT 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_EXT 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_EXT 0x8E6F +#define GL_MAX_TASK_WORK_GROUP_TOTAL_COUNT_EXT 0x9740 +#define GL_MAX_MESH_WORK_GROUP_TOTAL_COUNT_EXT 0x9741 +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_EXT 0x9757 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_EXT 0x9759 +#define GL_MAX_TASK_PAYLOAD_SIZE_EXT 0x9742 +#define GL_MAX_TASK_SHARED_MEMORY_SIZE_EXT 0x9743 +#define GL_MAX_MESH_SHARED_MEMORY_SIZE_EXT 0x9744 +#define GL_MAX_TASK_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9745 +#define GL_MAX_MESH_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9746 +#define GL_MAX_MESH_OUTPUT_MEMORY_SIZE_EXT 0x9747 +#define GL_MAX_MESH_PAYLOAD_AND_OUTPUT_MEMORY_SIZE_EXT 0x9748 +#define GL_MAX_MESH_OUTPUT_VERTICES_EXT 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT 0x9756 +#define GL_MAX_MESH_OUTPUT_COMPONENTS_EXT 0x9749 +#define GL_MAX_MESH_OUTPUT_LAYERS_EXT 0x974A +#define GL_MAX_MESH_MULTIVIEW_VIEW_COUNT_EXT 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_EXT 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_EXT 0x9543 +#define GL_MAX_PREFERRED_TASK_WORK_GROUP_INVOCATIONS_EXT 0x974B +#define GL_MAX_PREFERRED_MESH_WORK_GROUP_INVOCATIONS_EXT 0x974C +#define GL_MESH_PREFERS_LOCAL_INVOCATION_VERTEX_OUTPUT_EXT 0x974D +#define GL_MESH_PREFERS_LOCAL_INVOCATION_PRIMITIVE_OUTPUT_EXT 0x974E +#define GL_MESH_PREFERS_COMPACT_VERTEX_OUTPUT_EXT 0x974F +#define GL_MESH_PREFERS_COMPACT_PRIMITIVE_OUTPUT_EXT 0x9750 +#define GL_MAX_TASK_WORK_GROUP_COUNT_EXT 0x9751 +#define GL_MAX_MESH_WORK_GROUP_COUNT_EXT 0x9752 +#define GL_MAX_MESH_WORK_GROUP_SIZE_EXT 0x9758 +#define GL_MAX_TASK_WORK_GROUP_SIZE_EXT 0x975A +#define GL_MESH_WORK_GROUP_SIZE_EXT 0x953E +#define GL_TASK_WORK_GROUP_SIZE_EXT 0x953F +#define GL_MESH_VERTICES_OUT_EXT 0x9579 +#define GL_MESH_PRIMITIVES_OUT_EXT 0x957A +#define GL_MESH_OUTPUT_TYPE_EXT 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_EXT 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_EXT 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_EXT 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_EXT 0x95A1 +#define GL_TASK_SHADER_INVOCATIONS_EXT 0x9753 +#define GL_MESH_SHADER_INVOCATIONS_EXT 0x9754 +#define GL_MESH_PRIMITIVES_GENERATED_EXT 0x9755 +#define GL_MESH_SHADER_BIT_EXT 0x00000040 +#define GL_TASK_SHADER_BIT_EXT 0x00000080 +#define GL_MESH_SUBROUTINE_EXT 0x957C +#define GL_TASK_SUBROUTINE_EXT 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_EXT 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_EXT 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_EXT 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_EXT 0x959F +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSEXTPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTEXTPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawMeshTasksEXT (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDrawMeshTasksIndirectEXT (GLintptr indirect); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectEXT (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectCountEXT (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_EXT_mesh_shader */ + #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); @@ -2034,6 +2114,10 @@ GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsiz #define GL_EXT_shader_texture_lod 1 #endif /* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_samples +#define GL_EXT_shader_texture_samples 1 +#endif /* GL_EXT_shader_texture_samples */ + #ifndef GL_EXT_shadow_samplers #define GL_EXT_shadow_samplers 1 #define GL_TEXTURE_COMPARE_MODE_EXT 0x884C @@ -2400,6 +2484,16 @@ GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, c #define GL_GCCSO_SHADER_BINARY_FJ 0x9260 #endif /* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_HUAWEI_program_binary +#define GL_HUAWEI_program_binary 1 +#define GL_PROGRAM_BINARY_HUAWEI 0x9771 +#endif /* GL_HUAWEI_program_binary */ + +#ifndef GL_HUAWEI_shader_binary +#define GL_HUAWEI_shader_binary 1 +#define GL_SHADER_BINARY_HUAWEI 0x9770 +#endif /* GL_HUAWEI_shader_binary */ + #ifndef GL_IMG_bindless_texture #define GL_IMG_bindless_texture 1 typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture); @@ -2609,6 +2703,11 @@ GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pnam #define GL_MESA_shader_integer_functions 1 #endif /* GL_MESA_shader_integer_functions */ +#ifndef GL_MESA_texture_const_bandwidth +#define GL_MESA_texture_const_bandwidth 1 +#define GL_CONST_BW_TILING_MESA 0x8BBE +#endif /* GL_MESA_texture_const_bandwidth */ + #ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers #define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 #endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ @@ -3742,6 +3841,14 @@ GL_APICALL void GL_APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuin #define GL_NV_stereo_view_rendering 1 #endif /* GL_NV_stereo_view_rendering */ +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 +typedef void (GL_APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureBarrierNV (void); +#endif +#endif /* GL_NV_texture_barrier */ + #ifndef GL_NV_texture_border_clamp #define GL_NV_texture_border_clamp 1 #define GL_TEXTURE_BORDER_COLOR_NV 0x1004 @@ -3838,8 +3945,10 @@ GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, #define GL_MAX_VIEWS_OVR 0x9631 #define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +GL_APICALL void GL_APIENTRY glNamedFramebufferTextureMultiviewOVR (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #endif #endif /* GL_OVR_multiview */ @@ -4089,6 +4198,12 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); #define GL_WRITEONLY_RENDERING_QCOM 0x8823 #endif /* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_ycbcr_degamma +#define GL_QCOM_ycbcr_degamma 1 +#define GL_TEXTURE_Y_DEGAMMA_QCOM 0x9710 +#define GL_TEXTURE_CBCR_DEGAMMA_QCOM 0x9711 +#endif /* GL_QCOM_ycbcr_degamma */ + #ifndef GL_VIV_shader_binary #define GL_VIV_shader_binary 1 #define GL_SHADER_BINARY_VIV 0x8FC4 diff --git a/src/video/khronos/GLES3/gl3.h b/src/video/khronos/GLES3/gl3.h index 850eb836f1..388e880fb6 100644 --- a/src/video/khronos/GLES3/gl3.h +++ b/src/video/khronos/GLES3/gl3.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -25,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20240815 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: gles2 diff --git a/src/video/khronos/GLES3/gl31.h b/src/video/khronos/GLES3/gl31.h index 502d6feec8..8ed7129c51 100644 --- a/src/video/khronos/GLES3/gl31.h +++ b/src/video/khronos/GLES3/gl31.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -25,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20191013 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: gles2 @@ -458,7 +458,7 @@ typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -601,7 +601,7 @@ GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -1049,7 +1049,7 @@ typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); -typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); @@ -1076,7 +1076,7 @@ typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsiz typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); #if GL_GLES_PROTOTYPES GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); @@ -1154,7 +1154,7 @@ GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); -GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); @@ -1181,7 +1181,7 @@ GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numA GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); #endif #endif /* GL_ES_VERSION_3_0 */ @@ -1369,7 +1369,7 @@ typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, G typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); @@ -1438,7 +1438,7 @@ GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum p GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); diff --git a/src/video/khronos/GLES3/gl32.h b/src/video/khronos/GLES3/gl32.h index ae56b0e95f..56e9214416 100644 --- a/src/video/khronos/GLES3/gl32.h +++ b/src/video/khronos/GLES3/gl32.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright 2013-2020 The Khronos Group Inc. +** Copyright 2013-2026 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** This header is generated from the Khronos OpenGL / OpenGL ES XML @@ -25,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20191013 */ +/* Generated on date 20260319 */ /* Generated C header for: * API: gles2 @@ -458,7 +458,7 @@ typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -601,7 +601,7 @@ GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -1049,7 +1049,7 @@ typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); -typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); @@ -1076,7 +1076,7 @@ typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsiz typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); #if GL_GLES_PROTOTYPES GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); @@ -1154,7 +1154,7 @@ GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); -GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); @@ -1181,7 +1181,7 @@ GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numA GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); #endif #endif /* GL_ES_VERSION_3_0 */ @@ -1369,7 +1369,7 @@ typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, G typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); @@ -1438,7 +1438,7 @@ GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum p GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); From 322dfd3adae15e4985d58522bf2a1abf6659bf4c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 11:55:50 +0300 Subject: [PATCH 336/407] update vulkan headers from khronos. --- .../vk_video/vulkan_video_codec_av1std.h | 48 +- .../vulkan_video_codec_av1std_decode.h | 2 +- .../vulkan_video_codec_av1std_encode.h | 143 + .../vk_video/vulkan_video_codec_h264std.h | 18 +- .../vulkan_video_codec_h264std_decode.h | 4 +- .../vulkan_video_codec_h264std_encode.h | 2 +- .../vk_video/vulkan_video_codec_h265std.h | 48 +- .../vulkan_video_codec_h265std_decode.h | 4 +- .../vulkan_video_codec_h265std_encode.h | 2 +- .../vk_video/vulkan_video_codec_vp9std.h | 151 + .../vulkan_video_codec_vp9std_decode.h | 68 + .../vk_video/vulkan_video_codecs_common.h | 2 +- src/video/khronos/vulkan/vk_icd.h | 3 +- src/video/khronos/vulkan/vk_layer.h | 3 + src/video/khronos/vulkan/vk_platform.h | 2 +- src/video/khronos/vulkan/vulkan.h | 6 +- src/video/khronos/vulkan/vulkan_android.h | 8 +- src/video/khronos/vulkan/vulkan_beta.h | 181 +- src/video/khronos/vulkan/vulkan_core.h | 12959 ++++++++++++---- src/video/khronos/vulkan/vulkan_directfb.h | 6 +- src/video/khronos/vulkan/vulkan_fuchsia.h | 22 +- src/video/khronos/vulkan/vulkan_ggp.h | 4 +- src/video/khronos/vulkan/vulkan_ios.h | 4 +- src/video/khronos/vulkan/vulkan_macos.h | 4 +- src/video/khronos/vulkan/vulkan_metal.h | 51 +- src/video/khronos/vulkan/vulkan_ohos.h | 120 + src/video/khronos/vulkan/vulkan_screen.h | 8 +- src/video/khronos/vulkan/vulkan_vi.h | 4 +- src/video/khronos/vulkan/vulkan_wayland.h | 6 +- src/video/khronos/vulkan/vulkan_win32.h | 32 +- src/video/khronos/vulkan/vulkan_xcb.h | 6 +- src/video/khronos/vulkan/vulkan_xlib.h | 6 +- src/video/khronos/vulkan/vulkan_xlib_xrandr.h | 6 +- 33 files changed, 10904 insertions(+), 3029 deletions(-) create mode 100644 src/video/khronos/vk_video/vulkan_video_codec_av1std_encode.h create mode 100644 src/video/khronos/vk_video/vulkan_video_codec_vp9std.h create mode 100644 src/video/khronos/vk_video/vulkan_video_codec_vp9std_decode.h create mode 100644 src/video/khronos/vulkan/vulkan_ohos.h diff --git a/src/video/khronos/vk_video/vulkan_video_codec_av1std.h b/src/video/khronos/vk_video/vulkan_video_codec_av1std.h index 8ce283e8a8..75cebd74cb 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_av1std.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_av1std.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_AV1STD_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -22,27 +22,27 @@ extern "C" { // vulkan_video_codec_av1std is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_av1std 1 #include "vulkan_video_codecs_common.h" -#define STD_VIDEO_AV1_NUM_REF_FRAMES 8 -#define STD_VIDEO_AV1_REFS_PER_FRAME 7 -#define STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME 8 -#define STD_VIDEO_AV1_MAX_TILE_COLS 64 -#define STD_VIDEO_AV1_MAX_TILE_ROWS 64 -#define STD_VIDEO_AV1_MAX_SEGMENTS 8 -#define STD_VIDEO_AV1_SEG_LVL_MAX 8 -#define STD_VIDEO_AV1_PRIMARY_REF_NONE 7 -#define STD_VIDEO_AV1_SELECT_INTEGER_MV 2 -#define STD_VIDEO_AV1_SELECT_SCREEN_CONTENT_TOOLS 2 -#define STD_VIDEO_AV1_SKIP_MODE_FRAMES 2 -#define STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS 4 -#define STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS 2 -#define STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS 8 -#define STD_VIDEO_AV1_MAX_NUM_PLANES 3 -#define STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS 6 -#define STD_VIDEO_AV1_MAX_NUM_Y_POINTS 14 -#define STD_VIDEO_AV1_MAX_NUM_CB_POINTS 10 -#define STD_VIDEO_AV1_MAX_NUM_CR_POINTS 10 -#define STD_VIDEO_AV1_MAX_NUM_POS_LUMA 24 -#define STD_VIDEO_AV1_MAX_NUM_POS_CHROMA 25 +#define STD_VIDEO_AV1_NUM_REF_FRAMES 8U +#define STD_VIDEO_AV1_REFS_PER_FRAME 7U +#define STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME 8U +#define STD_VIDEO_AV1_MAX_TILE_COLS 64U +#define STD_VIDEO_AV1_MAX_TILE_ROWS 64U +#define STD_VIDEO_AV1_MAX_SEGMENTS 8U +#define STD_VIDEO_AV1_SEG_LVL_MAX 8U +#define STD_VIDEO_AV1_PRIMARY_REF_NONE 7U +#define STD_VIDEO_AV1_SELECT_INTEGER_MV 2U +#define STD_VIDEO_AV1_SELECT_SCREEN_CONTENT_TOOLS 2U +#define STD_VIDEO_AV1_SKIP_MODE_FRAMES 2U +#define STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS 4U +#define STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS 2U +#define STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS 8U +#define STD_VIDEO_AV1_MAX_NUM_PLANES 3U +#define STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS 6U +#define STD_VIDEO_AV1_MAX_NUM_Y_POINTS 14U +#define STD_VIDEO_AV1_MAX_NUM_CB_POINTS 10U +#define STD_VIDEO_AV1_MAX_NUM_CR_POINTS 10U +#define STD_VIDEO_AV1_MAX_NUM_POS_LUMA 24U +#define STD_VIDEO_AV1_MAX_NUM_POS_CHROMA 25U typedef enum StdVideoAV1Profile { STD_VIDEO_AV1_PROFILE_MAIN = 0, @@ -132,7 +132,7 @@ typedef enum StdVideoAV1FrameRestorationType { typedef enum StdVideoAV1ColorPrimaries { STD_VIDEO_AV1_COLOR_PRIMARIES_BT_709 = 1, - STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = 2, + STD_VIDEO_AV1_COLOR_PRIMARIES_UNSPECIFIED = 2, STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_M = 4, STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_B_G = 5, STD_VIDEO_AV1_COLOR_PRIMARIES_BT_601 = 6, @@ -144,6 +144,8 @@ typedef enum StdVideoAV1ColorPrimaries { STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_432 = 12, STD_VIDEO_AV1_COLOR_PRIMARIES_EBU_3213 = 22, STD_VIDEO_AV1_COLOR_PRIMARIES_INVALID = 0x7FFFFFFF, + // STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED is a legacy alias + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = STD_VIDEO_AV1_COLOR_PRIMARIES_UNSPECIFIED, STD_VIDEO_AV1_COLOR_PRIMARIES_MAX_ENUM = 0x7FFFFFFF } StdVideoAV1ColorPrimaries; diff --git a/src/video/khronos/vk_video/vulkan_video_codec_av1std_decode.h b/src/video/khronos/vk_video/vulkan_video_codec_av1std_decode.h index 6b8130cd9f..60bf2c0398 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_av1std_decode.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_av1std_decode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_AV1STD_DECODE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/video/khronos/vk_video/vulkan_video_codec_av1std_encode.h b/src/video/khronos/vk_video/vulkan_video_codec_av1std_encode.h new file mode 100644 index 0000000000..3602fe1250 --- /dev/null +++ b/src/video/khronos/vk_video/vulkan_video_codec_av1std_encode.h @@ -0,0 +1,143 @@ +#ifndef VULKAN_VIDEO_CODEC_AV1STD_ENCODE_H_ +#define VULKAN_VIDEO_CODEC_AV1STD_ENCODE_H_ 1 + +/* +** Copyright 2015-2026 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_av1std_encode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_av1std_encode 1 +#include "vulkan_video_codec_av1std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_encode" +typedef struct StdVideoEncodeAV1DecoderModelInfo { + uint8_t buffer_delay_length_minus_1; + uint8_t buffer_removal_time_length_minus_1; + uint8_t frame_presentation_time_length_minus_1; + uint8_t reserved1; + uint32_t num_units_in_decoding_tick; +} StdVideoEncodeAV1DecoderModelInfo; + +typedef struct StdVideoEncodeAV1ExtensionHeader { + uint8_t temporal_id; + uint8_t spatial_id; +} StdVideoEncodeAV1ExtensionHeader; + +typedef struct StdVideoEncodeAV1OperatingPointInfoFlags { + uint32_t decoder_model_present_for_this_op : 1; + uint32_t low_delay_mode_flag : 1; + uint32_t initial_display_delay_present_for_this_op : 1; + uint32_t reserved : 29; +} StdVideoEncodeAV1OperatingPointInfoFlags; + +typedef struct StdVideoEncodeAV1OperatingPointInfo { + StdVideoEncodeAV1OperatingPointInfoFlags flags; + uint16_t operating_point_idc; + uint8_t seq_level_idx; + uint8_t seq_tier; + uint32_t decoder_buffer_delay; + uint32_t encoder_buffer_delay; + uint8_t initial_display_delay_minus_1; +} StdVideoEncodeAV1OperatingPointInfo; + +typedef struct StdVideoEncodeAV1PictureInfoFlags { + uint32_t error_resilient_mode : 1; + uint32_t disable_cdf_update : 1; + uint32_t use_superres : 1; + uint32_t render_and_frame_size_different : 1; + uint32_t allow_screen_content_tools : 1; + uint32_t is_filter_switchable : 1; + uint32_t force_integer_mv : 1; + uint32_t frame_size_override_flag : 1; + uint32_t buffer_removal_time_present_flag : 1; + uint32_t allow_intrabc : 1; + uint32_t frame_refs_short_signaling : 1; + uint32_t allow_high_precision_mv : 1; + uint32_t is_motion_mode_switchable : 1; + uint32_t use_ref_frame_mvs : 1; + uint32_t disable_frame_end_update_cdf : 1; + uint32_t allow_warped_motion : 1; + uint32_t reduced_tx_set : 1; + uint32_t skip_mode_present : 1; + uint32_t delta_q_present : 1; + uint32_t delta_lf_present : 1; + uint32_t delta_lf_multi : 1; + uint32_t segmentation_enabled : 1; + uint32_t segmentation_update_map : 1; + uint32_t segmentation_temporal_update : 1; + uint32_t segmentation_update_data : 1; + uint32_t UsesLr : 1; + uint32_t usesChromaLr : 1; + uint32_t show_frame : 1; + uint32_t showable_frame : 1; + uint32_t reserved : 3; +} StdVideoEncodeAV1PictureInfoFlags; + +typedef struct StdVideoEncodeAV1PictureInfo { + StdVideoEncodeAV1PictureInfoFlags flags; + StdVideoAV1FrameType frame_type; + uint32_t frame_presentation_time; + uint32_t current_frame_id; + uint8_t order_hint; + uint8_t primary_ref_frame; + uint8_t refresh_frame_flags; + uint8_t coded_denom; + uint16_t render_width_minus_1; + uint16_t render_height_minus_1; + StdVideoAV1InterpolationFilter interpolation_filter; + StdVideoAV1TxMode TxMode; + uint8_t delta_q_res; + uint8_t delta_lf_res; + uint8_t ref_order_hint[STD_VIDEO_AV1_NUM_REF_FRAMES]; + int8_t ref_frame_idx[STD_VIDEO_AV1_REFS_PER_FRAME]; + uint8_t reserved1[3]; + uint32_t delta_frame_id_minus_1[STD_VIDEO_AV1_REFS_PER_FRAME]; + const StdVideoAV1TileInfo* pTileInfo; + const StdVideoAV1Quantization* pQuantization; + const StdVideoAV1Segmentation* pSegmentation; + const StdVideoAV1LoopFilter* pLoopFilter; + const StdVideoAV1CDEF* pCDEF; + const StdVideoAV1LoopRestoration* pLoopRestoration; + const StdVideoAV1GlobalMotion* pGlobalMotion; + const StdVideoEncodeAV1ExtensionHeader* pExtensionHeader; + const uint32_t* pBufferRemovalTimes; +} StdVideoEncodeAV1PictureInfo; + +typedef struct StdVideoEncodeAV1ReferenceInfoFlags { + uint32_t disable_frame_end_update_cdf : 1; + uint32_t segmentation_enabled : 1; + uint32_t reserved : 30; +} StdVideoEncodeAV1ReferenceInfoFlags; + +typedef struct StdVideoEncodeAV1ReferenceInfo { + StdVideoEncodeAV1ReferenceInfoFlags flags; + uint32_t RefFrameId; + StdVideoAV1FrameType frame_type; + uint8_t OrderHint; + uint8_t reserved1[3]; + const StdVideoEncodeAV1ExtensionHeader* pExtensionHeader; +} StdVideoEncodeAV1ReferenceInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h264std.h b/src/video/khronos/vk_video/vulkan_video_codec_h264std.h index 6d27af37b7..48621b6954 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h264std.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h264std.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -22,14 +22,14 @@ extern "C" { // vulkan_video_codec_h264std is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h264std 1 #include "vulkan_video_codecs_common.h" -#define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32 -#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6 -#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16 -#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS 6 -#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64 -#define STD_VIDEO_H264_MAX_NUM_LIST_REF 32 -#define STD_VIDEO_H264_MAX_CHROMA_PLANES 2 -#define STD_VIDEO_H264_NO_REFERENCE_PICTURE 0xFF +#define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32U +#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6U +#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16U +#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS 6U +#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64U +#define STD_VIDEO_H264_MAX_NUM_LIST_REF 32U +#define STD_VIDEO_H264_MAX_CHROMA_PLANES 2U +#define STD_VIDEO_H264_NO_REFERENCE_PICTURE 0xFFU typedef enum StdVideoH264ChromaFormatIdc { STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME = 0, diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h b/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h index 439cb885e7..a6bfe9d822 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,7 @@ extern "C" { #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode" -#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2 +#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2U typedef enum StdVideoDecodeH264FieldOrderCount { STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0, diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h b/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h index 9e24aa5d99..2d42ac321b 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h265std.h b/src/video/khronos/vk_video/vulkan_video_codec_h265std.h index d0a1bacbea..23617b8f96 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h265std.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h265std.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -22,29 +22,29 @@ extern "C" { // vulkan_video_codec_h265std is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h265std 1 #include "vulkan_video_codecs_common.h" -#define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32 -#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7 -#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6 -#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16 -#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6 -#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS 64 -#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS 6 -#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64 -#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2 -#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64 -#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6 -#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19 -#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21 -#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3 -#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128 -#define STD_VIDEO_H265_MAX_NUM_LIST_REF 15 -#define STD_VIDEO_H265_MAX_CHROMA_PLANES 2 -#define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64 -#define STD_VIDEO_H265_MAX_DPB_SIZE 16 -#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32 -#define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16 -#define STD_VIDEO_H265_MAX_DELTA_POC 48 -#define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFF +#define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32U +#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7U +#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6U +#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16U +#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6U +#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS 64U +#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS 6U +#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64U +#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2U +#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64U +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6U +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19U +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21U +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3U +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128U +#define STD_VIDEO_H265_MAX_NUM_LIST_REF 15U +#define STD_VIDEO_H265_MAX_CHROMA_PLANES 2U +#define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64U +#define STD_VIDEO_H265_MAX_DPB_SIZE 16U +#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32U +#define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16U +#define STD_VIDEO_H265_MAX_DELTA_POC 48U +#define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFFU typedef enum StdVideoH265ChromaFormatIdc { STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0, diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h b/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h index 0178793e51..1758d4a88d 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,7 @@ extern "C" { #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode" -#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8 +#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8U typedef struct StdVideoDecodeH265PictureInfoFlags { uint32_t IrapPicFlag : 1; uint32_t IdrPicFlag : 1; diff --git a/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h b/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h index ee34491f4e..e584a7262b 100644 --- a/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h +++ b/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/video/khronos/vk_video/vulkan_video_codec_vp9std.h b/src/video/khronos/vk_video/vulkan_video_codec_vp9std.h new file mode 100644 index 0000000000..3c62f287e7 --- /dev/null +++ b/src/video/khronos/vk_video/vulkan_video_codec_vp9std.h @@ -0,0 +1,151 @@ +#ifndef VULKAN_VIDEO_CODEC_VP9STD_H_ +#define VULKAN_VIDEO_CODEC_VP9STD_H_ 1 + +/* +** Copyright 2015-2026 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_vp9std is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_vp9std 1 +#include "vulkan_video_codecs_common.h" +#define STD_VIDEO_VP9_NUM_REF_FRAMES 8U +#define STD_VIDEO_VP9_REFS_PER_FRAME 3U +#define STD_VIDEO_VP9_MAX_REF_FRAMES 4U +#define STD_VIDEO_VP9_LOOP_FILTER_ADJUSTMENTS 2U +#define STD_VIDEO_VP9_MAX_SEGMENTS 8U +#define STD_VIDEO_VP9_SEG_LVL_MAX 4U +#define STD_VIDEO_VP9_MAX_SEGMENTATION_TREE_PROBS 7U +#define STD_VIDEO_VP9_MAX_SEGMENTATION_PRED_PROB 3U + +typedef enum StdVideoVP9Profile { + STD_VIDEO_VP9_PROFILE_0 = 0, + STD_VIDEO_VP9_PROFILE_1 = 1, + STD_VIDEO_VP9_PROFILE_2 = 2, + STD_VIDEO_VP9_PROFILE_3 = 3, + STD_VIDEO_VP9_PROFILE_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_PROFILE_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9Profile; + +typedef enum StdVideoVP9Level { + STD_VIDEO_VP9_LEVEL_1_0 = 0, + STD_VIDEO_VP9_LEVEL_1_1 = 1, + STD_VIDEO_VP9_LEVEL_2_0 = 2, + STD_VIDEO_VP9_LEVEL_2_1 = 3, + STD_VIDEO_VP9_LEVEL_3_0 = 4, + STD_VIDEO_VP9_LEVEL_3_1 = 5, + STD_VIDEO_VP9_LEVEL_4_0 = 6, + STD_VIDEO_VP9_LEVEL_4_1 = 7, + STD_VIDEO_VP9_LEVEL_5_0 = 8, + STD_VIDEO_VP9_LEVEL_5_1 = 9, + STD_VIDEO_VP9_LEVEL_5_2 = 10, + STD_VIDEO_VP9_LEVEL_6_0 = 11, + STD_VIDEO_VP9_LEVEL_6_1 = 12, + STD_VIDEO_VP9_LEVEL_6_2 = 13, + STD_VIDEO_VP9_LEVEL_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_LEVEL_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9Level; + +typedef enum StdVideoVP9FrameType { + STD_VIDEO_VP9_FRAME_TYPE_KEY = 0, + STD_VIDEO_VP9_FRAME_TYPE_NON_KEY = 1, + STD_VIDEO_VP9_FRAME_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_FRAME_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9FrameType; + +typedef enum StdVideoVP9ReferenceName { + STD_VIDEO_VP9_REFERENCE_NAME_INTRA_FRAME = 0, + STD_VIDEO_VP9_REFERENCE_NAME_LAST_FRAME = 1, + STD_VIDEO_VP9_REFERENCE_NAME_GOLDEN_FRAME = 2, + STD_VIDEO_VP9_REFERENCE_NAME_ALTREF_FRAME = 3, + STD_VIDEO_VP9_REFERENCE_NAME_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_REFERENCE_NAME_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9ReferenceName; + +typedef enum StdVideoVP9InterpolationFilter { + STD_VIDEO_VP9_INTERPOLATION_FILTER_EIGHTTAP = 0, + STD_VIDEO_VP9_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH = 1, + STD_VIDEO_VP9_INTERPOLATION_FILTER_EIGHTTAP_SHARP = 2, + STD_VIDEO_VP9_INTERPOLATION_FILTER_BILINEAR = 3, + STD_VIDEO_VP9_INTERPOLATION_FILTER_SWITCHABLE = 4, + STD_VIDEO_VP9_INTERPOLATION_FILTER_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_INTERPOLATION_FILTER_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9InterpolationFilter; + +typedef enum StdVideoVP9ColorSpace { + STD_VIDEO_VP9_COLOR_SPACE_UNKNOWN = 0, + STD_VIDEO_VP9_COLOR_SPACE_BT_601 = 1, + STD_VIDEO_VP9_COLOR_SPACE_BT_709 = 2, + STD_VIDEO_VP9_COLOR_SPACE_SMPTE_170 = 3, + STD_VIDEO_VP9_COLOR_SPACE_SMPTE_240 = 4, + STD_VIDEO_VP9_COLOR_SPACE_BT_2020 = 5, + STD_VIDEO_VP9_COLOR_SPACE_RESERVED = 6, + STD_VIDEO_VP9_COLOR_SPACE_RGB = 7, + STD_VIDEO_VP9_COLOR_SPACE_INVALID = 0x7FFFFFFF, + STD_VIDEO_VP9_COLOR_SPACE_MAX_ENUM = 0x7FFFFFFF +} StdVideoVP9ColorSpace; +typedef struct StdVideoVP9ColorConfigFlags { + uint32_t color_range : 1; + uint32_t reserved : 31; +} StdVideoVP9ColorConfigFlags; + +typedef struct StdVideoVP9ColorConfig { + StdVideoVP9ColorConfigFlags flags; + uint8_t BitDepth; + uint8_t subsampling_x; + uint8_t subsampling_y; + uint8_t reserved1; + StdVideoVP9ColorSpace color_space; +} StdVideoVP9ColorConfig; + +typedef struct StdVideoVP9LoopFilterFlags { + uint32_t loop_filter_delta_enabled : 1; + uint32_t loop_filter_delta_update : 1; + uint32_t reserved : 30; +} StdVideoVP9LoopFilterFlags; + +typedef struct StdVideoVP9LoopFilter { + StdVideoVP9LoopFilterFlags flags; + uint8_t loop_filter_level; + uint8_t loop_filter_sharpness; + uint8_t update_ref_delta; + int8_t loop_filter_ref_deltas[STD_VIDEO_VP9_MAX_REF_FRAMES]; + uint8_t update_mode_delta; + int8_t loop_filter_mode_deltas[STD_VIDEO_VP9_LOOP_FILTER_ADJUSTMENTS]; +} StdVideoVP9LoopFilter; + +typedef struct StdVideoVP9SegmentationFlags { + uint32_t segmentation_update_map : 1; + uint32_t segmentation_temporal_update : 1; + uint32_t segmentation_update_data : 1; + uint32_t segmentation_abs_or_delta_update : 1; + uint32_t reserved : 28; +} StdVideoVP9SegmentationFlags; + +typedef struct StdVideoVP9Segmentation { + StdVideoVP9SegmentationFlags flags; + uint8_t segmentation_tree_probs[STD_VIDEO_VP9_MAX_SEGMENTATION_TREE_PROBS]; + uint8_t segmentation_pred_prob[STD_VIDEO_VP9_MAX_SEGMENTATION_PRED_PROB]; + uint8_t FeatureEnabled[STD_VIDEO_VP9_MAX_SEGMENTS]; + int16_t FeatureData[STD_VIDEO_VP9_MAX_SEGMENTS][STD_VIDEO_VP9_SEG_LVL_MAX]; +} StdVideoVP9Segmentation; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video/khronos/vk_video/vulkan_video_codec_vp9std_decode.h b/src/video/khronos/vk_video/vulkan_video_codec_vp9std_decode.h new file mode 100644 index 0000000000..ac7fa7be8c --- /dev/null +++ b/src/video/khronos/vk_video/vulkan_video_codec_vp9std_decode.h @@ -0,0 +1,68 @@ +#ifndef VULKAN_VIDEO_CODEC_VP9STD_DECODE_H_ +#define VULKAN_VIDEO_CODEC_VP9STD_DECODE_H_ 1 + +/* +** Copyright 2015-2026 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_vp9std_decode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_vp9std_decode 1 +#include "vulkan_video_codec_vp9std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_vp9_decode" +typedef struct StdVideoDecodeVP9PictureInfoFlags { + uint32_t error_resilient_mode : 1; + uint32_t intra_only : 1; + uint32_t allow_high_precision_mv : 1; + uint32_t refresh_frame_context : 1; + uint32_t frame_parallel_decoding_mode : 1; + uint32_t segmentation_enabled : 1; + uint32_t show_frame : 1; + uint32_t UsePrevFrameMvs : 1; + uint32_t reserved : 24; +} StdVideoDecodeVP9PictureInfoFlags; + +typedef struct StdVideoDecodeVP9PictureInfo { + StdVideoDecodeVP9PictureInfoFlags flags; + StdVideoVP9Profile profile; + StdVideoVP9FrameType frame_type; + uint8_t frame_context_idx; + uint8_t reset_frame_context; + uint8_t refresh_frame_flags; + uint8_t ref_frame_sign_bias_mask; + StdVideoVP9InterpolationFilter interpolation_filter; + uint8_t base_q_idx; + int8_t delta_q_y_dc; + int8_t delta_q_uv_dc; + int8_t delta_q_uv_ac; + uint8_t tile_cols_log2; + uint8_t tile_rows_log2; + uint16_t reserved1[3]; + const StdVideoVP9ColorConfig* pColorConfig; + const StdVideoVP9LoopFilter* pLoopFilter; + const StdVideoVP9Segmentation* pSegmentation; +} StdVideoDecodeVP9PictureInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video/khronos/vk_video/vulkan_video_codecs_common.h b/src/video/khronos/vk_video/vulkan_video_codecs_common.h index 5e6ef1db48..3c4d0553d0 100644 --- a/src/video/khronos/vk_video/vulkan_video_codecs_common.h +++ b/src/video/khronos/vk_video/vulkan_video_codecs_common.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODECS_COMMON_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/video/khronos/vulkan/vk_icd.h b/src/video/khronos/vulkan/vk_icd.h index 59204a3419..d71f5682ab 100644 --- a/src/video/khronos/vulkan/vk_icd.h +++ b/src/video/khronos/vulkan/vk_icd.h @@ -44,8 +44,9 @@ typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this // file directly, it won't be found. -#ifndef PFN_GetPhysicalDeviceProcAddr +#ifndef IS_DEFINED_PFN_GetPhysicalDeviceProcAddr typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); +#define IS_DEFINED_PFN_GetPhysicalDeviceProcAddr #endif // Typedefs for loader/ICD interface diff --git a/src/video/khronos/vulkan/vk_layer.h b/src/video/khronos/vulkan/vk_layer.h index 19d88fce4b..19cf5880c8 100644 --- a/src/video/khronos/vulkan/vk_layer.h +++ b/src/video/khronos/vulkan/vk_layer.h @@ -27,7 +27,10 @@ #define VK_CURRENT_CHAIN_VERSION 1 // Typedef for use in the interfaces below +#ifndef IS_DEFINED_PFN_GetPhysicalDeviceProcAddr typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); +#define IS_DEFINED_PFN_GetPhysicalDeviceProcAddr +#endif // Version negotiation values typedef enum VkNegotiateLayerStructType { diff --git a/src/video/khronos/vulkan/vk_platform.h b/src/video/khronos/vulkan/vk_platform.h index 7d3ecfd277..ad849d7ee3 100644 --- a/src/video/khronos/vulkan/vk_platform.h +++ b/src/video/khronos/vulkan/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright 2014-2024 The Khronos Group Inc. +** Copyright 2014-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/src/video/khronos/vulkan/vulkan.h b/src/video/khronos/vulkan/vulkan.h index ef94006bb3..2ed8d9c7ab 100644 --- a/src/video/khronos/vulkan/vulkan.h +++ b/src/video/khronos/vulkan/vulkan.h @@ -2,7 +2,7 @@ #define VULKAN_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -96,4 +96,8 @@ #include "vulkan_beta.h" #endif +#ifdef VK_USE_PLATFORM_OHOS +#include "vulkan_ohos.h" +#endif + #endif // VULKAN_H_ diff --git a/src/video/khronos/vulkan/vulkan_android.h b/src/video/khronos/vulkan/vulkan_android.h index 61ff40ba8c..1d8265e87e 100644 --- a/src/video/khronos/vulkan/vulkan_android.h +++ b/src/video/khronos/vulkan/vulkan_android.h @@ -2,7 +2,7 @@ #define VULKAN_ANDROID_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -35,12 +35,14 @@ typedef struct VkAndroidSurfaceCreateInfoKHR { typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_ANDROID_external_memory_android_hardware_buffer is a preprocessor guard. Do not pass it to API calls. @@ -109,16 +111,20 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(Vk typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID( VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID( VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer); #endif +#endif // VK_ANDROID_external_format_resolve is a preprocessor guard. Do not pass it to API calls. diff --git a/src/video/khronos/vulkan/vulkan_beta.h b/src/video/khronos/vulkan/vulkan_beta.h index df18b4042b..147a3f3cc1 100644 --- a/src/video/khronos/vulkan/vulkan_beta.h +++ b/src/video/khronos/vulkan/vulkan_beta.h @@ -2,7 +2,7 @@ #define VULKAN_BETA_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -53,13 +53,14 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR { // VK_AMDX_shader_enqueue is a preprocessor guard. Do not pass it to API calls. #define VK_AMDX_shader_enqueue 1 -#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 1 +#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 2 #define VK_AMDX_SHADER_ENQUEUE_EXTENSION_NAME "VK_AMDX_shader_enqueue" #define VK_SHADER_INDEX_UNUSED_AMDX (~0U) typedef struct VkPhysicalDeviceShaderEnqueueFeaturesAMDX { VkStructureType sType; void* pNext; VkBool32 shaderEnqueue; + VkBool32 shaderMeshEnqueue; } VkPhysicalDeviceShaderEnqueueFeaturesAMDX; typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX { @@ -70,12 +71,16 @@ typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX { uint32_t maxExecutionGraphShaderPayloadSize; uint32_t maxExecutionGraphShaderPayloadCount; uint32_t executionGraphDispatchAddressAlignment; + uint32_t maxExecutionGraphWorkgroupCount[3]; + uint32_t maxExecutionGraphWorkgroups; } VkPhysicalDeviceShaderEnqueuePropertiesAMDX; typedef struct VkExecutionGraphPipelineScratchSizeAMDX { VkStructureType sType; void* pNext; - VkDeviceSize size; + VkDeviceSize minSize; + VkDeviceSize maxSize; + VkDeviceSize sizeGranularity; } VkExecutionGraphPipelineScratchSizeAMDX; typedef struct VkExecutionGraphPipelineCreateInfoAMDX { @@ -115,15 +120,16 @@ typedef struct VkPipelineShaderStageNodeCreateInfoAMDX { uint32_t index; } VkPipelineShaderStageNodeCreateInfoAMDX; -typedef VkResult (VKAPI_PTR *PFN_vkCreateExecutionGraphPipelinesAMDX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex); -typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceAddress countInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateExecutionGraphPipelinesAMDX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex); +typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkPipeline executionGraph, VkDeviceAddress scratch, VkDeviceSize scratchSize); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, VkDeviceAddress countInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateExecutionGraphPipelinesAMDX( VkDevice device, VkPipelineCache pipelineCache, @@ -131,37 +137,159 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateExecutionGraphPipelinesAMDX( const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineScratchSizeAMDX( VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineNodeIndexAMDX( VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdInitializeGraphScratchMemoryAMDX( VkCommandBuffer commandBuffer, - VkDeviceAddress scratch); + VkPipeline executionGraph, + VkDeviceAddress scratch, + VkDeviceSize scratchSize); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphAMDX( VkCommandBuffer commandBuffer, VkDeviceAddress scratch, + VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectAMDX( VkCommandBuffer commandBuffer, VkDeviceAddress scratch, + VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectCountAMDX( VkCommandBuffer commandBuffer, VkDeviceAddress scratch, + VkDeviceSize scratchSize, VkDeviceAddress countInfo); #endif +#endif + + +// VK_NV_cuda_kernel_launch is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cuda_kernel_launch 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaModuleNV) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaFunctionNV) +#define VK_NV_CUDA_KERNEL_LAUNCH_SPEC_VERSION 2 +#define VK_NV_CUDA_KERNEL_LAUNCH_EXTENSION_NAME "VK_NV_cuda_kernel_launch" +typedef struct VkCudaModuleCreateInfoNV { + VkStructureType sType; + const void* pNext; + size_t dataSize; + const void* pData; +} VkCudaModuleCreateInfoNV; + +typedef struct VkCudaFunctionCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkCudaModuleNV module; + const char* pName; +} VkCudaFunctionCreateInfoNV; + +typedef struct VkCudaLaunchInfoNV { + VkStructureType sType; + const void* pNext; + VkCudaFunctionNV function; + uint32_t gridDimX; + uint32_t gridDimY; + uint32_t gridDimZ; + uint32_t blockDimX; + uint32_t blockDimY; + uint32_t blockDimZ; + uint32_t sharedMemBytes; + size_t paramCount; + const void* const * pParams; + size_t extraCount; + const void* const * pExtras; +} VkCudaLaunchInfoNV; + +typedef struct VkPhysicalDeviceCudaKernelLaunchFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cudaKernelLaunchFeatures; +} VkPhysicalDeviceCudaKernelLaunchFeaturesNV; + +typedef struct VkPhysicalDeviceCudaKernelLaunchPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t computeCapabilityMinor; + uint32_t computeCapabilityMajor; +} VkPhysicalDeviceCudaKernelLaunchPropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaModuleNV)(VkDevice device, const VkCudaModuleCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaModuleNV* pModule); +typedef VkResult (VKAPI_PTR *PFN_vkGetCudaModuleCacheNV)(VkDevice device, VkCudaModuleNV module, size_t* pCacheSize, void* pCacheData); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaFunctionNV)(VkDevice device, const VkCudaFunctionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaFunctionNV* pFunction); +typedef void (VKAPI_PTR *PFN_vkDestroyCudaModuleNV)(VkDevice device, VkCudaModuleNV module, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyCudaFunctionNV)(VkDevice device, VkCudaFunctionNV function, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdCudaLaunchKernelNV)(VkCommandBuffer commandBuffer, const VkCudaLaunchInfoNV* pLaunchInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaModuleNV( + VkDevice device, + const VkCudaModuleCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCudaModuleNV* pModule); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetCudaModuleCacheNV( + VkDevice device, + VkCudaModuleNV module, + size_t* pCacheSize, + void* pCacheData); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaFunctionNV( + VkDevice device, + const VkCudaFunctionCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCudaFunctionNV* pFunction); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyCudaModuleNV( + VkDevice device, + VkCudaModuleNV module, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyCudaFunctionNV( + VkDevice device, + VkCudaFunctionNV function, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCudaLaunchKernelNV( + VkCommandBuffer commandBuffer, + const VkCudaLaunchInfoNV* pLaunchInfo); +#endif +#endif // VK_NV_displacement_micromap is a preprocessor guard. Do not pass it to API calls. @@ -209,6 +337,37 @@ typedef struct VkAccelerationStructureTrianglesDisplacementMicromapNV { } VkAccelerationStructureTrianglesDisplacementMicromapNV; + +// VK_AMDX_dense_geometry_format is a preprocessor guard. Do not pass it to API calls. +#define VK_AMDX_dense_geometry_format 1 +#define VK_AMDX_DENSE_GEOMETRY_FORMAT_SPEC_VERSION 1 +#define VK_AMDX_DENSE_GEOMETRY_FORMAT_EXTENSION_NAME "VK_AMDX_dense_geometry_format" +#define VK_COMPRESSED_TRIANGLE_FORMAT_DGF1_BYTE_ALIGNMENT_AMDX 128U +#define VK_COMPRESSED_TRIANGLE_FORMAT_DGF1_BYTE_STRIDE_AMDX 128U + +typedef enum VkCompressedTriangleFormatAMDX { + VK_COMPRESSED_TRIANGLE_FORMAT_DGF1_AMDX = 0, + VK_COMPRESSED_TRIANGLE_FORMAT_MAX_ENUM_AMDX = 0x7FFFFFFF +} VkCompressedTriangleFormatAMDX; +typedef struct VkPhysicalDeviceDenseGeometryFormatFeaturesAMDX { + VkStructureType sType; + void* pNext; + VkBool32 denseGeometryFormat; +} VkPhysicalDeviceDenseGeometryFormatFeaturesAMDX; + +typedef struct VkAccelerationStructureDenseGeometryFormatTrianglesDataAMDX { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR compressedData; + VkDeviceSize dataSize; + uint32_t numTriangles; + uint32_t numVertices; + uint32_t maxPrimitiveIndex; + uint32_t maxGeometryIndex; + VkCompressedTriangleFormatAMDX format; +} VkAccelerationStructureDenseGeometryFormatTrianglesDataAMDX; + + #ifdef __cplusplus } #endif diff --git a/src/video/khronos/vulkan/vulkan_core.h b/src/video/khronos/vulkan/vulkan_core.h index dd46027dff..2f659a47e9 100644 --- a/src/video/khronos/vulkan/vulkan_core.h +++ b/src/video/khronos/vulkan/vulkan_core.h @@ -2,7 +2,7 @@ #define VULKAN_CORE_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -62,42 +62,40 @@ extern "C" { #define VK_MAKE_API_VERSION(variant, major, minor, patch) \ ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) -// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. + //#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0 -// Vulkan 1.0 version number -#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 - // Version of this file -#define VK_HEADER_VERSION 282 +#define VK_HEADER_VERSION 352 // Complete version of this file -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 4, VK_HEADER_VERSION) + -// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. #define VK_MAKE_VERSION(major, minor, patch) \ ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) -// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. + #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22U) -// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. + #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) -// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. + #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) #define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U) #define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU) #define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) #define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) +// Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 + typedef uint32_t VkBool32; typedef uint64_t VkDeviceAddress; typedef uint64_t VkDeviceSize; typedef uint32_t VkFlags; typedef uint32_t VkSampleMask; -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) VK_DEFINE_HANDLE(VkInstance) VK_DEFINE_HANDLE(VkPhysicalDevice) VK_DEFINE_HANDLE(VkDevice) @@ -106,28 +104,28 @@ 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(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) -#define VK_ATTACHMENT_UNUSED (~0U) #define VK_FALSE 0U #define VK_LOD_CLAMP_NONE 1000.0F #define VK_QUEUE_FAMILY_IGNORED (~0U) #define VK_REMAINING_ARRAY_LAYERS (~0U) #define VK_REMAINING_MIP_LEVELS (~0U) -#define VK_SUBPASS_EXTERNAL (~0U) #define VK_TRUE 1U #define VK_WHOLE_SIZE (~0ULL) #define VK_MAX_MEMORY_TYPES 32U @@ -136,6 +134,8 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) #define VK_MAX_EXTENSION_NAME_SIZE 256U #define VK_MAX_DESCRIPTION_SIZE 256U #define VK_MAX_MEMORY_HEAPS 16U +#define VK_ATTACHMENT_UNUSED (~0U) +#define VK_SUBPASS_EXTERNAL (~0U) typedef enum VkResult { VK_SUCCESS = 0, @@ -157,17 +157,18 @@ typedef enum VkResult { VK_ERROR_FORMAT_NOT_SUPPORTED = -11, VK_ERROR_FRAGMENTED_POOL = -12, VK_ERROR_UNKNOWN = -13, + VK_ERROR_VALIDATION_FAILED = -1000011001, VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, - VK_ERROR_FRAGMENTATION = -1000161000, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_ERROR_FRAGMENTATION = -1000161000, VK_PIPELINE_COMPILE_REQUIRED = 1000297000, + VK_ERROR_NOT_PERMITTED = -1000174001, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, VK_ERROR_OUT_OF_DATE_KHR = -1000001004, VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, - VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR = -1000023000, VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR = -1000023001, @@ -176,7 +177,7 @@ typedef enum VkResult { VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR = -1000023004, VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR = -1000023005, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_NOT_PERMITTED_KHR = -1000174001, + VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT = -1000208000, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, VK_THREAD_IDLE_KHR = 1000268000, VK_THREAD_DONE_KHR = 1000268001, @@ -185,14 +186,19 @@ typedef enum VkResult { VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR = -1000299000, VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000, VK_INCOMPATIBLE_SHADER_BINARY_EXT = 1000482000, + VK_PIPELINE_BINARY_MISSING_KHR = 1000483000, + VK_ERROR_NOT_ENOUGH_SPACE_KHR = -1000483000, + VK_ERROR_VALIDATION_FAILED_EXT = VK_ERROR_VALIDATION_FAILED, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, - VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, + VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED, + VK_ERROR_NOT_PERMITTED_KHR = VK_ERROR_NOT_PERMITTED, VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + // VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT is a legacy alias VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT = VK_INCOMPATIBLE_SHADER_BINARY_EXT, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -247,14 +253,11 @@ typedef enum VkStructureType { 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_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, @@ -276,25 +279,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, - VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, - VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, - VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, - VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, @@ -309,47 +298,33 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, @@ -362,16 +337,43 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, @@ -380,19 +382,25 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, @@ -400,20 +408,68 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, - VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES = 55, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_PROPERTIES = 56, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES = 1000388001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES = 1000265000, + VK_STRUCTURE_TYPE_MEMORY_MAP_INFO = 1000271000, + VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO = 1000271001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES = 1000470000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES = 1000470001, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_SUBRESOURCE_INFO = 1000470004, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2 = 1000338002, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2 = 1000338003, + VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO = 1000470006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES = 1000545000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_PROPERTIES = 1000545001, + VK_STRUCTURE_TYPE_BIND_MEMORY_STATUS = 1000545002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES = 1000270000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES = 1000270001, + VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY = 1000270002, + VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY = 1000270003, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO = 1000270004, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO = 1000270005, + VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO = 1000270006, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO = 1000270007, + VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE = 1000270008, + VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY = 1000270009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES = 1000416000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES = 1000528000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES = 1000544000, + VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO = 1000470005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES = 1000080000, + VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO = 1000545003, + VK_STRUCTURE_TYPE_PUSH_CONSTANTS_INFO = 1000545004, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_INFO = 1000545005, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_INFO = 1000545006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES = 1000466000, + VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO = 1000068000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES = 1000068001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES = 1000068002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES = 1000259000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO = 1000259001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES = 1000259002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES = 1000525000, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO = 1000190001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES = 1000190002, + VK_STRUCTURE_TYPE_RENDERING_AREA_INFO = 1000470003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES = 1000232000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO = 1000232001, + VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO = 1000232002, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -464,6 +520,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX = 1000029000, VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX = 1000029001, VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX = 1000029002, + VK_STRUCTURE_TYPE_CU_MODULE_TEXTURING_MODE_CREATE_INFO_NVX = 1000029004, VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_KHR = 1000038000, @@ -501,10 +558,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR = 1000040005, VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR = 1000040006, VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, - VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, - VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, - VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, @@ -516,9 +569,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, - VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = 1000068000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = 1000068001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = 1000068002, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, @@ -533,7 +583,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, @@ -546,6 +595,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, + VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, @@ -590,6 +640,13 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GPA_FEATURES_AMD = 1000133000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GPA_PROPERTIES_AMD = 1000133001, + VK_STRUCTURE_TYPE_GPA_SAMPLE_BEGIN_INFO_AMD = 1000133002, + VK_STRUCTURE_TYPE_GPA_SESSION_CREATE_INFO_AMD = 1000133003, + VK_STRUCTURE_TYPE_GPA_DEVICE_CLOCK_MODE_INFO_AMD = 1000133004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GPA_PROPERTIES_2_AMD = 1000133005, + VK_STRUCTURE_TYPE_GPA_DEVICE_GET_CLOCK_INFO_AMD = 1000133006, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX = 1000134000, #endif @@ -605,6 +662,23 @@ typedef enum VkStructureType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NODE_CREATE_INFO_AMDX = 1000134004, #endif + VK_STRUCTURE_TYPE_TEXEL_BUFFER_DESCRIPTOR_INFO_EXT = 1000135000, + VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT = 1000135001, + VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT = 1000135002, + VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT = 1000135003, + VK_STRUCTURE_TYPE_PUSH_DATA_INFO_EXT = 1000135004, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_AND_BINDING_MAPPING_EXT = 1000135005, + VK_STRUCTURE_TYPE_SHADER_DESCRIPTOR_SET_AND_BINDING_MAPPING_INFO_EXT = 1000135006, + VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DATA_CREATE_INFO_EXT = 1000135007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT = 1000135008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT = 1000135009, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_DESCRIPTOR_HEAP_INFO_EXT = 1000135010, + VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_INDEX_CREATE_INFO_EXT = 1000135011, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_PUSH_DATA_TOKEN_NV = 1000135012, + VK_STRUCTURE_TYPE_SUBSAMPLED_IMAGE_FORMAT_PROPERTIES_EXT = 1000135013, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_TENSOR_PROPERTIES_ARM = 1000135014, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_BFLOAT16_FEATURES_KHR = 1000141000, VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, @@ -671,6 +745,8 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_CONVERSION_FEATURES_QCOM = 1000172000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ELAPSED_TIMER_QUERY_FEATURES_QCOM = 1000173000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, @@ -683,13 +759,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR = 1000187003, VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_KHR = 1000187004, VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR = 1000187005, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, @@ -697,6 +769,18 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT = 1000208000, + VK_STRUCTURE_TYPE_SWAPCHAIN_TIMING_PROPERTIES_EXT = 1000208001, + VK_STRUCTURE_TYPE_SWAPCHAIN_TIME_DOMAIN_PROPERTIES_EXT = 1000208002, + VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT = 1000208003, + VK_STRUCTURE_TYPE_PRESENT_TIMING_INFO_EXT = 1000208004, + VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_INFO_EXT = 1000208005, + VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_PROPERTIES_EXT = 1000208006, + VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT = 1000208007, + VK_STRUCTURE_TYPE_PRESENT_TIMING_SURFACE_CAPABILITIES_EXT = 1000208008, + VK_STRUCTURE_TYPE_SWAPCHAIN_CALIBRATED_TIMESTAMP_INFO_EXT = 1000208009, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, @@ -712,16 +796,19 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES_KHR = 1000232000, - VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR = 1000232001, - VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR = 1000232002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CONSTANT_DATA_FEATURES_KHR = 1000231000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_FEATURES_KHR = 1000233000, + VK_STRUCTURE_TYPE_DEVICE_FAULT_SHADER_ABORT_MESSAGE_INFO_KHR = 1000233001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_PROPERTIES_KHR = 1000233002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR = 1000235000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, @@ -756,31 +843,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT = 1000270000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT = 1000270001, - VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT = 1000270002, - VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT = 1000270003, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT = 1000270004, - VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT = 1000270005, - VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT = 1000270006, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO_EXT = 1000270007, - VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE_EXT = 1000270008, - VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT = 1000270009, - VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR = 1000271000, - VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR = 1000271001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT = 1000272000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT = 1000272001, VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT = 1000272002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT = 1000274000, - VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT = 1000274001, - VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT = 1000274002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT = 1000275000, - VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT = 1000275001, - VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT = 1000275002, - VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT = 1000275003, - VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT = 1000275004, - VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT = 1000275005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, @@ -800,11 +866,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT = 1000288000, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV = 1000292000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_BARRIER_NV = 1000292001, @@ -824,11 +889,35 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR = 1000299010, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, + VK_STRUCTURE_TYPE_PERF_HINT_INFO_QCOM = 1000302000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_FEATURES_QCOM = 1000302001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_PROPERTIES_QCOM = 1000302002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_3_FEATURES_QCOM = 1000303000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MULTIPLE_WAIT_QUEUES_FEATURES_QCOM = 1000304000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MULTIPLE_WAIT_QUEUES_PROPERTIES_QCOM = 1000304001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SPLIT_BARRIER_FEATURES_EXT = 1000305000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SPLIT_BARRIER_PROPERTIES_EXT = 1000305001, +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_CUDA_MODULE_CREATE_INFO_NV = 1000307000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_CUDA_FUNCTION_CREATE_INFO_NV = 1000307001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_CUDA_LAUNCH_INFO_NV = 1000307002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV = 1000307003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_PROPERTIES_NV = 1000307004, +#endif + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_FEATURES_QCOM = 1000309000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_PROPERTIES_QCOM = 1000309001, + VK_STRUCTURE_TYPE_RENDER_PASS_TILE_SHADING_CREATE_INFO_QCOM = 1000309002, + VK_STRUCTURE_TYPE_PER_TILE_BEGIN_INFO_QCOM = 1000309003, + VK_STRUCTURE_TYPE_PER_TILE_END_INFO_QCOM = 1000309004, + VK_STRUCTURE_TYPE_DISPATCH_TILE_INFO_QCOM = 1000309005, VK_STRUCTURE_TYPE_QUERY_LOW_LATENCY_SUPPORT_NV = 1000310000, VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000, VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001, @@ -842,8 +931,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT = 1000311009, VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311010, VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311011, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, - VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT = 1000316000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_DENSITY_MAP_PROPERTIES_EXT = 1000316001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT = 1000316002, @@ -857,6 +944,22 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT = 1000316011, VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_PUSH_DESCRIPTOR_BUFFER_HANDLE_EXT = 1000316012, VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316009, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_COPY_KHR = 1000318000, + VK_STRUCTURE_TYPE_COPY_DEVICE_MEMORY_INFO_KHR = 1000318001, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_IMAGE_COPY_KHR = 1000318002, + VK_STRUCTURE_TYPE_COPY_DEVICE_MEMORY_IMAGE_INFO_KHR = 1000318003, + VK_STRUCTURE_TYPE_MEMORY_RANGE_BARRIERS_INFO_KHR = 1000318004, + VK_STRUCTURE_TYPE_MEMORY_RANGE_BARRIER_KHR = 1000318005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_ADDRESS_COMMANDS_FEATURES_KHR = 1000318006, + VK_STRUCTURE_TYPE_BIND_INDEX_BUFFER_3_INFO_KHR = 1000318007, + VK_STRUCTURE_TYPE_BIND_VERTEX_BUFFER_3_INFO_KHR = 1000318008, + VK_STRUCTURE_TYPE_DRAW_INDIRECT_2_INFO_KHR = 1000318009, + VK_STRUCTURE_TYPE_DRAW_INDIRECT_COUNT_2_INFO_KHR = 1000318010, + VK_STRUCTURE_TYPE_DISPATCH_INDIRECT_2_INFO_KHR = 1000318011, + VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_2_EXT = 1000318012, + VK_STRUCTURE_TYPE_BIND_TRANSFORM_FEEDBACK_BUFFER_2_INFO_EXT = 1000318013, + VK_STRUCTURE_TYPE_MEMORY_MARKER_INFO_AMD = 1000318014, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_2_KHR = 1000318015, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, @@ -930,6 +1033,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR = 1000386000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR = 1000387000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_RGB_CONVERSION_FEATURES_VALVE = 1000390000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RGB_CONVERSION_CAPABILITIES_VALVE = 1000390001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_PROFILE_RGB_CONVERSION_INFO_VALVE = 1000390002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_RGB_CONVERSION_CREATE_INFO_VALVE = 1000390003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, @@ -963,32 +1071,29 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_ARM = 1000415000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR = 1000416000, VK_STRUCTURE_TYPE_DEVICE_QUEUE_SHADER_CORE_CONTROL_CREATE_INFO_ARM = 1000417000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM = 1000417001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_PROPERTIES_ARM = 1000417002, + VK_STRUCTURE_TYPE_DISPATCH_PARAMETERS_ARM = 1000417003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_DISPATCH_PARAMETERS_PROPERTIES_ARM = 1000417004, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT = 1000418000, VK_STRUCTURE_TYPE_IMAGE_VIEW_SLICED_CREATE_INFO_EXT = 1000418001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT = 1000421000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT = 1000422000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM = 1000424000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_PROPERTIES_ARM = 1000424001, VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_BEGIN_INFO_ARM = 1000424002, VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_INFO_ARM = 1000424003, VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_SUBMIT_INFO_ARM = 1000424004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, - VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV = 1000426000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_NV = 1000426001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_NV = 1000427000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_NV = 1000427001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV = 1000428000, VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_INDIRECT_BUFFER_INFO_NV = 1000428001, VK_STRUCTURE_TYPE_PIPELINE_INDIRECT_DEVICE_ADDRESS_INFO_NV = 1000428002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_LINEAR_SWEPT_SPHERES_FEATURES_NV = 1000429008, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_LINEAR_SWEPT_SPHERES_DATA_NV = 1000429009, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_SPHERES_DATA_NV = 1000429010, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR = 1000434000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000, @@ -997,6 +1102,12 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM = 1000440002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT = 1000451000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_PROPERTIES_EXT = 1000451001, + VK_STRUCTURE_TYPE_NATIVE_BUFFER_USAGE_OHOS = 1000452000, + VK_STRUCTURE_TYPE_NATIVE_BUFFER_PROPERTIES_OHOS = 1000452001, + VK_STRUCTURE_TYPE_NATIVE_BUFFER_FORMAT_PROPERTIES_OHOS = 1000452002, + VK_STRUCTURE_TYPE_IMPORT_NATIVE_BUFFER_INFO_OHOS = 1000452003, + VK_STRUCTURE_TYPE_MEMORY_GET_NATIVE_BUFFER_INFO_OHOS = 1000452004, + VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS = 1000452005, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXT = 1000453000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT = 1000455000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT = 1000455001, @@ -1006,6 +1117,30 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003, VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG = 1000459000, VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG = 1000459001, + VK_STRUCTURE_TYPE_TENSOR_CREATE_INFO_ARM = 1000460000, + VK_STRUCTURE_TYPE_TENSOR_VIEW_CREATE_INFO_ARM = 1000460001, + VK_STRUCTURE_TYPE_BIND_TENSOR_MEMORY_INFO_ARM = 1000460002, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_TENSOR_ARM = 1000460003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_PROPERTIES_ARM = 1000460004, + VK_STRUCTURE_TYPE_TENSOR_FORMAT_PROPERTIES_ARM = 1000460005, + VK_STRUCTURE_TYPE_TENSOR_DESCRIPTION_ARM = 1000460006, + VK_STRUCTURE_TYPE_TENSOR_MEMORY_REQUIREMENTS_INFO_ARM = 1000460007, + VK_STRUCTURE_TYPE_TENSOR_MEMORY_BARRIER_ARM = 1000460008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_FEATURES_ARM = 1000460009, + VK_STRUCTURE_TYPE_DEVICE_TENSOR_MEMORY_REQUIREMENTS_ARM = 1000460010, + VK_STRUCTURE_TYPE_COPY_TENSOR_INFO_ARM = 1000460011, + VK_STRUCTURE_TYPE_TENSOR_COPY_ARM = 1000460012, + VK_STRUCTURE_TYPE_TENSOR_DEPENDENCY_INFO_ARM = 1000460013, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_TENSOR_ARM = 1000460014, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_TENSOR_INFO_ARM = 1000460015, + VK_STRUCTURE_TYPE_EXTERNAL_TENSOR_PROPERTIES_ARM = 1000460016, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_TENSOR_CREATE_INFO_ARM = 1000460017, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_FEATURES_ARM = 1000460018, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_PROPERTIES_ARM = 1000460019, + VK_STRUCTURE_TYPE_DESCRIPTOR_GET_TENSOR_INFO_ARM = 1000460020, + VK_STRUCTURE_TYPE_TENSOR_CAPTURE_DESCRIPTOR_DATA_INFO_ARM = 1000460021, + VK_STRUCTURE_TYPE_TENSOR_VIEW_CAPTURE_DESCRIPTOR_DATA_INFO_ARM = 1000460022, + VK_STRUCTURE_TYPE_FRAME_BOUNDARY_TENSORS_ARM = 1000460023, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT = 1000462000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002, @@ -1019,38 +1154,70 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_OPTICAL_FLOW_EXECUTE_INFO_NV = 1000464005, VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_PRIVATE_DATA_INFO_NV = 1000464010, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT = 1000465000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT = 1000466000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID = 1000468000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_PROPERTIES_ANDROID = 1000468001, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_RESOLVE_PROPERTIES_ANDROID = 1000468002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR = 1000470000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES_KHR = 1000470001, - VK_STRUCTURE_TYPE_RENDERING_AREA_INFO_KHR = 1000470003, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_SUBRESOURCE_INFO_KHR = 1000470004, - VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR = 1000338002, - VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR = 1000338003, - VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR = 1000470005, - VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR = 1000470006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD = 1000476000, + VK_STRUCTURE_TYPE_ANTI_LAG_DATA_AMD = 1000476001, + VK_STRUCTURE_TYPE_ANTI_LAG_PRESENTATION_INFO_AMD = 1000476002, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DENSE_GEOMETRY_FORMAT_FEATURES_AMDX = 1000478000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DENSE_GEOMETRY_FORMAT_TRIANGLES_DATA_AMDX = 1000478001, +#endif + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_ID_2_KHR = 1000479000, + VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR = 1000479001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR = 1000479002, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_WAIT_2_KHR = 1000480000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR = 1000480001, + VK_STRUCTURE_TYPE_PRESENT_WAIT_2_INFO_KHR = 1000480002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR = 1000481000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT = 1000482000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT = 1000482001, VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT = 1000482002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR = 1000483000, + VK_STRUCTURE_TYPE_PIPELINE_BINARY_CREATE_INFO_KHR = 1000483001, + VK_STRUCTURE_TYPE_PIPELINE_BINARY_INFO_KHR = 1000483002, + VK_STRUCTURE_TYPE_PIPELINE_BINARY_KEY_KHR = 1000483003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_PROPERTIES_KHR = 1000483004, + VK_STRUCTURE_TYPE_RELEASE_CAPTURED_PIPELINE_DATA_INFO_KHR = 1000483005, + VK_STRUCTURE_TYPE_PIPELINE_BINARY_DATA_INFO_KHR = 1000483006, + VK_STRUCTURE_TYPE_PIPELINE_CREATE_INFO_KHR = 1000483007, + VK_STRUCTURE_TYPE_DEVICE_PIPELINE_BINARY_INTERNAL_CACHE_CONTROL_KHR = 1000483008, + VK_STRUCTURE_TYPE_PIPELINE_BINARY_HANDLES_INFO_KHR = 1000483009, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000, VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000, VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC = 1000485001, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_KHR = 1000274000, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_KHR = 1000274001, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_KHR = 1000274002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR = 1000275000, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_KHR = 1000275001, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_KHR = 1000275002, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_KHR = 1000275003, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_KHR = 1000275004, + VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_KHR = 1000275005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM = 1000488000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV = 1000490000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_PROPERTIES_NV = 1000490001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV = 1000491000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_PROPERTIES_NV = 1000491001, + VK_STRUCTURE_TYPE_COOPERATIVE_VECTOR_PROPERTIES_NV = 1000491002, + VK_STRUCTURE_TYPE_CONVERT_COOPERATIVE_VECTOR_MATRIX_INFO_NV = 1000491004, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV = 1000492000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_PROPERTIES_NV = 1000492001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT = 1000351000, VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT = 1000351002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT = 1000495000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_PROPERTIES_EXT = 1000495001, VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT = 1000496000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM = 1000497000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM = 1000497001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT = 1000498000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT = 1000499000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR = 1000504000, VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV = 1000505000, VK_STRUCTURE_TYPE_LATENCY_SLEEP_INFO_NV = 1000505001, VK_STRUCTURE_TYPE_SET_LATENCY_MARKER_INFO_NV = 1000505002, @@ -1063,13 +1230,51 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR = 1000506000, VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_KHR = 1000506001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_KHR = 1000506002, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_CREATE_INFO_ARM = 1000507000, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_CREATE_INFO_ARM = 1000507001, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_RESOURCE_INFO_ARM = 1000507002, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_CONSTANT_ARM = 1000507003, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_MEMORY_REQUIREMENTS_INFO_ARM = 1000507004, + VK_STRUCTURE_TYPE_BIND_DATA_GRAPH_PIPELINE_SESSION_MEMORY_INFO_ARM = 1000507005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_FEATURES_ARM = 1000507006, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SHADER_MODULE_CREATE_INFO_ARM = 1000507007, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_PROPERTY_QUERY_RESULT_ARM = 1000507008, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_INFO_ARM = 1000507009, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_COMPILER_CONTROL_CREATE_INFO_ARM = 1000507010, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_REQUIREMENTS_INFO_ARM = 1000507011, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_REQUIREMENT_ARM = 1000507012, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_IDENTIFIER_CREATE_INFO_ARM = 1000507013, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_DISPATCH_INFO_ARM = 1000507014, + VK_STRUCTURE_TYPE_DATA_GRAPH_PROCESSING_ENGINE_CREATE_INFO_ARM = 1000507016, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROCESSING_ENGINE_PROPERTIES_ARM = 1000507017, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROPERTIES_ARM = 1000507018, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_FAMILY_DATA_GRAPH_PROCESSING_ENGINE_INFO_ARM = 1000507019, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_CONSTANT_TENSOR_SEMI_STRUCTURED_SPARSITY_INFO_ARM = 1000507015, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_TOSA_PROPERTIES_ARM = 1000508000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM = 1000510000, VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM = 1000510001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR = 1000201000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_PROPERTIES_KHR = 1000511000, VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR = 1000512000, VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PICTURE_INFO_KHR = 1000512001, VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR = 1000512003, VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000512004, VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR = 1000512005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR = 1000513000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000513001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR = 1000513002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_DPB_SLOT_INFO_KHR = 1000513003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR = 1000513004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR = 1000513005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_INFO_KHR = 1000513006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR = 1000513007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_QUALITY_LEVEL_PROPERTIES_KHR = 1000513008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_SESSION_CREATE_INFO_KHR = 1000513009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_GOP_REMAINING_FRAME_INFO_KHR = 1000513010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR = 1000514000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_CAPABILITIES_KHR = 1000514001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PICTURE_INFO_KHR = 1000514002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR = 1000514003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR = 1000515000, VK_STRUCTURE_TYPE_VIDEO_INLINE_QUERY_INFO_KHR = 1000515001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV = 1000516000, @@ -1083,44 +1288,200 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_YCBCR_DEGAMMA_CREATE_INFO_QCOM = 1000520001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM = 1000521000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT = 1000524000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_KHR = 1000525000, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR = 1000190001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR = 1000190002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES_KHR = 1000528000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR = 1000527000, + VK_STRUCTURE_TYPE_ATTACHMENT_FEEDBACK_LOOP_INFO_EXT = 1000527001, VK_STRUCTURE_TYPE_SCREEN_BUFFER_PROPERTIES_QNX = 1000529000, VK_STRUCTURE_TYPE_SCREEN_BUFFER_FORMAT_PROPERTIES_QNX = 1000529001, VK_STRUCTURE_TYPE_IMPORT_SCREEN_BUFFER_INFO_QNX = 1000529002, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_QNX = 1000529003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX = 1000529004, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT = 1000530000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_KHR = 1000265000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_KHR = 1000259000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_KHR = 1000259001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_KHR = 1000259002, VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_KHR = 1000184000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR = 1000544000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR = 1000545000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_PROPERTIES_KHR = 1000545001, - VK_STRUCTURE_TYPE_BIND_MEMORY_STATUS_KHR = 1000545002, - VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO_KHR = 1000545003, - VK_STRUCTURE_TYPE_PUSH_CONSTANTS_INFO_KHR = 1000545004, - VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_INFO_KHR = 1000545005, - VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_INFO_KHR = 1000545006, VK_STRUCTURE_TYPE_SET_DESCRIPTOR_BUFFER_OFFSETS_INFO_EXT = 1000545007, VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_BUFFER_EMBEDDED_SAMPLERS_INFO_EXT = 1000545008, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV = 1000546000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM = 1000547000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_PROPERTIES_QCOM = 1000547001, + VK_STRUCTURE_TYPE_TILE_MEMORY_REQUIREMENTS_QCOM = 1000547002, + VK_STRUCTURE_TYPE_TILE_MEMORY_BIND_INFO_QCOM = 1000547003, + VK_STRUCTURE_TYPE_TILE_MEMORY_SIZE_INFO_QCOM = 1000547004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_KHR = 1000549000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_KHR = 1000426001, + VK_STRUCTURE_TYPE_COPY_MEMORY_INDIRECT_INFO_KHR = 1000549002, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INDIRECT_INFO_KHR = 1000549003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT = 1000427000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_EXT = 1000427001, + VK_STRUCTURE_TYPE_DECOMPRESS_MEMORY_INFO_EXT = 1000550002, + VK_STRUCTURE_TYPE_DISPLAY_SURFACE_STEREO_CREATE_INFO_NV = 1000551000, + VK_STRUCTURE_TYPE_DISPLAY_MODE_STEREO_PROPERTIES_NV = 1000551001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_INTRA_REFRESH_CAPABILITIES_KHR = 1000552000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_INTRA_REFRESH_CREATE_INFO_KHR = 1000552001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_INTRA_REFRESH_INFO_KHR = 1000552002, + VK_STRUCTURE_TYPE_VIDEO_REFERENCE_INTRA_REFRESH_INFO_KHR = 1000552003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_INTRA_REFRESH_FEATURES_KHR = 1000552004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUANTIZATION_MAP_CAPABILITIES_KHR = 1000553000, + VK_STRUCTURE_TYPE_VIDEO_FORMAT_QUANTIZATION_MAP_PROPERTIES_KHR = 1000553001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUANTIZATION_MAP_INFO_KHR = 1000553002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUANTIZATION_MAP_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000553005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUANTIZATION_MAP_FEATURES_KHR = 1000553009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_QUANTIZATION_MAP_CAPABILITIES_KHR = 1000553003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_QUANTIZATION_MAP_CAPABILITIES_KHR = 1000553004, + VK_STRUCTURE_TYPE_VIDEO_FORMAT_H265_QUANTIZATION_MAP_PROPERTIES_KHR = 1000553006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_QUANTIZATION_MAP_CAPABILITIES_KHR = 1000553007, + VK_STRUCTURE_TYPE_VIDEO_FORMAT_AV1_QUANTIZATION_MAP_PROPERTIES_KHR = 1000553008, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV = 1000555000, + VK_STRUCTURE_TYPE_EXTERNAL_COMPUTE_QUEUE_DEVICE_CREATE_INFO_NV = 1000556000, + VK_STRUCTURE_TYPE_EXTERNAL_COMPUTE_QUEUE_CREATE_INFO_NV = 1000556001, + VK_STRUCTURE_TYPE_EXTERNAL_COMPUTE_QUEUE_DATA_PARAMS_NV = 1000556002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_COMPUTE_QUEUE_PROPERTIES_NV = 1000556003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR = 1000558000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV = 1000559000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR = 1000562000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_PROPERTIES_KHR = 1000562001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_API_PROPERTIES_LIST_KHR = 1000562002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_API_PROPERTIES_KHR = 1000562003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_API_VULKAN_PROPERTIES_KHR = 1000562004, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV = 1000563000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT = 1000564000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT8_FEATURES_EXT = 1000567000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV = 1000568000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_FEATURES_NV = 1000569000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_PROPERTIES_NV = 1000569001, + VK_STRUCTURE_TYPE_CLUSTER_ACCELERATION_STRUCTURE_CLUSTERS_BOTTOM_LEVEL_INPUT_NV = 1000569002, + VK_STRUCTURE_TYPE_CLUSTER_ACCELERATION_STRUCTURE_TRIANGLE_CLUSTER_INPUT_NV = 1000569003, + VK_STRUCTURE_TYPE_CLUSTER_ACCELERATION_STRUCTURE_MOVE_OBJECTS_INPUT_NV = 1000569004, + VK_STRUCTURE_TYPE_CLUSTER_ACCELERATION_STRUCTURE_INPUT_INFO_NV = 1000569005, + VK_STRUCTURE_TYPE_CLUSTER_ACCELERATION_STRUCTURE_COMMANDS_INFO_NV = 1000569006, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CLUSTER_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000569007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_FEATURES_NV = 1000570000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_PROPERTIES_NV = 1000570001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_PARTITIONED_ACCELERATION_STRUCTURE_NV = 1000570002, + VK_STRUCTURE_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCES_INPUT_NV = 1000570003, + VK_STRUCTURE_TYPE_BUILD_PARTITIONED_ACCELERATION_STRUCTURE_INFO_NV = 1000570004, + VK_STRUCTURE_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_FLAGS_NV = 1000570005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_EXT = 1000572000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_EXT = 1000572001, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_EXT = 1000572002, + VK_STRUCTURE_TYPE_INDIRECT_EXECUTION_SET_CREATE_INFO_EXT = 1000572003, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_EXT = 1000572004, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_EXT = 1000572006, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_EXT = 1000572007, + VK_STRUCTURE_TYPE_WRITE_INDIRECT_EXECUTION_SET_PIPELINE_EXT = 1000572008, + VK_STRUCTURE_TYPE_WRITE_INDIRECT_EXECUTION_SET_SHADER_EXT = 1000572009, + VK_STRUCTURE_TYPE_INDIRECT_EXECUTION_SET_PIPELINE_INFO_EXT = 1000572010, + VK_STRUCTURE_TYPE_INDIRECT_EXECUTION_SET_SHADER_INFO_EXT = 1000572011, + VK_STRUCTURE_TYPE_INDIRECT_EXECUTION_SET_SHADER_LAYOUT_INFO_EXT = 1000572012, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_PIPELINE_INFO_EXT = 1000572013, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_SHADER_INFO_EXT = 1000572014, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_KHR = 1000573000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_PROPERTIES_KHR = 1000573001, + VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_KHR = 1000573002, + VK_STRUCTURE_TYPE_DEVICE_FAULT_DEBUG_INFO_KHR = 1000573003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR = 1000574000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_ACCESS_FLAGS_3_KHR = 1000574002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA = 1000575000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_PROPERTIES_MESA = 1000575001, + VK_STRUCTURE_TYPE_IMAGE_ALIGNMENT_CONTROL_CREATE_INFO_MESA = 1000575002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR = 1000579000, + VK_STRUCTURE_TYPE_PUSH_CONSTANT_BANK_INFO_NV = 1000580000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_FEATURES_NV = 1000580001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_PROPERTIES_NV = 1000580002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_EXT = 1000581000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_PROPERTIES_EXT = 1000581001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_CONTROL_FEATURES_EXT = 1000582000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLAMP_CONTROL_CREATE_INFO_EXT = 1000582001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR = 1000584000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_PROPERTIES_KHR = 1000584001, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_OWNERSHIP_TRANSFER_PROPERTIES_KHR = 1000584002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR = 1000586000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_INLINE_SESSION_PARAMETERS_INFO_KHR = 1000586001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_INLINE_SESSION_PARAMETERS_INFO_KHR = 1000586002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_INLINE_SESSION_PARAMETERS_INFO_KHR = 1000586003, + VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS = 1000685000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI = 1000590000, + VK_STRUCTURE_TYPE_HDR_VIVID_DYNAMIC_METADATA_HUAWEI = 1000590001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV = 1000593000, + VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_FLEXIBLE_DIMENSIONS_PROPERTIES_NV = 1000593001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_PROPERTIES_NV = 1000593002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM = 1000596000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT = 1000602000, + VK_STRUCTURE_TYPE_MEMORY_METAL_HANDLE_PROPERTIES_EXT = 1000602001, + VK_STRUCTURE_TYPE_MEMORY_GET_METAL_HANDLE_INFO_EXT = 1000602002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR = 1000421000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_FEATURES_ARM = 1000605000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_PROPERTIES_ARM = 1000605001, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_ARM = 1000605002, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_ARM = 1000605003, + VK_STRUCTURE_TYPE_RENDER_PASS_PERFORMANCE_COUNTERS_BY_REGION_BEGIN_INFO_ARM = 1000605004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_FEATURES_ARM = 1000607000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_PROPERTIES_ARM = 1000607001, + VK_STRUCTURE_TYPE_SHADER_INSTRUMENTATION_CREATE_INFO_ARM = 1000607002, + VK_STRUCTURE_TYPE_SHADER_INSTRUMENTATION_METRIC_DESCRIPTION_ARM = 1000607003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_ROBUSTNESS_FEATURES_EXT = 1000608000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FORMAT_PACK_FEATURES_ARM = 1000609000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_FEATURES_VALVE = 1000611000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_PROPERTIES_VALVE = 1000611001, + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_DENSITY_MAP_LAYERED_CREATE_INFO_VALVE = 1000611002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR = 1000286000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_KHR = 1000286001, + VK_STRUCTURE_TYPE_SET_PRESENT_CONFIG_NV = 1000613000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV = 1000613001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT = 1000425000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_EXT = 1000425001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_EXT = 1000425002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT = 1000620000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR = 1000361000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_KHR = 1000623000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_PROPERTIES_KHR = 1000623001, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MICROMAP_DATA_KHR = 1000623002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_KHR = 1000623003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_64_BIT_INDEXING_FEATURES_EXT = 1000627000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_RESOLVE_FEATURES_EXT = 1000628000, + VK_STRUCTURE_TYPE_BEGIN_CUSTOM_RESOLVE_INFO_EXT = 1000628001, + VK_STRUCTURE_TYPE_CUSTOM_RESOLVE_CREATE_INFO_EXT = 1000628002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_MODEL_FEATURES_QCOM = 1000629000, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_BUILTIN_MODEL_CREATE_INFO_QCOM = 1000629001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_FEATURES_KHR = 1000630000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_PROPERTIES_KHR = 1000630001, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_FLAGS_INFO_KHR = 1000630002, + VK_STRUCTURE_TYPE_RENDERING_END_INFO_KHR = 1000619003, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_MODE_INFO_KHR = 1000630004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_OPTICAL_FLOW_FEATURES_ARM = 1000631000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_OPTICAL_FLOW_PROPERTIES_ARM = 1000631001, + VK_STRUCTURE_TYPE_DATA_GRAPH_OPTICAL_FLOW_IMAGE_FORMAT_INFO_ARM = 1000631003, + VK_STRUCTURE_TYPE_DATA_GRAPH_OPTICAL_FLOW_IMAGE_FORMAT_PROPERTIES_ARM = 1000631004, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_OPTICAL_FLOW_DISPATCH_INFO_ARM = 1000631005, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_OPTICAL_FLOW_CREATE_INFO_ARM = 1000631002, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_RESOURCE_INFO_IMAGE_LAYOUT_ARM = 1000631006, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SINGLE_NODE_CREATE_INFO_ARM = 1000631007, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SINGLE_NODE_CONNECTION_ARM = 1000631008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT = 1000635000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_PROPERTIES_EXT = 1000635001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CACHE_INCREMENTAL_MODE_FEATURES_SEC = 1000637000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_FEATURES_EXT = 1000642000, + VK_STRUCTURE_TYPE_COMPUTE_OCCUPANCY_PRIORITY_PARAMETERS_NV = 1000645000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_OCCUPANCY_PRIORITY_FEATURES_NV = 1000645001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR = 1000657000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_OPTIMAL_IMAGE_TRANSFER_GRANULARITY_PROPERTIES_KHR = 1000657001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT = 1000662000, + VK_STRUCTURE_TYPE_UBM_SURFACE_CREATE_INFO_SEC = 1000664000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE = 1000673000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC = 1000674000, + VK_STRUCTURE_TYPE_THROTTLE_HINT_SUBMIT_INFO_SEC = 1000674001, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_NEURAL_STATISTICS_CREATE_INFO_ARM = 1000676000, + VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_NEURAL_STATISTICS_CREATE_INFO_ARM = 1000676001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM = 1000676002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT = 1000678000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_DECODE_VECTOR_FEATURES_NV = 1000689000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, + // VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT is a legacy alias VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, - VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, @@ -1141,6 +1502,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, @@ -1154,10 +1518,12 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + // VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT is a legacy alias VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, @@ -1193,6 +1559,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, @@ -1208,18 +1575,22 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_KHR, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, @@ -1227,6 +1598,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, + // VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL is a legacy alias VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, @@ -1234,6 +1606,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO, + VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, @@ -1247,15 +1622,38 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_KHR, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES, + VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY, + VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO, + VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO_EXT = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO, + VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE_EXT = VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE, + VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT = VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY, + VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO, + VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_KHR, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT = VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_KHR, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_KHR, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_KHR, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_KHR, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_KHR, + VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, @@ -1281,70 +1679,58 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, - VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR, - VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR, VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_EXT, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES, + VK_STRUCTURE_TYPE_RENDERING_AREA_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_AREA_INFO, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_SUBRESOURCE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_SUBRESOURCE_INFO, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR = VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2, + VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO, + VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO, VK_STRUCTURE_TYPE_SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_PROPERTIES, + VK_STRUCTURE_TYPE_BIND_MEMORY_STATUS_KHR = VK_STRUCTURE_TYPE_BIND_MEMORY_STATUS, + VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO_KHR = VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO, + VK_STRUCTURE_TYPE_PUSH_CONSTANTS_INFO_KHR = VK_STRUCTURE_TYPE_PUSH_CONSTANTS_INFO, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_INFO_KHR = VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_INFO, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_INFO_KHR = VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_INFO, + VK_STRUCTURE_TYPE_RENDERING_END_INFO_EXT = VK_STRUCTURE_TYPE_RENDERING_END_INFO_KHR, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; - -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_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, - VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, - VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, - VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001, - VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002, - VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, - VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, - VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003, - VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR = 1000232000, - VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000, - VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001, - VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, - VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF -} VkImageLayout; - typedef enum VkObjectType { VK_OBJECT_TYPE_UNKNOWN = 0, VK_OBJECT_TYPE_INSTANCE = 1, @@ -1372,8 +1758,8 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, VK_OBJECT_TYPE_FRAMEBUFFER = 24, VK_OBJECT_TYPE_COMMAND_POOL = 25, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, @@ -1385,18 +1771,31 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000, VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001, VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, + VK_OBJECT_TYPE_GPA_SESSION_AMD = 1000133000, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_OBJECT_TYPE_CUDA_MODULE_NV = 1000307000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS VK_OBJECT_TYPE_CUDA_FUNCTION_NV = 1000307001, +#endif VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000, + VK_OBJECT_TYPE_TENSOR_ARM = 1000460000, + VK_OBJECT_TYPE_TENSOR_VIEW_ARM = 1000460001, VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000, VK_OBJECT_TYPE_SHADER_EXT = 1000482000, + VK_OBJECT_TYPE_PIPELINE_BINARY_KHR = 1000483000, + VK_OBJECT_TYPE_DATA_GRAPH_PIPELINE_SESSION_ARM = 1000507000, + VK_OBJECT_TYPE_EXTERNAL_COMPUTE_QUEUE_NV = 1000556000, + VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT = 1000572000, + VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT = 1000572001, + VK_OBJECT_TYPE_SHADER_INSTRUMENTATION_ARM = 1000607000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, @@ -1404,6 +1803,7 @@ typedef enum VkObjectType { } VkObjectType; typedef enum VkVendorId { + VK_VENDOR_ID_KHRONOS = 0x10000, VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VSI = 0x10002, VK_VENDOR_ID_KAZAN = 0x10003, @@ -1668,6 +2068,8 @@ typedef enum VkFormat { VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, + VK_FORMAT_A1B5G5R5_UNORM_PACK16 = 1000470000, + VK_FORMAT_A8_UNORM = 1000470001, VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1676,9 +2078,55 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, + VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT = 1000288000, + VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT = 1000288001, + VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT = 1000288002, + VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT = 1000288003, + VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT = 1000288004, + VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT = 1000288005, + VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT = 1000288006, + VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT = 1000288007, + VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT = 1000288008, + VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT = 1000288009, + VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT = 1000288010, + VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT = 1000288011, + VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT = 1000288012, + VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT = 1000288013, + VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT = 1000288014, + VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT = 1000288015, + VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT = 1000288016, + VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT = 1000288017, + VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT = 1000288018, + VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT = 1000288019, + VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT = 1000288020, + VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT = 1000288021, + VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT = 1000288022, + VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT = 1000288023, + VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT = 1000288024, + VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT = 1000288025, + VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT = 1000288026, + VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT = 1000288027, + VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT = 1000288028, + VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT = 1000288029, + VK_FORMAT_R8_BOOL_ARM = 1000460000, + VK_FORMAT_R16_SFLOAT_FPENCODING_BFLOAT16_ARM = 1000460001, + VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM = 1000460002, + VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E5M2_ARM = 1000460003, VK_FORMAT_R16G16_SFIXED5_NV = 1000464000, - VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = 1000470000, - VK_FORMAT_A8_UNORM_KHR = 1000470001, + VK_FORMAT_R10X6_UINT_PACK16_ARM = 1000609000, + VK_FORMAT_R10X6G10X6_UINT_2PACK16_ARM = 1000609001, + VK_FORMAT_R10X6G10X6B10X6A10X6_UINT_4PACK16_ARM = 1000609002, + VK_FORMAT_R12X4_UINT_PACK16_ARM = 1000609003, + VK_FORMAT_R12X4G12X4_UINT_2PACK16_ARM = 1000609004, + VK_FORMAT_R12X4G12X4B12X4A12X4_UINT_4PACK16_ARM = 1000609005, + VK_FORMAT_R14X2_UINT_PACK16_ARM = 1000609006, + VK_FORMAT_R14X2G14X2_UINT_2PACK16_ARM = 1000609007, + VK_FORMAT_R14X2G14X2B14X2A14X2_UINT_4PACK16_ARM = 1000609008, + VK_FORMAT_R14X2_UNORM_PACK16_ARM = 1000609009, + VK_FORMAT_R14X2G14X2_UNORM_2PACK16_ARM = 1000609010, + VK_FORMAT_R14X2G14X2B14X2A14X2_UNORM_4PACK16_ARM = 1000609011, + VK_FORMAT_G14X2_B14X2R14X2_2PLANE_420_UNORM_3PACK16_ARM = 1000609012, + VK_FORMAT_G14X2_B14X2R14X2_2PLANE_422_UNORM_3PACK16_ARM = 1000609013, VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, @@ -1733,7 +2181,10 @@ typedef enum VkFormat { VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, + // VK_FORMAT_R16G16_S10_5_NV is a legacy alias VK_FORMAT_R16G16_S10_5_NV = VK_FORMAT_R16G16_SFIXED5_NV, + VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = VK_FORMAT_A1B5G5R5_UNORM_PACK16, + VK_FORMAT_A8_UNORM_KHR = VK_FORMAT_A8_UNORM, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -1770,6 +2221,7 @@ typedef enum VkQueryType { VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000150000, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150001, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, + VK_QUERY_TYPE_TIME_ELAPSED_QCOM = 1000173000, VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR = 1000299000, VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT = 1000328000, @@ -1787,6 +2239,52 @@ typedef enum VkSharingMode { 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_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, + VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ = 1000232000, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, + VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001, + VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002, + VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, + VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000, + VK_IMAGE_LAYOUT_TENSOR_ALIASING_ARM = 1000460000, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR = 1000553000, + VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT = 1000620000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, + VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_IDENTITY = 0, VK_COMPONENT_SWIZZLE_ZERO = 1, @@ -1809,6 +2307,116 @@ typedef enum VkImageViewType { VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF } VkImageViewType; +typedef enum VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 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_UINT8 = 1000265000, + VK_INDEX_TYPE_NONE_KHR = 1000165000, + VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, + VK_INDEX_TYPE_UINT8_EXT = VK_INDEX_TYPE_UINT8, + VK_INDEX_TYPE_UINT8_KHR = VK_INDEX_TYPE_UINT8, + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkIndexType; + +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_DATA_GRAPH_QCOM = 1000629000, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + +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_FLOAT_CUSTOM_EXT = 1000287003, + VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF +} VkBorderColor; + +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_EXT = 1000015000, + VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT, + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +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_MIRROR_CLAMP_TO_EDGE_KHR is a legacy alias + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +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_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + +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_INLINE_UNIFORM_BLOCK = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000, + VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001, + VK_DESCRIPTOR_TYPE_TENSOR_ARM = 1000460000, + VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000, + VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV = 1000570000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, + VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = VK_DESCRIPTOR_TYPE_MUTABLE_EXT, + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +typedef enum VkPipelineBindPoint { + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_PIPELINE_BIND_POINT_EXECUTION_GRAPH_AMDX = 1000134000, +#endif + VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, + VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003, + VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM = 1000507000, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF +} VkPipelineBindPoint; + typedef enum VkBlendFactor { VK_BLEND_FACTOR_ZERO = 0, VK_BLEND_FACTOR_ONE = 1, @@ -1887,18 +2495,6 @@ typedef enum VkBlendOp { VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF } VkBlendOp; -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_MAX_ENUM = 0x7FFFFFFF -} VkCompareOp; - typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT = 0, VK_DYNAMIC_STATE_SCISSOR = 1, @@ -1924,6 +2520,7 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, + VK_DYNAMIC_STATE_LINE_STIPPLE = 1000259000, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT = 1000099001, @@ -1971,8 +2568,8 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV = 1000455031, VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV = 1000455032, VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT = 1000524000, - VK_DYNAMIC_STATE_LINE_STIPPLE_KHR = 1000259000, - VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = VK_DYNAMIC_STATE_LINE_STIPPLE_KHR, + VK_DYNAMIC_STATE_DEPTH_CLAMP_RANGE_EXT = 1000582000, + VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = VK_DYNAMIC_STATE_LINE_STIPPLE, VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, @@ -1988,6 +2585,7 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, + VK_DYNAMIC_STATE_LINE_STIPPLE_KHR = VK_DYNAMIC_STATE_LINE_STIPPLE, VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; @@ -1997,6 +2595,38 @@ typedef enum VkFrontFace { VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF } VkFrontFace; +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_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; + +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_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + typedef enum VkVertexInputRate { VK_VERTEX_INPUT_RATE_VERTEX = 0, VK_VERTEX_INPUT_RATE_INSTANCE = 1, @@ -2026,103 +2656,13 @@ typedef enum VkPolygonMode { VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF } VkPolygonMode; -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_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_MAX_ENUM = 0x7FFFFFFF -} VkLogicOp; - -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_FLOAT_CUSTOM_EXT = 1000287003, - VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, - VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF -} VkBorderColor; - -typedef enum VkFilter { - VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1, - VK_FILTER_CUBIC_EXT = 1000015000, - VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT, - VK_FILTER_MAX_ENUM = 0x7FFFFFFF -} VkFilter; - -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_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerAddressMode; - -typedef enum VkSamplerMipmapMode { - VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerMipmapMode; - -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_INLINE_UNIFORM_BLOCK = 1000138000, - VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, - VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000, - VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001, - VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, - VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = VK_DESCRIPTOR_TYPE_MUTABLE_EXT, - 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_NONE_KHR = 1000400000, - VK_ATTACHMENT_LOAD_OP_NONE_EXT = VK_ATTACHMENT_LOAD_OP_NONE_KHR, + VK_ATTACHMENT_LOAD_OP_NONE = 1000400000, + VK_ATTACHMENT_LOAD_OP_NONE_EXT = VK_ATTACHMENT_LOAD_OP_NONE, + VK_ATTACHMENT_LOAD_OP_NONE_KHR = VK_ATTACHMENT_LOAD_OP_NONE, VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentLoadOp; @@ -2136,100 +2676,14 @@ typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; -typedef enum VkPipelineBindPoint { - VK_PIPELINE_BIND_POINT_GRAPHICS = 0, - VK_PIPELINE_BIND_POINT_COMPUTE = 1, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_PIPELINE_BIND_POINT_EXECUTION_GRAPH_AMDX = 1000134000, -#endif - VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, - VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003, - VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, - 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_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferLevel; - -typedef enum VkIndexType { - VK_INDEX_TYPE_UINT16 = 0, - VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_NONE_KHR = 1000165000, - VK_INDEX_TYPE_UINT8_KHR = 1000265000, - VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, - VK_INDEX_TYPE_UINT8_EXT = VK_INDEX_TYPE_UINT8_KHR, - 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_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT = 1000451000, + VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR = 1000451000, + VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT = VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR, VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF } VkSubpassContents; -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, - VK_ACCESS_NONE = 0, - VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, - VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, - VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, - VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, - VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, - VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, - VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, - VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, - VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, - VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAccessFlagBits; -typedef VkFlags VkAccessFlags; - -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, - VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, - VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, - VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, - VK_IMAGE_ASPECT_NONE = 0, - VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, - VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, - VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, - VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, - VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, - VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, - VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, - VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageAspectFlagBits; -typedef VkFlags VkImageAspectFlags; - typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, @@ -2291,19 +2745,22 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, + VK_IMAGE_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_EXT = 0x00010000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, - VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00010000, VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000, VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, - VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR = 0x00100000, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT = 0x00008000, + VK_IMAGE_CREATE_ALIAS_SINGLE_LAYER_DESCRIPTOR_BIT_KHR = 0x00400000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT, VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT, + VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = VK_IMAGE_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_EXT, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT, VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageCreateFlagBits; typedef VkFlags VkImageCreateFlags; @@ -2329,12 +2786,12 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT = 0x00400000, VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00000400, VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800, VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100, - VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT = 0x00400000, VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000, VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000, VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, @@ -2342,7 +2799,12 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000, VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000, VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000, + VK_IMAGE_USAGE_TENSOR_ALIASING_BIT_ARM = 0x00800000, + VK_IMAGE_USAGE_TILE_MEMORY_BIT_QCOM = 0x08000000, + VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x02000000, + VK_IMAGE_USAGE_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR = 0x04000000, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT = VK_IMAGE_USAGE_HOST_TRANSFER_BIT, VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; @@ -2356,6 +2818,7 @@ typedef VkFlags VkInstanceCreateFlags; typedef enum VkMemoryHeapFlagBits { VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002, + VK_MEMORY_HEAP_TILE_MEMORY_BIT_QCOM = 0x00000008, VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT, VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryHeapFlagBits; @@ -2384,13 +2847,46 @@ typedef enum VkQueueFlagBits { VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020, VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040, VK_QUEUE_OPTICAL_FLOW_BIT_NV = 0x00000100, + VK_QUEUE_DATA_GRAPH_BIT_ARM = 0x00000400, VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueueFlagBits; typedef VkFlags VkQueueFlags; + +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 = 0x0000001F, + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, + VK_SHADER_STAGE_TASK_BIT_EXT = 0x00000040, + VK_SHADER_STAGE_MESH_BIT_EXT = 0x00000080, + VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000, + VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI = 0x00080000, + VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, + VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, + VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, + VK_SHADER_STAGE_TASK_BIT_NV = VK_SHADER_STAGE_TASK_BIT_EXT, + VK_SHADER_STAGE_MESH_BIT_NV = VK_SHADER_STAGE_MESH_BIT_EXT, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkShaderStageFlagBits; +typedef VkFlags VkShaderStageFlags; typedef VkFlags VkDeviceCreateFlags; typedef enum VkDeviceQueueCreateFlagBits { VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001, + VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR = 0x00000004, VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDeviceQueueCreateFlagBits; typedef VkFlags VkDeviceQueueCreateFlags; @@ -2420,14 +2916,15 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, - VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT = 0x00080000, VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT = 0x00100000, + VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_EXT = 0x00020000, VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT, + VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_EXT, VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; @@ -2439,11 +2936,26 @@ typedef enum VkMemoryMapFlagBits { } VkMemoryMapFlagBits; typedef VkFlags VkMemoryMapFlags; -typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, - VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseMemoryBindFlagBits; -typedef VkFlags VkSparseMemoryBindFlags; +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, + VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, + VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, + VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_NONE = 0, + VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, + VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, + VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, + VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, + VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, + VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, + VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; typedef enum VkSparseImageFormatFlagBits { VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, @@ -2453,6 +2965,12 @@ typedef enum VkSparseImageFormatFlagBits { } VkSparseImageFormatFlagBits; typedef VkFlags VkSparseImageFormatFlags; +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; + typedef enum VkFenceCreateFlagBits { VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF @@ -2460,12 +2978,11 @@ typedef enum VkFenceCreateFlagBits { typedef VkFlags VkFenceCreateFlags; typedef VkFlags VkSemaphoreCreateFlags; -typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, - VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, - VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkEventCreateFlagBits; -typedef VkFlags VkEventCreateFlags; +typedef enum VkQueryPoolCreateFlagBits { + VK_QUERY_POOL_CREATE_RESET_BIT_KHR = 0x00000001, + VK_QUERY_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryPoolCreateFlagBits; +typedef VkFlags VkQueryPoolCreateFlags; typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, @@ -2485,7 +3002,6 @@ typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryPipelineStatisticFlagBits; typedef VkFlags VkQueryPipelineStatisticFlags; -typedef VkFlags VkQueryPoolCreateFlags; typedef enum VkQueryResultFlagBits { VK_QUERY_RESULT_64_BIT = 0x00000001, @@ -2530,6 +3046,7 @@ typedef enum VkBufferUsageFlagBits { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_BUFFER_USAGE_EXECUTION_GRAPH_SCRATCH_BIT_AMDX = 0x02000000, #endif + VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT = 0x10000000, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400, @@ -2540,13 +3057,13 @@ typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT = 0x04000000, VK_BUFFER_USAGE_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000, VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT = 0x01000000, + VK_BUFFER_USAGE_TILE_MEMORY_BIT_QCOM = 0x08000000, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferUsageFlagBits; typedef VkFlags VkBufferUsageFlags; -typedef VkFlags VkBufferViewCreateFlags; typedef enum VkImageViewCreateFlagBits { VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, @@ -2555,34 +3072,121 @@ typedef enum VkImageViewCreateFlagBits { VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageViewCreateFlagBits; typedef VkFlags VkImageViewCreateFlags; + +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, + VK_ACCESS_NONE = 0, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, + VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, + VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, + VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_EXT = 0x00020000, + VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_EXT = 0x00040000, + VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_EXT, + VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_EXT, + VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; + +typedef enum VkDependencyFlagBits { + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, + VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, + VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, + VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008, + VK_DEPENDENCY_QUEUE_FAMILY_OWNERSHIP_TRANSFER_USE_ALL_STAGES_BIT_KHR = 0x00000020, + VK_DEPENDENCY_ASYMMETRIC_EVENT_BIT_KHR = 0x00000040, + VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, + VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDependencyFlagBits; +typedef VkFlags VkDependencyFlags; + +typedef enum VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, + VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolCreateFlagBits; +typedef VkFlags VkCommandPoolCreateFlags; + +typedef enum VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolResetFlagBits; +typedef VkFlags VkCommandPoolResetFlags; + +typedef enum VkQueryControlFlagBits { + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryControlFlagBits; +typedef VkFlags VkQueryControlFlags; + +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, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferUsageFlagBits; +typedef VkFlags VkCommandBufferUsageFlags; + +typedef enum VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferResetFlagBits; +typedef VkFlags VkCommandBufferResetFlags; + +typedef enum VkEventCreateFlagBits { + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, + VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkEventCreateFlagBits; +typedef VkFlags VkEventCreateFlags; +typedef VkFlags VkBufferViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef enum VkPipelineCacheCreateFlagBits { VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_INTERNALLY_SYNCHRONIZED_MERGE_BIT_KHR = 0x00000008, VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; -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, - VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkColorComponentFlagBits; -typedef VkFlags VkColorComponentFlags; - typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, - VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, + VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT = 0x08000000, + VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT = 0x40000000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, @@ -2591,6 +3195,8 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000, VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000, VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040, VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, @@ -2601,23 +3207,36 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000, VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000, - VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_PIPELINE_CREATE_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000, #endif - VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000, - VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000, + VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_KHR = 0x01000000, + // VK_PIPELINE_CREATE_DISPATCH_BASE is a legacy alias VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, - VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_DISPATCH_BASE_BIT_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + // VK_PIPELINE_CREATE_DISPATCH_BASE_KHR is a legacy alias + VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + // VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT is a legacy alias + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, + // VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR is a legacy alias + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, + VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_KHR, + VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT, + VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; +typedef enum VkPipelineLayoutCreateFlagBits { + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, + VK_PIPELINE_LAYOUT_CREATE_NO_TASK_SHADER_BIT_KHR = 0x00000004, + VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineLayoutCreateFlagBits; +typedef VkFlags VkPipelineLayoutCreateFlags; + typedef enum VkPipelineShaderStageCreateFlagBits { VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, @@ -2627,75 +3246,6 @@ typedef enum VkPipelineShaderStageCreateFlagBits { } VkPipelineShaderStageCreateFlagBits; 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 = 0x0000001F, - VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, - VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, - VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, - VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, - VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, - VK_SHADER_STAGE_TASK_BIT_EXT = 0x00000040, - VK_SHADER_STAGE_MESH_BIT_EXT = 0x00000080, - VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000, - VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI = 0x00080000, - VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, - VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, - VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, - VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, - VK_SHADER_STAGE_TASK_BIT_NV = VK_SHADER_STAGE_TASK_BIT_EXT, - VK_SHADER_STAGE_MESH_BIT_NV = VK_SHADER_STAGE_MESH_BIT_EXT, - VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkShaderStageFlagBits; - -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 = 0x00000003, - VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCullModeFlagBits; -typedef VkFlags VkCullModeFlags; -typedef VkFlags VkPipelineVertexInputStateCreateFlags; -typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; -typedef VkFlags VkPipelineTessellationStateCreateFlags; -typedef VkFlags VkPipelineViewportStateCreateFlags; -typedef VkFlags VkPipelineRasterizationStateCreateFlags; -typedef VkFlags VkPipelineMultisampleStateCreateFlags; - -typedef enum VkPipelineDepthStencilStateCreateFlagBits { - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000001, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000002, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineDepthStencilStateCreateFlagBits; -typedef VkFlags VkPipelineDepthStencilStateCreateFlags; - -typedef enum VkPipelineColorBlendStateCreateFlagBits { - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT = 0x00000001, - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT, - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineColorBlendStateCreateFlagBits; -typedef VkFlags VkPipelineColorBlendStateCreateFlags; -typedef VkFlags VkPipelineDynamicStateCreateFlags; - -typedef enum VkPipelineLayoutCreateFlagBits { - VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, - VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineLayoutCreateFlagBits; -typedef VkFlags VkPipelineLayoutCreateFlags; -typedef VkFlags VkShaderStageFlags; - typedef enum VkSamplerCreateFlagBits { VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, @@ -2721,35 +3271,68 @@ typedef VkFlags VkDescriptorPoolResetFlags; typedef enum VkDescriptorSetLayoutCreateFlagBits { VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT = 0x00000001, VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00000010, VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT = 0x00000020, VK_DESCRIPTOR_SET_LAYOUT_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00000080, VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT = 0x00000004, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PER_STAGE_BIT_NV = 0x00000040, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT, VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT, VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorSetLayoutCreateFlagBits; typedef VkFlags VkDescriptorSetLayoutCreateFlags; +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, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; + +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 = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCullModeFlagBits; +typedef VkFlags VkCullModeFlags; + +typedef enum VkPipelineColorBlendStateCreateFlagBits { + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT = 0x00000001, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineColorBlendStateCreateFlagBits; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; + +typedef enum VkPipelineDepthStencilStateCreateFlagBits { + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000001, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000002, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineDepthStencilStateCreateFlagBits; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; +typedef VkFlags VkPipelineDynamicStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; + typedef enum VkAttachmentDescriptionFlagBits { VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, + VK_ATTACHMENT_DESCRIPTION_RESOLVE_SKIP_TRANSFER_FUNCTION_BIT_KHR = 0x00000002, + VK_ATTACHMENT_DESCRIPTION_RESOLVE_ENABLE_TRANSFER_FUNCTION_BIT_KHR = 0x00000004, VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAttachmentDescriptionFlagBits; typedef VkFlags VkAttachmentDescriptionFlags; -typedef enum VkDependencyFlagBits { - VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, - VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, - VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, - VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008, - VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, - VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, - VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDependencyFlagBits; -typedef VkFlags VkDependencyFlags; - typedef enum VkFramebufferCreateFlagBits { VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, @@ -2759,6 +3342,7 @@ typedef VkFlags VkFramebufferCreateFlags; typedef enum VkRenderPassCreateFlagBits { VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002, + VK_RENDER_PASS_CREATE_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE = 0x00000004, VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkRenderPassCreateFlagBits; typedef VkFlags VkRenderPassCreateFlags; @@ -2766,12 +3350,15 @@ typedef VkFlags VkRenderPassCreateFlags; typedef enum VkSubpassDescriptionFlagBits { VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, - VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, - VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_TILE_SHADING_APRON_BIT_QCOM = 0x00000100, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT = 0x00000010, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000020, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000040, VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000080, + VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_EXT = 0x00000004, + VK_SUBPASS_DESCRIPTION_CUSTOM_RESOLVE_BIT_EXT = 0x00000008, + VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_EXT, + VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = VK_SUBPASS_DESCRIPTION_CUSTOM_RESOLVE_BIT_EXT, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT, VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT, @@ -2779,44 +3366,11 @@ typedef enum VkSubpassDescriptionFlagBits { } VkSubpassDescriptionFlagBits; typedef VkFlags VkSubpassDescriptionFlags; -typedef enum VkCommandPoolCreateFlagBits { - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, - VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, - VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolCreateFlagBits; -typedef VkFlags VkCommandPoolCreateFlags; - -typedef enum VkCommandPoolResetFlagBits { - VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} 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, - VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferUsageFlagBits; -typedef VkFlags VkCommandBufferUsageFlags; - -typedef enum VkQueryControlFlagBits { - VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, - VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryControlFlagBits; -typedef VkFlags VkQueryControlFlags; - -typedef enum VkCommandBufferResetFlagBits { - VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferResetFlagBits; -typedef VkFlags VkCommandBufferResetFlags; - typedef enum VkStencilFaceFlagBits { VK_STENCIL_FACE_FRONT_BIT = 0x00000001, VK_STENCIL_FACE_BACK_BIT = 0x00000002, VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, + // VK_STENCIL_FRONT_AND_BACK is a legacy alias VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkStencilFaceFlagBits; @@ -2858,75 +3412,6 @@ typedef struct VkBaseOutStructure { struct VkBaseOutStructure* pNext; } VkBaseOutStructure; -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 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 struct VkImageSubresourceRange { - VkImageAspectFlags aspectMask; - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceRange; - -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 VkMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; -} VkMemoryBarrier; - -typedef struct VkPipelineCacheHeaderVersionOne { - uint32_t headerSize; - VkPipelineCacheHeaderVersion headerVersion; - uint32_t vendorID; - uint32_t deviceID; - uint8_t pipelineCacheUUID[VK_UUID_SIZE]; -} VkPipelineCacheHeaderVersionOne; - typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( void* pUserData, size_t size, @@ -3227,7 +3712,9 @@ typedef struct VkDeviceCreateInfo { VkDeviceCreateFlags flags; uint32_t queueCreateInfoCount; const VkDeviceQueueCreateInfo* pQueueCreateInfos; + // enabledLayerCount is legacy and not used uint32_t enabledLayerCount; + // ppEnabledLayerNames is legacy and not used const char* const* ppEnabledLayerNames; uint32_t enabledExtensionCount; const char* const* ppEnabledExtensionNames; @@ -3279,6 +3766,41 @@ typedef struct VkMemoryRequirements { uint32_t memoryTypeBits; } VkMemoryRequirements; +typedef struct VkImageSubresource { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +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 VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + typedef struct VkSparseMemoryBind { VkDeviceSize resourceOffset; VkDeviceSize size; @@ -3299,27 +3821,6 @@ typedef struct VkSparseImageOpaqueMemoryBindInfo { const VkSparseMemoryBind* pBinds; } VkSparseImageOpaqueMemoryBindInfo; -typedef struct VkImageSubresource { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t arrayLayer; -} VkImageSubresource; - -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; @@ -3335,20 +3836,6 @@ typedef struct VkBindSparseInfo { const VkSemaphore* pSignalSemaphores; } VkBindSparseInfo; -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 VkFenceCreateInfo { VkStructureType sType; const void* pNext; @@ -3361,12 +3848,6 @@ typedef struct VkSemaphoreCreateInfo { VkSemaphoreCreateFlags flags; } VkSemaphoreCreateInfo; -typedef struct VkEventCreateInfo { - VkStructureType sType; - const void* pNext; - VkEventCreateFlags flags; -} VkEventCreateInfo; - typedef struct VkQueryPoolCreateInfo { VkStructureType sType; const void* pNext; @@ -3387,16 +3868,6 @@ typedef struct VkBufferCreateInfo { 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; @@ -3430,6 +3901,14 @@ typedef struct VkComponentMapping { 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; @@ -3441,6 +3920,131 @@ typedef struct VkImageViewCreateInfo { VkImageSubresourceRange subresourceRange; } VkImageViewCreateInfo; +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 VkBufferImageCopy { + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +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 VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkPipelineCacheHeaderVersionOne { + uint32_t headerSize; + VkPipelineCacheHeaderVersion headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; +} VkPipelineCacheHeaderVersionOne; + +typedef struct VkEventCreateInfo { + VkStructureType sType; + const void* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkBufferViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferViewCreateFlags flags; + VkBuffer buffer; + VkFormat format; + VkDeviceSize offset; + VkDeviceSize range; +} VkBufferViewCreateInfo; + typedef struct VkShaderModuleCreateInfo { VkStructureType sType; const void* pNext; @@ -3490,168 +4094,6 @@ typedef struct VkComputePipelineCreateInfo { int32_t basePipelineIndex; } VkComputePipelineCreateInfo; -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 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 VkPushConstantRange { VkShaderStageFlags stageFlags; uint32_t offset; @@ -3764,6 +4206,189 @@ typedef struct VkWriteDescriptorSet { const VkBufferView* pTexelBufferView; } VkWriteDescriptorSet; +typedef union VkClearColorValue { + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +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 struct VkStencilOpState { + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkVertexInputAttributeDescription { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkVertexInputBindingDescription { + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkViewport { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +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 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 VkPipelineDynamicStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState* pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkPipelineInputAssemblyStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +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 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 VkPipelineTessellationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +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 VkPipelineViewportStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport* pViewports; + uint32_t scissorCount; + const VkRect2D* pScissors; +} VkPipelineViewportStateCreateInfo; + +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 VkAttachmentDescription { VkAttachmentDescriptionFlags flags; VkFormat format; @@ -3793,6 +4418,16 @@ typedef struct VkFramebufferCreateInfo { uint32_t layers; } VkFramebufferCreateInfo; +typedef struct VkSubpassDependency { + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + typedef struct VkSubpassDescription { VkSubpassDescriptionFlags flags; VkPipelineBindPoint pipelineBindPoint; @@ -3806,16 +4441,6 @@ typedef struct VkSubpassDescription { 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; @@ -3828,72 +4453,17 @@ typedef struct VkRenderPassCreateInfo { 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 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 struct VkClearRect { + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + typedef union VkClearValue { VkClearColorValue color; VkClearDepthStencilValue depthStencil; @@ -3905,12 +4475,6 @@ typedef struct VkClearAttachment { VkClearValue clearValue; } VkClearAttachment; -typedef struct VkClearRect { - VkRect2D rect; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkClearRect; - typedef struct VkImageBlit { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffsets[2]; @@ -3918,14 +4482,6 @@ typedef struct VkImageBlit { VkOffset3D dstOffsets[2]; } VkImageBlit; -typedef struct VkImageCopy { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy; - typedef struct VkImageResolve { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffset; @@ -3986,30 +4542,50 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fenc 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_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_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_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 void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +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_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +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_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_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); @@ -4024,20 +4600,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescr 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 void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +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_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +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_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); +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_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); @@ -4047,40 +4624,19 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, 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 groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -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 void* 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( @@ -4304,29 +4860,6 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( 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, @@ -4359,17 +4892,6 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( 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, @@ -4398,6 +4920,174 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( VkImageView imageView, const VkAllocationCallbacks* pAllocator); +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 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 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 void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +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 vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); + +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 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 vkCreateShaderModule( VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, @@ -4432,14 +5122,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( 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, @@ -4520,6 +5202,79 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +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 vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( + VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); + +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 vkCmdPushConstants( + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void* pValues); + +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 vkCreateFramebuffer( VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, @@ -4547,49 +5302,6 @@ VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( 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, @@ -4636,16 +5348,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( 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, @@ -4688,33 +5390,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( uint32_t drawCount, uint32_t stride); -VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( - VkCommandBuffer commandBuffer, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - -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, @@ -4725,44 +5400,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( 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 void* 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, @@ -4787,82 +5424,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( 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, @@ -4874,11 +5435,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); #endif @@ -4887,8 +5443,8 @@ VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( // Vulkan 1.1 version number #define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) #define VK_MAX_DEVICE_GROUP_SIZE 32U #define VK_LUID_SIZE 8U #define VK_QUEUE_FAMILY_EXTERNAL (~1U) @@ -4901,13 +5457,13 @@ typedef enum VkPointClippingBehavior { VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF } VkPointClippingBehavior; -typedef enum VkTessellationDomainOrigin { - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF -} VkTessellationDomainOrigin; +typedef enum VkDescriptorUpdateTemplateType { + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS = 1, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorUpdateTemplateType; typedef enum VkSamplerYcbcrModelConversion { VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, @@ -4939,12 +5495,13 @@ typedef enum VkChromaLocation { VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF } VkChromaLocation; -typedef enum VkDescriptorUpdateTemplateType { - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorUpdateTemplateType; +typedef enum VkTessellationDomainOrigin { + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF +} VkTessellationDomainOrigin; typedef enum VkSubgroupFeatureFlagBits { VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001, @@ -4955,9 +5512,12 @@ typedef enum VkSubgroupFeatureFlagBits { VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, - VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, - VK_SUBGROUP_FEATURE_ROTATE_BIT_KHR = 0x00000200, - VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT_KHR = 0x00000400, + VK_SUBGROUP_FEATURE_ROTATE_BIT = 0x00000200, + VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT = 0x00000400, + VK_SUBGROUP_FEATURE_PARTITIONED_BIT_EXT = 0x00000100, + VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = VK_SUBGROUP_FEATURE_PARTITIONED_BIT_EXT, + VK_SUBGROUP_FEATURE_ROTATE_BIT_KHR = VK_SUBGROUP_FEATURE_ROTATE_BIT, + VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT_KHR = VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT, VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubgroupFeatureFlagBits; typedef VkFlags VkSubgroupFeatureFlags; @@ -4979,6 +5539,7 @@ typedef enum VkMemoryAllocateFlagBits { VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004, + VK_MEMORY_ALLOCATE_ZERO_INITIALIZE_BIT_EXT = 0x00000008, VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, @@ -4986,7 +5547,6 @@ typedef enum VkMemoryAllocateFlagBits { } VkMemoryAllocateFlagBits; typedef VkFlags VkMemoryAllocateFlags; typedef VkFlags VkCommandPoolTrimFlags; -typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, @@ -5002,7 +5562,11 @@ typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800, VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OH_NATIVE_BUFFER_BIT_OHOS = 0x00008000, VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX = 0x00004000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT = 0x00010000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT = 0x00020000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLHEAP_BIT_EXT = 0x00040000, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, @@ -5086,15 +5650,7 @@ typedef enum VkExternalSemaphoreFeatureFlagBits { VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalSemaphoreFeatureFlagBits; typedef VkFlags VkExternalSemaphoreFeatureFlags; -typedef struct VkPhysicalDeviceSubgroupProperties { - VkStructureType sType; - void* pNext; - uint32_t subgroupSize; - VkShaderStageFlags supportedStages; - VkSubgroupFeatureFlags supportedOperations; - VkBool32 quadOperationsInAllStages; -} VkPhysicalDeviceSubgroupProperties; - +typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; typedef struct VkBindBufferMemoryInfo { VkStructureType sType; const void* pNext; @@ -5111,15 +5667,6 @@ typedef struct VkBindImageMemoryInfo { VkDeviceSize memoryOffset; } VkBindImageMemoryInfo; -typedef struct VkPhysicalDevice16BitStorageFeatures { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; -} VkPhysicalDevice16BitStorageFeatures; - typedef struct VkMemoryDedicatedRequirements { VkStructureType sType; void* pNext; @@ -5141,14 +5688,6 @@ typedef struct VkMemoryAllocateFlagsInfo { uint32_t deviceMask; } VkMemoryAllocateFlagsInfo; -typedef struct VkDeviceGroupRenderPassBeginInfo { - VkStructureType sType; - const void* pNext; - uint32_t deviceMask; - uint32_t deviceRenderAreaCount; - const VkRect2D* pDeviceRenderAreas; -} VkDeviceGroupRenderPassBeginInfo; - typedef struct VkDeviceGroupCommandBufferBeginInfo { VkStructureType sType; const void* pNext; @@ -5296,72 +5835,12 @@ typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { VkImageTiling tiling; } VkPhysicalDeviceSparseImageFormatInfo2; -typedef struct VkPhysicalDevicePointClippingProperties { - VkStructureType sType; - void* pNext; - VkPointClippingBehavior pointClippingBehavior; -} VkPhysicalDevicePointClippingProperties; - -typedef struct VkInputAttachmentAspectReference { - uint32_t subpass; - uint32_t inputAttachmentIndex; - VkImageAspectFlags aspectMask; -} VkInputAttachmentAspectReference; - -typedef struct VkRenderPassInputAttachmentAspectCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t aspectReferenceCount; - const VkInputAttachmentAspectReference* pAspectReferences; -} VkRenderPassInputAttachmentAspectCreateInfo; - typedef struct VkImageViewUsageCreateInfo { VkStructureType sType; const void* pNext; VkImageUsageFlags usage; } VkImageViewUsageCreateInfo; -typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkTessellationDomainOrigin domainOrigin; -} VkPipelineTessellationDomainOriginStateCreateInfo; - -typedef struct VkRenderPassMultiviewCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t subpassCount; - const uint32_t* pViewMasks; - uint32_t dependencyCount; - const int32_t* pViewOffsets; - uint32_t correlationMaskCount; - const uint32_t* pCorrelationMasks; -} VkRenderPassMultiviewCreateInfo; - -typedef struct VkPhysicalDeviceMultiviewFeatures { - VkStructureType sType; - void* pNext; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; -} VkPhysicalDeviceMultiviewFeatures; - -typedef struct VkPhysicalDeviceMultiviewProperties { - VkStructureType sType; - void* pNext; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; -} VkPhysicalDeviceMultiviewProperties; - -typedef struct VkPhysicalDeviceVariablePointersFeatures { - VkStructureType sType; - void* pNext; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; -} VkPhysicalDeviceVariablePointersFeatures; - -typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; - typedef struct VkPhysicalDeviceProtectedMemoryFeatures { VkStructureType sType; void* pNext; @@ -5388,25 +5867,6 @@ typedef struct VkProtectedSubmitInfo { VkBool32 protectedSubmit; } VkProtectedSubmitInfo; -typedef struct VkSamplerYcbcrConversionCreateInfo { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkSamplerYcbcrModelConversion ycbcrModel; - VkSamplerYcbcrRange ycbcrRange; - VkComponentMapping components; - VkChromaLocation xChromaOffset; - VkChromaLocation yChromaOffset; - VkFilter chromaFilter; - VkBool32 forceExplicitReconstruction; -} VkSamplerYcbcrConversionCreateInfo; - -typedef struct VkSamplerYcbcrConversionInfo { - VkStructureType sType; - const void* pNext; - VkSamplerYcbcrConversion conversion; -} VkSamplerYcbcrConversionInfo; - typedef struct VkBindImagePlaneMemoryInfo { VkStructureType sType; const void* pNext; @@ -5419,40 +5879,6 @@ typedef struct VkImagePlaneMemoryRequirementsInfo { VkImageAspectFlagBits planeAspect; } VkImagePlaneMemoryRequirementsInfo; -typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { - VkStructureType sType; - void* pNext; - VkBool32 samplerYcbcrConversion; -} VkPhysicalDeviceSamplerYcbcrConversionFeatures; - -typedef struct VkSamplerYcbcrConversionImageFormatProperties { - VkStructureType sType; - void* pNext; - uint32_t combinedImageSamplerDescriptorCount; -} VkSamplerYcbcrConversionImageFormatProperties; - -typedef struct VkDescriptorUpdateTemplateEntry { - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - size_t offset; - size_t stride; -} VkDescriptorUpdateTemplateEntry; - -typedef struct VkDescriptorUpdateTemplateCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorUpdateTemplateCreateFlags flags; - uint32_t descriptorUpdateEntryCount; - const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; - VkDescriptorUpdateTemplateType templateType; - VkDescriptorSetLayout descriptorSetLayout; - VkPipelineBindPoint pipelineBindPoint; - VkPipelineLayout pipelineLayout; - uint32_t set; -} VkDescriptorUpdateTemplateCreateInfo; - typedef struct VkExternalMemoryProperties { VkExternalMemoryFeatureFlags externalMemoryFeatures; VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; @@ -5553,6 +5979,55 @@ typedef struct VkExternalSemaphoreProperties { VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; } VkExternalSemaphoreProperties; +typedef struct VkPhysicalDeviceSubgroupProperties { + VkStructureType sType; + void* pNext; + uint32_t subgroupSize; + VkShaderStageFlags supportedStages; + VkSubgroupFeatureFlags supportedOperations; + VkBool32 quadOperationsInAllStages; +} VkPhysicalDeviceSubgroupProperties; + +typedef struct VkPhysicalDevice16BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; +} VkPhysicalDevice16BitStorageFeatures; + +typedef struct VkPhysicalDeviceVariablePointersFeatures { + VkStructureType sType; + void* pNext; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; +} VkPhysicalDeviceVariablePointersFeatures; + +typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; + +typedef struct VkDescriptorUpdateTemplateEntry { + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + size_t offset; + size_t stride; +} VkDescriptorUpdateTemplateEntry; + +typedef struct VkDescriptorUpdateTemplateCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorUpdateTemplateCreateFlags flags; + uint32_t descriptorUpdateEntryCount; + const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; + VkDescriptorUpdateTemplateType templateType; + VkDescriptorSetLayout descriptorSetLayout; + VkPipelineBindPoint pipelineBindPoint; + VkPipelineLayout pipelineLayout; + uint32_t set; +} VkDescriptorUpdateTemplateCreateInfo; + typedef struct VkPhysicalDeviceMaintenance3Properties { VkStructureType sType; void* pNext; @@ -5566,6 +6041,96 @@ typedef struct VkDescriptorSetLayoutSupport { VkBool32 supported; } VkDescriptorSetLayoutSupport; +typedef struct VkSamplerYcbcrConversionCreateInfo { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkSamplerYcbcrModelConversion ycbcrModel; + VkSamplerYcbcrRange ycbcrRange; + VkComponentMapping components; + VkChromaLocation xChromaOffset; + VkChromaLocation yChromaOffset; + VkFilter chromaFilter; + VkBool32 forceExplicitReconstruction; +} VkSamplerYcbcrConversionCreateInfo; + +typedef struct VkSamplerYcbcrConversionInfo { + VkStructureType sType; + const void* pNext; + VkSamplerYcbcrConversion conversion; +} VkSamplerYcbcrConversionInfo; + +typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { + VkStructureType sType; + void* pNext; + VkBool32 samplerYcbcrConversion; +} VkPhysicalDeviceSamplerYcbcrConversionFeatures; + +typedef struct VkSamplerYcbcrConversionImageFormatProperties { + VkStructureType sType; + void* pNext; + uint32_t combinedImageSamplerDescriptorCount; +} VkSamplerYcbcrConversionImageFormatProperties; + +typedef struct VkDeviceGroupRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceMask; + uint32_t deviceRenderAreaCount; + const VkRect2D* pDeviceRenderAreas; +} VkDeviceGroupRenderPassBeginInfo; + +typedef struct VkPhysicalDevicePointClippingProperties { + VkStructureType sType; + void* pNext; + VkPointClippingBehavior pointClippingBehavior; +} VkPhysicalDevicePointClippingProperties; + +typedef struct VkInputAttachmentAspectReference { + uint32_t subpass; + uint32_t inputAttachmentIndex; + VkImageAspectFlags aspectMask; +} VkInputAttachmentAspectReference; + +typedef struct VkRenderPassInputAttachmentAspectCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t aspectReferenceCount; + const VkInputAttachmentAspectReference* pAspectReferences; +} VkRenderPassInputAttachmentAspectCreateInfo; + +typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkTessellationDomainOrigin domainOrigin; +} VkPipelineTessellationDomainOriginStateCreateInfo; + +typedef struct VkRenderPassMultiviewCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t subpassCount; + const uint32_t* pViewMasks; + uint32_t dependencyCount; + const int32_t* pViewOffsets; + uint32_t correlationMaskCount; + const uint32_t* pCorrelationMasks; +} VkRenderPassMultiviewCreateInfo; + +typedef struct VkPhysicalDeviceMultiviewFeatures { + VkStructureType sType; + void* pNext; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; +} VkPhysicalDeviceMultiviewFeatures; + +typedef struct VkPhysicalDeviceMultiviewProperties { + VkStructureType sType; + void* pNext; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; +} VkPhysicalDeviceMultiviewProperties; + typedef struct VkPhysicalDeviceShaderDrawParametersFeatures { VkStructureType sType; void* pNext; @@ -5579,7 +6144,6 @@ typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); @@ -5593,15 +6157,16 @@ typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDev typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); -typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion( @@ -5628,15 +6193,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask( VkCommandBuffer commandBuffer, uint32_t deviceMask); -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase( - VkCommandBuffer commandBuffer, - uint32_t baseGroupX, - uint32_t baseGroupY, - uint32_t baseGroupZ, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, @@ -5701,16 +6257,29 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2( const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue); -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( - VkDevice device, - const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSamplerYcbcrConversion* pYcbcrConversion); +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, + VkExternalBufferProperties* pExternalBufferProperties); -VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( - VkDevice device, - VkSamplerYcbcrConversion ycbcrConversion, - const VkAllocationCallbacks* pAllocator); +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, + VkExternalFenceProperties* pExternalFenceProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, + VkExternalSemaphoreProperties* pExternalSemaphoreProperties); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase( + VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate( VkDevice device, @@ -5729,25 +6298,21 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate( VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, - VkExternalBufferProperties* pExternalBufferProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, - VkExternalFenceProperties* pExternalFenceProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, - VkExternalSemaphoreProperties* pExternalSemaphoreProperties); - VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( + VkDevice device, + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversion* pYcbcrConversion); + +VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( + VkDevice device, + VkSamplerYcbcrConversion ycbcrConversion, + const VkAllocationCallbacks* pAllocator); #endif @@ -5785,7 +6350,10 @@ typedef enum VkDriverId { VK_DRIVER_ID_MESA_DOZEN = 23, VK_DRIVER_ID_MESA_NVK = 24, VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA = 25, - VK_DRIVER_ID_MESA_AGXV = 26, + VK_DRIVER_ID_MESA_HONEYKRISP = 26, + VK_DRIVER_ID_VULKAN_SC_EMULATION_ON_VULKAN = 27, + VK_DRIVER_ID_MESA_KOSMICKRISP = 28, + VK_DRIVER_ID_MESA_GFXSTREAM = 29, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, @@ -5811,6 +6379,14 @@ typedef enum VkShaderFloatControlsIndependence { VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF } VkShaderFloatControlsIndependence; +typedef enum VkSemaphoreType { + VK_SEMAPHORE_TYPE_BINARY = 0, + VK_SEMAPHORE_TYPE_TIMELINE = 1, + VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, + VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, + VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreType; + typedef enum VkSamplerReductionMode { VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, VK_SAMPLER_REDUCTION_MODE_MIN = 1, @@ -5822,30 +6398,32 @@ typedef enum VkSamplerReductionMode { VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF } VkSamplerReductionMode; -typedef enum VkSemaphoreType { - VK_SEMAPHORE_TYPE_BINARY = 0, - VK_SEMAPHORE_TYPE_TIMELINE = 1, - VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, - VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, - VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreType; - typedef enum VkResolveModeFlagBits { VK_RESOLVE_MODE_NONE = 0, VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001, VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002, VK_RESOLVE_MODE_MIN_BIT = 0x00000004, VK_RESOLVE_MODE_MAX_BIT = 0x00000008, - VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = 0x00000010, + VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_BIT_ANDROID = 0x00000010, + VK_RESOLVE_MODE_CUSTOM_BIT_EXT = 0x00000020, VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE, VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT, VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT, VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT, + // VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID is a legacy alias + VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_BIT_ANDROID, VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkResolveModeFlagBits; typedef VkFlags VkResolveModeFlags; +typedef enum VkSemaphoreWaitFlagBits { + VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, + VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, + VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreWaitFlagBits; +typedef VkFlags VkSemaphoreWaitFlags; + typedef enum VkDescriptorBindingFlagBits { VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001, VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, @@ -5858,13 +6436,22 @@ typedef enum VkDescriptorBindingFlagBits { VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorBindingFlagBits; typedef VkFlags VkDescriptorBindingFlags; +typedef struct VkConformanceVersion { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersion; + +typedef struct VkPhysicalDeviceDriverProperties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; +} VkPhysicalDeviceDriverProperties; -typedef enum VkSemaphoreWaitFlagBits { - VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, - VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, - VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreWaitFlagBits; -typedef VkFlags VkSemaphoreWaitFlags; typedef struct VkPhysicalDeviceVulkan11Features { VkStructureType sType; void* pNext; @@ -5954,13 +6541,6 @@ typedef struct VkPhysicalDeviceVulkan12Features { VkBool32 subgroupBroadcastDynamicId; } VkPhysicalDeviceVulkan12Features; -typedef struct VkConformanceVersion { - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t patch; -} VkConformanceVersion; - typedef struct VkPhysicalDeviceVulkan12Properties { VkStructureType sType; void* pNext; @@ -6025,81 +6605,95 @@ typedef struct VkImageFormatListCreateInfo { const VkFormat* pViewFormats; } VkImageFormatListCreateInfo; -typedef struct VkAttachmentDescription2 { - VkStructureType sType; - const void* pNext; - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription2; +typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { + VkStructureType sType; + void* pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeatures; -typedef struct VkAttachmentReference2 { - VkStructureType sType; - const void* pNext; - uint32_t attachment; - VkImageLayout layout; - VkImageAspectFlags aspectMask; -} VkAttachmentReference2; +typedef struct VkPhysicalDeviceHostQueryResetFeatures { + VkStructureType sType; + void* pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeatures; -typedef struct VkSubpassDescription2 { - VkStructureType sType; - const void* pNext; - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t viewMask; - uint32_t inputAttachmentCount; - const VkAttachmentReference2* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference2* pColorAttachments; - const VkAttachmentReference2* pResolveAttachments; - const VkAttachmentReference2* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription2; +typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { + VkStructureType sType; + void* pNext; + VkBool32 timelineSemaphore; +} VkPhysicalDeviceTimelineSemaphoreFeatures; -typedef struct VkSubpassDependency2 { - VkStructureType sType; - const void* pNext; - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; - int32_t viewOffset; -} VkSubpassDependency2; +typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { + VkStructureType sType; + void* pNext; + uint64_t maxTimelineSemaphoreValueDifference; +} VkPhysicalDeviceTimelineSemaphoreProperties; -typedef struct VkRenderPassCreateInfo2 { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription2* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription2* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency2* pDependencies; - uint32_t correlatedViewMaskCount; - const uint32_t* pCorrelatedViewMasks; -} VkRenderPassCreateInfo2; - -typedef struct VkSubpassBeginInfo { - VkStructureType sType; - const void* pNext; - VkSubpassContents contents; -} VkSubpassBeginInfo; - -typedef struct VkSubpassEndInfo { +typedef struct VkSemaphoreTypeCreateInfo { VkStructureType sType; const void* pNext; -} VkSubpassEndInfo; + VkSemaphoreType semaphoreType; + uint64_t initialValue; +} VkSemaphoreTypeCreateInfo; + +typedef struct VkTimelineSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreValueCount; + const uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValueCount; + const uint64_t* pSignalSemaphoreValues; +} VkTimelineSemaphoreSubmitInfo; + +typedef struct VkSemaphoreWaitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreWaitFlags flags; + uint32_t semaphoreCount; + const VkSemaphore* pSemaphores; + const uint64_t* pValues; +} VkSemaphoreWaitInfo; + +typedef struct VkSemaphoreSignalInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; +} VkSemaphoreSignalInfo; + +typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeatures; + +typedef struct VkBufferDeviceAddressInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfo; + +typedef struct VkBufferOpaqueCaptureAddressCreateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkBufferOpaqueCaptureAddressCreateInfo; + +typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkMemoryOpaqueCaptureAddressAllocateInfo; + +typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkDeviceMemoryOpaqueCaptureAddressInfo; typedef struct VkPhysicalDevice8BitStorageFeatures { VkStructureType sType; @@ -6109,15 +6703,6 @@ typedef struct VkPhysicalDevice8BitStorageFeatures { VkBool32 storagePushConstant8; } VkPhysicalDevice8BitStorageFeatures; -typedef struct VkPhysicalDeviceDriverProperties { - VkStructureType sType; - void* pNext; - VkDriverId driverID; - char driverName[VK_MAX_DRIVER_NAME_SIZE]; - char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; - VkConformanceVersion conformanceVersion; -} VkPhysicalDeviceDriverProperties; - typedef struct VkPhysicalDeviceShaderAtomicInt64Features { VkStructureType sType; void* pNext; @@ -6227,6 +6812,113 @@ typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { uint32_t maxVariableDescriptorCount; } VkDescriptorSetVariableDescriptorCountLayoutSupport; +typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeatures; + +typedef struct VkSamplerReductionModeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerReductionMode reductionMode; +} VkSamplerReductionModeCreateInfo; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { + VkStructureType sType; + void* pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxProperties; + +typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 uniformBufferStandardLayout; +} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; + +typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupExtendedTypes; +} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; + +typedef struct VkAttachmentDescription2 { + VkStructureType sType; + const void* pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2; + +typedef struct VkAttachmentReference2 { + VkStructureType sType; + const void* pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2; + +typedef struct VkSubpassDescription2 { + VkStructureType sType; + const void* pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2* pColorAttachments; + const VkAttachmentReference2* pResolveAttachments; + const VkAttachmentReference2* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription2; + +typedef struct VkSubpassDependency2 { + VkStructureType sType; + const void* pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2; + +typedef struct VkSubpassBeginInfo { + VkStructureType sType; + const void* pNext; + VkSubpassContents contents; +} VkSubpassBeginInfo; + +typedef struct VkSubpassEndInfo { + VkStructureType sType; + const void* pNext; +} VkSubpassEndInfo; + +typedef struct VkRenderPassCreateInfo2 { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2* pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t* pCorrelatedViewMasks; +} VkRenderPassCreateInfo2; + typedef struct VkSubpassDescriptionDepthStencilResolve { VkStructureType sType; const void* pNext; @@ -6244,39 +6936,12 @@ typedef struct VkPhysicalDeviceDepthStencilResolveProperties { VkBool32 independentResolve; } VkPhysicalDeviceDepthStencilResolveProperties; -typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { - VkStructureType sType; - void* pNext; - VkBool32 scalarBlockLayout; -} VkPhysicalDeviceScalarBlockLayoutFeatures; - typedef struct VkImageStencilUsageCreateInfo { VkStructureType sType; const void* pNext; VkImageUsageFlags stencilUsage; } VkImageStencilUsageCreateInfo; -typedef struct VkSamplerReductionModeCreateInfo { - VkStructureType sType; - const void* pNext; - VkSamplerReductionMode reductionMode; -} VkSamplerReductionModeCreateInfo; - -typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { - VkStructureType sType; - void* pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxProperties; - -typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { - VkStructureType sType; - void* pNext; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; -} VkPhysicalDeviceVulkanMemoryModelFeatures; - typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { VkStructureType sType; void* pNext; @@ -6295,13 +6960,6 @@ typedef struct VkFramebufferAttachmentImageInfo { const VkFormat* pViewFormats; } VkFramebufferAttachmentImageInfo; -typedef struct VkFramebufferAttachmentsCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t attachmentImageInfoCount; - const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; -} VkFramebufferAttachmentsCreateInfo; - typedef struct VkRenderPassAttachmentBeginInfo { VkStructureType sType; const void* pNext; @@ -6309,17 +6967,12 @@ typedef struct VkRenderPassAttachmentBeginInfo { const VkImageView* pAttachments; } VkRenderPassAttachmentBeginInfo; -typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { - VkStructureType sType; - void* pNext; - VkBool32 uniformBufferStandardLayout; -} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; - -typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupExtendedTypes; -} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; +typedef struct VkFramebufferAttachmentsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfo; typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { VkStructureType sType; @@ -6340,94 +6993,6 @@ typedef struct VkAttachmentDescriptionStencilLayout { VkImageLayout stencilFinalLayout; } VkAttachmentDescriptionStencilLayout; -typedef struct VkPhysicalDeviceHostQueryResetFeatures { - VkStructureType sType; - void* pNext; - VkBool32 hostQueryReset; -} VkPhysicalDeviceHostQueryResetFeatures; - -typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { - VkStructureType sType; - void* pNext; - VkBool32 timelineSemaphore; -} VkPhysicalDeviceTimelineSemaphoreFeatures; - -typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { - VkStructureType sType; - void* pNext; - uint64_t maxTimelineSemaphoreValueDifference; -} VkPhysicalDeviceTimelineSemaphoreProperties; - -typedef struct VkSemaphoreTypeCreateInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreType semaphoreType; - uint64_t initialValue; -} VkSemaphoreTypeCreateInfo; - -typedef struct VkTimelineSemaphoreSubmitInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreValueCount; - const uint64_t* pWaitSemaphoreValues; - uint32_t signalSemaphoreValueCount; - const uint64_t* pSignalSemaphoreValues; -} VkTimelineSemaphoreSubmitInfo; - -typedef struct VkSemaphoreWaitInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreWaitFlags flags; - uint32_t semaphoreCount; - const VkSemaphore* pSemaphores; - const uint64_t* pValues; -} VkSemaphoreWaitInfo; - -typedef struct VkSemaphoreSignalInfo { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; -} VkSemaphoreSignalInfo; - -typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { - VkStructureType sType; - void* pNext; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; -} VkPhysicalDeviceBufferDeviceAddressFeatures; - -typedef struct VkBufferDeviceAddressInfo { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferDeviceAddressInfo; - -typedef struct VkBufferOpaqueCaptureAddressCreateInfo { - VkStructureType sType; - const void* pNext; - uint64_t opaqueCaptureAddress; -} VkBufferOpaqueCaptureAddressCreateInfo; - -typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { - VkStructureType sType; - const void* pNext; - uint64_t opaqueCaptureAddress; -} VkMemoryOpaqueCaptureAddressAllocateInfo; - -typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; -} VkDeviceMemoryOpaqueCaptureAddressInfo; - -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); @@ -6435,8 +7000,46 @@ typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSem typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); #ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -6474,38 +7077,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2( VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2( VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); - -VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( - VkDevice device, - VkSemaphore semaphore, - uint64_t* pValue); - -VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( - VkDevice device, - const VkSemaphoreWaitInfo* pWaitInfo, - uint64_t timeout); - -VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( - VkDevice device, - const VkSemaphoreSignalInfo* pSignalInfo); - -VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( - VkDevice device, - const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); #endif @@ -6517,17 +7088,6 @@ VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( typedef uint64_t VkFlags64; VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) -typedef enum VkPipelineCreationFeedbackFlagBits { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBits; -typedef VkFlags VkPipelineCreationFeedbackFlags; - typedef enum VkToolPurposeFlagBits { VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, @@ -6550,62 +7110,63 @@ typedef VkFlags64 VkPipelineStageFlags2; // Flag bits for VkPipelineStageFlagBits2 typedef VkFlags64 VkPipelineStageFlagBits2; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT = 0x00020000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; @@ -6618,69 +7179,80 @@ static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0 static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT = 0x00080000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT = 0x00100000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI = 0x8000000000ULL; +// VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI is a legacy alias static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT = 0x40000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLUSTER_CULLING_SHADER_BIT_HUAWEI = 0x20000000000ULL; static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_OPTICAL_FLOW_BIT_NV = 0x20000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONVERT_COOPERATIVE_VECTOR_MATRIX_BIT_NV = 0x100000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DATA_GRAPH_BIT_ARM = 0x40000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR = 0x400000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT = 0x200000000000ULL; typedef VkFlags64 VkAccessFlags2; // Flag bits for VkAccessFlagBits2 typedef VkFlags64 VkAccessFlagBits2; static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT = 0x200000000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT = 0x400000000000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_TILE_ATTACHMENT_READ_BIT_QCOM = 0x8000000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_TILE_ATTACHMENT_WRITE_BIT_QCOM = 0x10000000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_EXT = 0x00020000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_EXT = 0x00040000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; @@ -6696,6 +7268,10 @@ static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_READ_BIT_EXT = 0x10000000000 static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT = 0x200000000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_READ_BIT_NV = 0x40000000000ULL; static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_WRITE_BIT_NV = 0x80000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DATA_GRAPH_READ_BIT_ARM = 0x800000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DATA_GRAPH_WRITE_BIT_ARM = 0x1000000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT = 0x80000000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT = 0x100000000000000ULL; typedef enum VkSubmitFlagBits { @@ -6704,77 +7280,38 @@ typedef enum VkSubmitFlagBits { VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubmitFlagBits; typedef VkFlags VkSubmitFlags; - -typedef enum VkRenderingFlagBits { - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, - VK_RENDERING_SUSPENDING_BIT = 0x00000002, - VK_RENDERING_RESUMING_BIT = 0x00000004, - VK_RENDERING_CONTENTS_INLINE_BIT_EXT = 0x00000010, - VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000008, - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, - VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, - VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, - VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkRenderingFlagBits; -typedef VkFlags VkRenderingFlags; typedef VkFlags64 VkFormatFeatureFlags2; // Flag bits for VkFormatFeatureFlagBits2 typedef VkFlags64 VkFormatFeatureFlagBits2; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT = 0x400000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; @@ -6783,15 +7320,86 @@ static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT = 0x400000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_SXD_BIT_QCOM = 0x100000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_RADIUS_BUFFER_BIT_NV = 0x8000000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM = 0x400000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM = 0x800000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM = 0x1000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM = 0x2000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TENSOR_SHADER_BIT_ARM = 0x8000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TENSOR_IMAGE_ALIASING_BIT_ARM = 0x80000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_IMAGE_BIT_NV = 0x10000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_VECTOR_BIT_NV = 0x20000000000ULL; static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_COST_BIT_NV = 0x40000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TENSOR_DATA_GRAPH_BIT_ARM = 0x1000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COPY_IMAGE_INDIRECT_DST_BIT_KHR = 0x800000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x2000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR = 0x4000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_COPY_ON_COMPUTE_QUEUE_BIT_KHR = 0x10000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_COPY_ON_TRANSFER_QUEUE_BIT_KHR = 0x20000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STENCIL_COPY_ON_COMPUTE_QUEUE_BIT_KHR = 0x40000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STENCIL_COPY_ON_TRANSFER_QUEUE_BIT_KHR = 0x80000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DATA_GRAPH_OPTICAL_FLOW_IMAGE_BIT_ARM = 0x100000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DATA_GRAPH_OPTICAL_FLOW_VECTOR_BIT_ARM = 0x200000000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DATA_GRAPH_OPTICAL_FLOW_COST_BIT_ARM = 0x400000000000000ULL; + +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef VkFlags VkPipelineCreationFeedbackFlags; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, + VK_RENDERING_SUSPENDING_BIT = 0x00000002, + VK_RENDERING_RESUMING_BIT = 0x00000004, + VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000008, + VK_RENDERING_CONTENTS_INLINE_BIT_KHR = 0x00000010, + VK_RENDERING_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE = 0x00000020, + VK_RENDERING_FRAGMENT_REGION_BIT_EXT = 0x00000040, + VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT = 0x00000080, + VK_RENDERING_LOCAL_READ_CONCURRENT_ACCESS_CONTROL_BIT_KHR = 0x00000100, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_CONTENTS_INLINE_BIT_EXT = VK_RENDERING_CONTENTS_INLINE_BIT_KHR, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; +typedef VkFlags VkRenderingFlags; typedef struct VkPhysicalDeviceVulkan13Features { VkStructureType sType; void* pNext; @@ -6862,25 +7470,6 @@ typedef struct VkPhysicalDeviceVulkan13Properties { VkDeviceSize maxBufferSize; } VkPhysicalDeviceVulkan13Properties; -typedef struct VkPipelineCreationFeedback { - VkPipelineCreationFeedbackFlags flags; - uint64_t duration; -} VkPipelineCreationFeedback; - -typedef struct VkPipelineCreationFeedbackCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreationFeedback* pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfo; - -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeatures; - typedef struct VkPhysicalDeviceToolProperties { VkStructureType sType; void* pNext; @@ -6891,12 +7480,6 @@ typedef struct VkPhysicalDeviceToolProperties { char layer[VK_MAX_EXTENSION_NAME_SIZE]; } VkPhysicalDeviceToolProperties; -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; - typedef struct VkPhysicalDevicePrivateDataFeatures { VkStructureType sType; void* pNext; @@ -6915,12 +7498,6 @@ typedef struct VkPrivateDataSlotCreateInfo { VkPrivateDataSlotCreateFlags flags; } VkPrivateDataSlotCreateInfo; -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { - VkStructureType sType; - void* pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeatures; - typedef struct VkMemoryBarrier2 { VkStructureType sType; const void* pNext; @@ -7005,18 +7582,6 @@ typedef struct VkPhysicalDeviceSynchronization2Features { VkBool32 synchronization2; } VkPhysicalDeviceSynchronization2Features; -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; - -typedef struct VkPhysicalDeviceImageRobustnessFeatures { - VkStructureType sType; - void* pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeatures; - typedef struct VkBufferCopy2 { VkStructureType sType; const void* pNext; @@ -7086,6 +7651,190 @@ typedef struct VkCopyImageToBufferInfo2 { const VkBufferImageCopy2* pRegions; } VkCopyImageToBufferInfo2; +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void* pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkBufferCreateInfo* pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreationFeedback* pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void* pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void* pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + typedef struct VkImageBlit2 { VkStructureType sType; const void* pNext; @@ -7128,64 +7877,6 @@ typedef struct VkResolveImageInfo2 { const VkImageResolve2* pRegions; } VkResolveImageInfo2; -typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { - VkStructureType sType; - void* pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeatures; - -typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlProperties; - -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { - VkStructureType sType; - void* pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; - -typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { - VkStructureType sType; - void* pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeatures; - -typedef struct VkPhysicalDeviceInlineUniformBlockProperties { - VkStructureType sType; - void* pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockProperties; - -typedef struct VkWriteDescriptorSetInlineUniformBlock { - VkStructureType sType; - const void* pNext; - uint32_t dataSize; - const void* pData; -} VkWriteDescriptorSetInlineUniformBlock; - -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfo; - -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { - VkStructureType sType; - void* pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; - typedef struct VkRenderingAttachmentInfo { VkStructureType sType; const void* pNext; @@ -7240,104 +7931,24 @@ typedef struct VkCommandBufferInheritanceRenderingInfo { VkSampleCountFlagBits rasterizationSamples; } VkCommandBufferInheritanceRenderingInfo; -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeatures; - -typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { - VkStructureType sType; - void* pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductProperties; - -typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { - VkStructureType sType; - void* pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentProperties; - -typedef struct VkFormatProperties3 { - VkStructureType sType; - void* pNext; - VkFormatFeatureFlags2 linearTilingFeatures; - VkFormatFeatureFlags2 optimalTilingFeatures; - VkFormatFeatureFlags2 bufferFeatures; -} VkFormatProperties3; - -typedef struct VkPhysicalDeviceMaintenance4Features { - VkStructureType sType; - void* pNext; - VkBool32 maintenance4; -} VkPhysicalDeviceMaintenance4Features; - -typedef struct VkPhysicalDeviceMaintenance4Properties { - VkStructureType sType; - void* pNext; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceMaintenance4Properties; - -typedef struct VkDeviceBufferMemoryRequirements { - VkStructureType sType; - const void* pNext; - const VkBufferCreateInfo* pCreateInfo; -} VkDeviceBufferMemoryRequirements; - -typedef struct VkDeviceImageMemoryRequirements { - VkStructureType sType; - const void* pNext; - const VkImageCreateInfo* pCreateInfo; - VkImageAspectFlagBits planeAspect; -} VkDeviceImageMemoryRequirements; - typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); @@ -7357,9 +7968,6 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, V typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); -typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( @@ -7392,22 +8000,6 @@ VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( VkPrivateDataSlot privateDataSlot, uint64_t* pData); -VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( - VkCommandBuffer commandBuffer, - VkEvent event, - const VkDependencyInfo* pDependencyInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags2 stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - const VkDependencyInfo* pDependencyInfos); - VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); @@ -7440,6 +8032,38 @@ VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); @@ -7525,22 +8149,753 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +#endif -VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( - VkDevice device, - const VkDeviceBufferMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( - VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); +// VK_VERSION_1_4 is a preprocessor guard. Do not pass it to API calls. +#define VK_VERSION_1_4 1 +// Vulkan 1.4 version number +#define VK_API_VERSION_1_4 VK_MAKE_API_VERSION(0, 1, 4, 0)// Patch version should always be set to 0 -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( +#define VK_MAX_GLOBAL_PRIORITY_SIZE 16U + +typedef enum VkPipelineRobustnessBufferBehavior { + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT = 0, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED = 1, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS = 2, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2 = 3, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF +} VkPipelineRobustnessBufferBehavior; + +typedef enum VkPipelineRobustnessImageBehavior { + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT = 0, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED = 1, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS = 2, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2 = 3, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF +} VkPipelineRobustnessImageBehavior; + +typedef enum VkQueueGlobalPriority { + VK_QUEUE_GLOBAL_PRIORITY_LOW = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME = 1024, + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME, + VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = VK_QUEUE_GLOBAL_PRIORITY_LOW, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = VK_QUEUE_GLOBAL_PRIORITY_HIGH, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = VK_QUEUE_GLOBAL_PRIORITY_REALTIME, + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM = 0x7FFFFFFF +} VkQueueGlobalPriority; + +typedef enum VkLineRasterizationMode { + VK_LINE_RASTERIZATION_MODE_DEFAULT = 0, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR = 1, + VK_LINE_RASTERIZATION_MODE_BRESENHAM = 2, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH = 3, + VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = VK_LINE_RASTERIZATION_MODE_DEFAULT, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR, + VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = VK_LINE_RASTERIZATION_MODE_BRESENHAM, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH, + VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR = VK_LINE_RASTERIZATION_MODE_DEFAULT, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_KHR = VK_LINE_RASTERIZATION_MODE_RECTANGULAR, + VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR = VK_LINE_RASTERIZATION_MODE_BRESENHAM, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH, + VK_LINE_RASTERIZATION_MODE_MAX_ENUM = 0x7FFFFFFF +} VkLineRasterizationMode; + +typedef enum VkMemoryUnmapFlagBits { + VK_MEMORY_UNMAP_RESERVE_BIT_EXT = 0x00000001, + VK_MEMORY_UNMAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryUnmapFlagBits; +typedef VkFlags VkMemoryUnmapFlags; +typedef VkFlags64 VkBufferUsageFlags2; + +// Flag bits for VkBufferUsageFlagBits2 +typedef VkFlags64 VkBufferUsageFlagBits2; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT = 0x00000001ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFER_DST_BIT = 0x00000002ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000008ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT = 0x00000010ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT = 0x00000020ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT = 0x00000040ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT = 0x00000080ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT = 0x00000100ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT = 0x00020000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_EXECUTION_GRAPH_SCRATCH_BIT_AMDX = 0x02000000ULL; +#endif +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT = 0x10000000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_MICROMAP_STORAGE_BIT_EXT = 0x01000000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT_KHR = 0x00000001ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFER_DST_BIT_KHR = 0x00000002ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000004ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR = 0x00000020ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT_KHR = 0x00000080ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT_KHR = 0x00000100ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_RAY_TRACING_BIT_NV = 0x00000400ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR = 0x00004000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT = 0x00200000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00400000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT = 0x04000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_COMPRESSED_DATA_DGF1_BIT_AMDX = 0x200000000ULL; +#endif +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_DATA_GRAPH_FOREIGN_DESCRIPTOR_BIT_ARM = 0x20000000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_TILE_MEMORY_BIT_QCOM = 0x08000000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT = 0x100000000ULL; +static const VkBufferUsageFlagBits2 VK_BUFFER_USAGE_2_PREPROCESS_BUFFER_BIT_EXT = 0x80000000ULL; + + +typedef enum VkHostImageCopyFlagBits { + VK_HOST_IMAGE_COPY_MEMCPY_BIT = 0x00000001, + // VK_HOST_IMAGE_COPY_MEMCPY is a legacy alias + VK_HOST_IMAGE_COPY_MEMCPY = VK_HOST_IMAGE_COPY_MEMCPY_BIT, + VK_HOST_IMAGE_COPY_MEMCPY_BIT_EXT = VK_HOST_IMAGE_COPY_MEMCPY_BIT, + // VK_HOST_IMAGE_COPY_MEMCPY_EXT is a legacy alias + VK_HOST_IMAGE_COPY_MEMCPY_EXT = VK_HOST_IMAGE_COPY_MEMCPY_BIT, + VK_HOST_IMAGE_COPY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkHostImageCopyFlagBits; +typedef VkFlags VkHostImageCopyFlags; +typedef VkFlags64 VkPipelineCreateFlags2; + +// Flag bits for VkPipelineCreateFlagBits2 +typedef VkFlags64 VkPipelineCreateFlagBits2; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT = 0x00000001ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT = 0x00000002ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DERIVATIVE_BIT = 0x00000004ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT = 0x00000010ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT = 0x08000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT = 0x40000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_EXECUTION_GRAPH_BIT_AMDX = 0x100000000ULL; +#endif +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT = 0x1000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_BUILT_IN_PRIMITIVES_BIT_KHR = 0x00001000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_ALLOW_SPHERES_AND_LINEAR_SWEPT_SPHERES_BIT_NV = 0x200000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x400000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT_KHR = 0x00000001ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR = 0x00000002ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR = 0x00000004ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT_KHR = 0x00000010ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DEFER_COMPILE_BIT_NV = 0x00000020ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_CAPTURE_STATISTICS_BIT_KHR = 0x00000040ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR = 0x00000100ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR = 0x00000200ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR = 0x00000800ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_INDIRECT_BINDABLE_BIT_NV = 0x00040000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000ULL; +#endif +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DESCRIPTOR_BUFFER_BIT_EXT = 0x20000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_DISALLOW_OPACITY_MICROMAP_BIT_ARM = 0x2000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_INSTRUMENT_SHADERS_BIT_ARM = 0x8000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR = 0x80000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_INDIRECT_BINDABLE_BIT_EXT = 0x4000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE = 0x10000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_OPACITY_MICROMAP_BIT_KHR = 0x01000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_OPACITY_MICROMAP_DISALLOW_MIXED_SPECIAL_INDEX_BIT_KHR = 0x20000000000ULL; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_64_BIT_INDEXING_BIT_EXT = 0x80000000000ULL; + +typedef struct VkPhysicalDeviceVulkan14Features { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; + VkBool32 shaderSubgroupRotate; + VkBool32 shaderSubgroupRotateClustered; + VkBool32 shaderFloatControls2; + VkBool32 shaderExpectAssume; + VkBool32 rectangularLines; + VkBool32 bresenhamLines; + VkBool32 smoothLines; + VkBool32 stippledRectangularLines; + VkBool32 stippledBresenhamLines; + VkBool32 stippledSmoothLines; + VkBool32 vertexAttributeInstanceRateDivisor; + VkBool32 vertexAttributeInstanceRateZeroDivisor; + VkBool32 indexTypeUint8; + VkBool32 dynamicRenderingLocalRead; + VkBool32 maintenance5; + VkBool32 maintenance6; + VkBool32 pipelineProtectedAccess; + VkBool32 pipelineRobustness; + VkBool32 hostImageCopy; + VkBool32 pushDescriptor; +} VkPhysicalDeviceVulkan14Features; + +typedef struct VkPhysicalDeviceVulkan14Properties { + VkStructureType sType; + void* pNext; + uint32_t lineSubPixelPrecisionBits; + uint32_t maxVertexAttribDivisor; + VkBool32 supportsNonZeroFirstInstance; + uint32_t maxPushDescriptors; + VkBool32 dynamicRenderingLocalReadDepthStencilAttachments; + VkBool32 dynamicRenderingLocalReadMultisampledAttachments; + VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting; + VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting; + VkBool32 depthStencilSwizzleOneSupport; + VkBool32 polygonModePointSize; + VkBool32 nonStrictSinglePixelWideLinesUseParallelogram; + VkBool32 nonStrictWideLinesUseParallelogram; + VkBool32 blockTexelViewCompatibleMultipleLayers; + uint32_t maxCombinedImageSamplerDescriptorCount; + VkBool32 fragmentShadingRateClampCombinerInputs; + VkPipelineRobustnessBufferBehavior defaultRobustnessStorageBuffers; + VkPipelineRobustnessBufferBehavior defaultRobustnessUniformBuffers; + VkPipelineRobustnessBufferBehavior defaultRobustnessVertexInputs; + VkPipelineRobustnessImageBehavior defaultRobustnessImages; + uint32_t copySrcLayoutCount; + VkImageLayout* pCopySrcLayouts; + uint32_t copyDstLayoutCount; + VkImageLayout* pCopyDstLayouts; + uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE]; + VkBool32 identicalMemoryTypeRequirements; +} VkPhysicalDeviceVulkan14Properties; + +typedef struct VkDeviceQueueGlobalPriorityCreateInfo { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriority globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfo; + +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeatures; + +typedef struct VkQueueFamilyGlobalPriorityProperties { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriority priorities[VK_MAX_GLOBAL_PRIORITY_SIZE]; +} VkQueueFamilyGlobalPriorityProperties; + +typedef struct VkPhysicalDeviceIndexTypeUint8Features { + VkStructureType sType; + void* pNext; + VkBool32 indexTypeUint8; +} VkPhysicalDeviceIndexTypeUint8Features; + +typedef struct VkMemoryMapInfo { + VkStructureType sType; + const void* pNext; + VkMemoryMapFlags flags; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMemoryMapInfo; + +typedef struct VkMemoryUnmapInfo { + VkStructureType sType; + const void* pNext; + VkMemoryUnmapFlags flags; + VkDeviceMemory memory; +} VkMemoryUnmapInfo; + +typedef struct VkPhysicalDeviceMaintenance5Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance5; +} VkPhysicalDeviceMaintenance5Features; + +typedef struct VkPhysicalDeviceMaintenance5Properties { + VkStructureType sType; + void* pNext; + VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting; + VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting; + VkBool32 depthStencilSwizzleOneSupport; + VkBool32 polygonModePointSize; + VkBool32 nonStrictSinglePixelWideLinesUseParallelogram; + VkBool32 nonStrictWideLinesUseParallelogram; +} VkPhysicalDeviceMaintenance5Properties; + +typedef struct VkSubresourceLayout2 { + VkStructureType sType; + void* pNext; + VkSubresourceLayout subresourceLayout; +} VkSubresourceLayout2; + +typedef struct VkImageSubresource2 { + VkStructureType sType; + void* pNext; + VkImageSubresource imageSubresource; +} VkImageSubresource2; + +typedef struct VkDeviceImageSubresourceInfo { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + const VkImageSubresource2* pSubresource; +} VkDeviceImageSubresourceInfo; + +typedef struct VkBufferUsageFlags2CreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferUsageFlags2 usage; +} VkBufferUsageFlags2CreateInfo; + +typedef struct VkPhysicalDeviceMaintenance6Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance6; +} VkPhysicalDeviceMaintenance6Features; + +typedef struct VkPhysicalDeviceMaintenance6Properties { + VkStructureType sType; + void* pNext; + VkBool32 blockTexelViewCompatibleMultipleLayers; + uint32_t maxCombinedImageSamplerDescriptorCount; + VkBool32 fragmentShadingRateClampCombinerInputs; +} VkPhysicalDeviceMaintenance6Properties; + +typedef struct VkBindMemoryStatus { + VkStructureType sType; + const void* pNext; + VkResult* pResult; +} VkBindMemoryStatus; + +typedef struct VkPhysicalDeviceHostImageCopyFeatures { + VkStructureType sType; + void* pNext; + VkBool32 hostImageCopy; +} VkPhysicalDeviceHostImageCopyFeatures; + +typedef struct VkPhysicalDeviceHostImageCopyProperties { + VkStructureType sType; + void* pNext; + uint32_t copySrcLayoutCount; + VkImageLayout* pCopySrcLayouts; + uint32_t copyDstLayoutCount; + VkImageLayout* pCopyDstLayouts; + uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE]; + VkBool32 identicalMemoryTypeRequirements; +} VkPhysicalDeviceHostImageCopyProperties; + +typedef struct VkMemoryToImageCopy { + VkStructureType sType; + const void* pNext; + const void* pHostPointer; + uint32_t memoryRowLength; + uint32_t memoryImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkMemoryToImageCopy; + +typedef struct VkImageToMemoryCopy { + VkStructureType sType; + const void* pNext; + void* pHostPointer; + uint32_t memoryRowLength; + uint32_t memoryImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkImageToMemoryCopy; + +typedef struct VkCopyMemoryToImageInfo { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlags flags; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkMemoryToImageCopy* pRegions; +} VkCopyMemoryToImageInfo; + +typedef struct VkCopyImageToMemoryInfo { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlags flags; + VkImage srcImage; + VkImageLayout srcImageLayout; + uint32_t regionCount; + const VkImageToMemoryCopy* pRegions; +} VkCopyImageToMemoryInfo; + +typedef struct VkCopyImageToImageInfo { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlags flags; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageToImageInfo; + +typedef struct VkHostImageLayoutTransitionInfo { + VkStructureType sType; + const void* pNext; + VkImage image; + VkImageLayout oldLayout; + VkImageLayout newLayout; + VkImageSubresourceRange subresourceRange; +} VkHostImageLayoutTransitionInfo; + +typedef struct VkSubresourceHostMemcpySize { + VkStructureType sType; + void* pNext; + VkDeviceSize size; +} VkSubresourceHostMemcpySize; + +typedef struct VkHostImageCopyDevicePerformanceQuery { + VkStructureType sType; + void* pNext; + VkBool32 optimalDeviceAccess; + VkBool32 identicalMemoryLayout; +} VkHostImageCopyDevicePerformanceQuery; + +typedef struct VkPhysicalDeviceShaderSubgroupRotateFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupRotate; + VkBool32 shaderSubgroupRotateClustered; +} VkPhysicalDeviceShaderSubgroupRotateFeatures; + +typedef struct VkPhysicalDeviceShaderFloatControls2Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloatControls2; +} VkPhysicalDeviceShaderFloatControls2Features; + +typedef struct VkPhysicalDeviceShaderExpectAssumeFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderExpectAssume; +} VkPhysicalDeviceShaderExpectAssumeFeatures; + +typedef struct VkPipelineCreateFlags2CreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags2 flags; +} VkPipelineCreateFlags2CreateInfo; + +typedef struct VkPhysicalDevicePushDescriptorProperties { + VkStructureType sType; + void* pNext; + uint32_t maxPushDescriptors; +} VkPhysicalDevicePushDescriptorProperties; + +typedef struct VkBindDescriptorSetsInfo { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t firstSet; + uint32_t descriptorSetCount; + const VkDescriptorSet* pDescriptorSets; + uint32_t dynamicOffsetCount; + const uint32_t* pDynamicOffsets; +} VkBindDescriptorSetsInfo; + +typedef struct VkPushConstantsInfo { + VkStructureType sType; + const void* pNext; + VkPipelineLayout layout; + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; + const void* pValues; +} VkPushConstantsInfo; + +typedef struct VkPushDescriptorSetInfo { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t set; + uint32_t descriptorWriteCount; + const VkWriteDescriptorSet* pDescriptorWrites; +} VkPushDescriptorSetInfo; + +typedef struct VkPushDescriptorSetWithTemplateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorUpdateTemplate descriptorUpdateTemplate; + VkPipelineLayout layout; + uint32_t set; + const void* pData; +} VkPushDescriptorSetWithTemplateInfo; + +typedef struct VkPhysicalDevicePipelineProtectedAccessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineProtectedAccess; +} VkPhysicalDevicePipelineProtectedAccessFeatures; + +typedef struct VkPhysicalDevicePipelineRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineRobustness; +} VkPhysicalDevicePipelineRobustnessFeatures; + +typedef struct VkPhysicalDevicePipelineRobustnessProperties { + VkStructureType sType; + void* pNext; + VkPipelineRobustnessBufferBehavior defaultRobustnessStorageBuffers; + VkPipelineRobustnessBufferBehavior defaultRobustnessUniformBuffers; + VkPipelineRobustnessBufferBehavior defaultRobustnessVertexInputs; + VkPipelineRobustnessImageBehavior defaultRobustnessImages; +} VkPhysicalDevicePipelineRobustnessProperties; + +typedef struct VkPipelineRobustnessCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineRobustnessBufferBehavior storageBuffers; + VkPipelineRobustnessBufferBehavior uniformBuffers; + VkPipelineRobustnessBufferBehavior vertexInputs; + VkPipelineRobustnessImageBehavior images; +} VkPipelineRobustnessCreateInfo; + +typedef struct VkPhysicalDeviceLineRasterizationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 rectangularLines; + VkBool32 bresenhamLines; + VkBool32 smoothLines; + VkBool32 stippledRectangularLines; + VkBool32 stippledBresenhamLines; + VkBool32 stippledSmoothLines; +} VkPhysicalDeviceLineRasterizationFeatures; + +typedef struct VkPhysicalDeviceLineRasterizationProperties { + VkStructureType sType; + void* pNext; + uint32_t lineSubPixelPrecisionBits; +} VkPhysicalDeviceLineRasterizationProperties; + +typedef struct VkPipelineRasterizationLineStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkLineRasterizationMode lineRasterizationMode; + VkBool32 stippledLineEnable; + uint32_t lineStippleFactor; + uint16_t lineStipplePattern; +} VkPipelineRasterizationLineStateCreateInfo; + +typedef struct VkPhysicalDeviceVertexAttributeDivisorProperties { + VkStructureType sType; + void* pNext; + uint32_t maxVertexAttribDivisor; + VkBool32 supportsNonZeroFirstInstance; +} VkPhysicalDeviceVertexAttributeDivisorProperties; + +typedef struct VkVertexInputBindingDivisorDescription { + uint32_t binding; + uint32_t divisor; +} VkVertexInputBindingDivisorDescription; + +typedef struct VkPipelineVertexInputDivisorStateCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t vertexBindingDivisorCount; + const VkVertexInputBindingDivisorDescription* pVertexBindingDivisors; +} VkPipelineVertexInputDivisorStateCreateInfo; + +typedef struct VkPhysicalDeviceVertexAttributeDivisorFeatures { + VkStructureType sType; + void* pNext; + VkBool32 vertexAttributeInstanceRateDivisor; + VkBool32 vertexAttributeInstanceRateZeroDivisor; +} VkPhysicalDeviceVertexAttributeDivisorFeatures; + +typedef struct VkRenderingAreaInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkRenderingAreaInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingLocalReadFeatures { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRenderingLocalRead; +} VkPhysicalDeviceDynamicRenderingLocalReadFeatures; + +typedef struct VkRenderingAttachmentLocationInfo { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const uint32_t* pColorAttachmentLocations; +} VkRenderingAttachmentLocationInfo; + +typedef struct VkRenderingInputAttachmentIndexInfo { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const uint32_t* pColorAttachmentInputIndices; + const uint32_t* pDepthInputAttachmentIndex; + const uint32_t* pStencilInputAttachmentIndex; +} VkRenderingInputAttachmentIndexInfo; + +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory2)(VkDevice device, const VkMemoryMapInfo* pMemoryMapInfo, void** ppData); +typedef VkResult (VKAPI_PTR *PFN_vkUnmapMemory2)(VkDevice device, const VkMemoryUnmapInfo* pMemoryUnmapInfo); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSubresourceLayout)(VkDevice device, const VkDeviceImageSubresourceInfo* pInfo, VkSubresourceLayout2* pLayout); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2)(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource, VkSubresourceLayout2* pLayout); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToImage)(VkDevice device, const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToMemory)(VkDevice device, const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToImage)(VkDevice device, const VkCopyImageToImageInfo* pCopyImageToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkTransitionImageLayout)(VkDevice device, uint32_t transitionCount, const VkHostImageLayoutTransitionInfo* pTransitions); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSet)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplate)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets2)(VkCommandBuffer commandBuffer, const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants2)(VkCommandBuffer commandBuffer, const VkPushConstantsInfo* pPushConstantsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSet2)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetInfo* pPushDescriptorSetInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplate2)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineStipple)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer2)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkGetRenderingAreaGranularity)(VkDevice device, const VkRenderingAreaInfo* pRenderingAreaInfo, VkExtent2D* pGranularity); +typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingAttachmentLocations)(VkCommandBuffer commandBuffer, const VkRenderingAttachmentLocationInfo* pLocationInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingInputAttachmentIndices)(VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory2( VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + const VkMemoryMapInfo* pMemoryMapInfo, + void** ppData); + +VKAPI_ATTR VkResult VKAPI_CALL vkUnmapMemory2( + VkDevice device, + const VkMemoryUnmapInfo* pMemoryUnmapInfo); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSubresourceLayout( + VkDevice device, + const VkDeviceImageSubresourceInfo* pInfo, + VkSubresourceLayout2* pLayout); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2( + VkDevice device, + VkImage image, + const VkImageSubresource2* pSubresource, + VkSubresourceLayout2* pLayout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToImage( + VkDevice device, + const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToMemory( + VkDevice device, + const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToImage( + VkDevice device, + const VkCopyImageToImageInfo* pCopyImageToImageInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkTransitionImageLayout( + VkDevice device, + uint32_t transitionCount, + const VkHostImageLayoutTransitionInfo* pTransitions); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t set, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate( + VkCommandBuffer commandBuffer, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + VkPipelineLayout layout, + uint32_t set, + const void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets2( + VkCommandBuffer commandBuffer, + const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants2( + VkCommandBuffer commandBuffer, + const VkPushConstantsInfo* pPushConstantsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet2( + VkCommandBuffer commandBuffer, + const VkPushDescriptorSetInfo* pPushDescriptorSetInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate2( + VkCommandBuffer commandBuffer, + const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStipple( + VkCommandBuffer commandBuffer, + uint32_t lineStippleFactor, + uint16_t lineStipplePattern); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer2( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkDeviceSize size, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderingAreaGranularity( + VkDevice device, + const VkRenderingAreaInfo* pRenderingAreaInfo, + VkExtent2D* pGranularity); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingAttachmentLocations( + VkCommandBuffer commandBuffer, + const VkRenderingAttachmentLocationInfo* pLocationInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingInputAttachmentIndices( + VkCommandBuffer commandBuffer, + const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo); #endif @@ -7557,6 +8912,8 @@ typedef enum VkPresentModeKHR { VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, + VK_PRESENT_MODE_FIFO_LATEST_READY_KHR = 1000361000, + VK_PRESENT_MODE_FIFO_LATEST_READY_EXT = VK_PRESENT_MODE_FIFO_LATEST_READY_KHR, VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF } VkPresentModeKHR; @@ -7570,6 +8927,7 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, + // VK_COLOR_SPACE_DOLBYVISION_EXT is legacy, but no reason was given in the API XML VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, @@ -7577,7 +8935,9 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000, + // VK_COLORSPACE_SRGB_NONLINEAR_KHR is a legacy alias VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + // VK_COLOR_SPACE_DCI_P3_LINEAR_EXT is a legacy alias VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF } VkColorSpaceKHR; @@ -7594,6 +8954,7 @@ typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSurfaceTransformFlagBitsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, @@ -7603,7 +8964,6 @@ typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkCompositeAlphaFlagBitsKHR; typedef VkFlags VkCompositeAlphaFlagsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; typedef struct VkSurfaceCapabilitiesKHR { uint32_t minImageCount; uint32_t maxImageCount; @@ -7629,34 +8989,44 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysica typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); #endif +#endif // VK_KHR_swapchain is a preprocessor guard. Do not pass it to API calls. @@ -7669,7 +9039,11 @@ typedef enum VkSwapchainCreateFlagBitsKHR { VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, - VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = 0x00000008, + VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT = 0x00000200, + VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR = 0x00000040, + VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR = 0x00000080, + VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR = 0x00000008, + VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR, VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSwapchainCreateFlagBitsKHR; typedef VkFlags VkSwapchainCreateFlagsKHR; @@ -7769,23 +9143,30 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhys typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( VkDevice device, VkSwapchainKHR swapchain, @@ -7793,31 +9174,42 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR* pPresentInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR( VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR( VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR( VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex); #endif +#endif // VK_KHR_display is a preprocessor guard. Do not pass it to API calls. @@ -7903,47 +9295,61 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDev typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_KHR_display_swapchain is a preprocessor guard. Do not pass it to API calls. @@ -7961,6 +9367,7 @@ typedef struct VkDisplayPresentInfoKHR { typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( VkDevice device, uint32_t swapchainCount, @@ -7968,6 +9375,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); #endif +#endif // VK_KHR_sampler_mirror_clamp_to_edge is a preprocessor guard. Do not pass it to API calls. @@ -7998,6 +9406,8 @@ typedef enum VkVideoCodecOperationFlagBitsKHR { VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR = 0x00000001, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR = 0x00000002, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR = 0x00000004, + VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR = 0x00040000, + VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR = 0x00000008, VK_VIDEO_CODEC_OPERATION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoCodecOperationFlagBitsKHR; typedef VkFlags VkVideoCodecOperationFlagsKHR; @@ -8032,9 +9442,17 @@ typedef enum VkVideoSessionCreateFlagBitsKHR { VK_VIDEO_SESSION_CREATE_PROTECTED_CONTENT_BIT_KHR = 0x00000001, VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_PARAMETER_OPTIMIZATIONS_BIT_KHR = 0x00000002, VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR = 0x00000004, + VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x00000008, + VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_EMPHASIS_MAP_BIT_KHR = 0x00000010, + VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR = 0x00000020, VK_VIDEO_SESSION_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoSessionCreateFlagBitsKHR; typedef VkFlags VkVideoSessionCreateFlagsKHR; + +typedef enum VkVideoSessionParametersCreateFlagBitsKHR { + VK_VIDEO_SESSION_PARAMETERS_CREATE_QUANTIZATION_MAP_COMPATIBLE_BIT_KHR = 0x00000001, + VK_VIDEO_SESSION_PARAMETERS_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoSessionParametersCreateFlagBitsKHR; typedef VkFlags VkVideoSessionParametersCreateFlagsKHR; typedef VkFlags VkVideoBeginCodingFlagsKHR; typedef VkFlags VkVideoEndCodingFlagsKHR; @@ -8201,68 +9619,92 @@ typedef void (VKAPI_PTR *PFN_vkCmdEndVideoCodingKHR)(VkCommandBuffer commandBuff typedef void (VKAPI_PTR *PFN_vkCmdControlVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoCodingControlInfoKHR* pCodingControlInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoCapabilitiesKHR( VkPhysicalDevice physicalDevice, const VkVideoProfileInfoKHR* pVideoProfile, VkVideoCapabilitiesKHR* pCapabilities); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoFormatPropertiesKHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, uint32_t* pVideoFormatPropertyCount, VkVideoFormatPropertiesKHR* pVideoFormatProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionKHR( VkDevice device, const VkVideoSessionCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionKHR* pVideoSession); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionKHR( VkDevice device, VkVideoSessionKHR videoSession, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetVideoSessionMemoryRequirementsKHR( VkDevice device, VkVideoSessionKHR videoSession, uint32_t* pMemoryRequirementsCount, VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBindVideoSessionMemoryKHR( VkDevice device, VkVideoSessionKHR videoSession, uint32_t bindSessionMemoryInfoCount, const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionParametersKHR( VkDevice device, const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionParametersKHR* pVideoSessionParameters); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkUpdateVideoSessionParametersKHR( VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionParametersKHR( VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoBeginCodingInfoKHR* pBeginInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoEndCodingInfoKHR* pEndCodingInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdControlVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoCodingControlInfoKHR* pCodingControlInfo); #endif +#endif // VK_KHR_video_decode_queue is a preprocessor guard. Do not pass it to API calls. @@ -8314,10 +9756,12 @@ typedef struct VkVideoDecodeInfoKHR { typedef void (VKAPI_PTR *PFN_vkCmdDecodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pDecodeInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDecodeVideoKHR( VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pDecodeInfo); #endif +#endif // VK_KHR_video_encode_h264 is a preprocessor guard. Do not pass it to API calls. @@ -8337,6 +9781,8 @@ typedef enum VkVideoEncodeH264CapabilityFlagBitsKHR { VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR = 0x00000040, VK_VIDEO_ENCODE_H264_CAPABILITY_PER_SLICE_CONSTANT_QP_BIT_KHR = 0x00000080, VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR = 0x00000100, + VK_VIDEO_ENCODE_H264_CAPABILITY_B_PICTURE_INTRA_REFRESH_BIT_KHR = 0x00000400, + VK_VIDEO_ENCODE_H264_CAPABILITY_MB_QP_DIFF_WRAPAROUND_BIT_KHR = 0x00000200, VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoEncodeH264CapabilityFlagBitsKHR; typedef VkFlags VkVideoEncodeH264CapabilityFlagsKHR; @@ -8537,6 +9983,8 @@ typedef enum VkVideoEncodeH265CapabilityFlagBitsKHR { VK_VIDEO_ENCODE_H265_CAPABILITY_PER_SLICE_SEGMENT_CONSTANT_QP_BIT_KHR = 0x00000080, VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILES_PER_SLICE_SEGMENT_BIT_KHR = 0x00000100, VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_SEGMENTS_PER_TILE_BIT_KHR = 0x00000200, + VK_VIDEO_ENCODE_H265_CAPABILITY_B_PICTURE_INTRA_REFRESH_BIT_KHR = 0x00000800, + VK_VIDEO_ENCODE_H265_CAPABILITY_CU_QP_DIFF_WRAPAROUND_BIT_KHR = 0x00000400, VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoEncodeH265CapabilityFlagBitsKHR; typedef VkFlags VkVideoEncodeH265CapabilityFlagsKHR; @@ -8822,49 +10270,21 @@ typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderin typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; -typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; - VkExtent2D shadingRateAttachmentTexelSize; -} VkRenderingFragmentShadingRateAttachmentInfoKHR; - -typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; -} VkRenderingFragmentDensityMapAttachmentInfoEXT; - -typedef struct VkAttachmentSampleCountInfoAMD { - VkStructureType sType; - const void* pNext; - uint32_t colorAttachmentCount; - const VkSampleCountFlagBits* pColorAttachmentSamples; - VkSampleCountFlagBits depthStencilAttachmentSamples; -} VkAttachmentSampleCountInfoAMD; - -typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; - -typedef struct VkMultiviewPerViewAttributesInfoNVX { - VkStructureType sType; - const void* pNext; - VkBool32 perViewAttributes; - VkBool32 perViewAttributesPositionXOnly; -} VkMultiviewPerViewAttributesInfoNVX; - typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( VkCommandBuffer commandBuffer); #endif +#endif // VK_KHR_multiview is a preprocessor guard. Do not pass it to API calls. @@ -8910,39 +10330,53 @@ typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysical typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); #endif +#endif // VK_KHR_device_group is a preprocessor guard. Do not pass it to API calls. @@ -8976,17 +10410,22 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer commandBuffe typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR( VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHR( VkCommandBuffer commandBuffer, uint32_t deviceMask); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( VkCommandBuffer commandBuffer, uint32_t baseGroupX, @@ -8996,6 +10435,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( uint32_t groupCountY, uint32_t groupCountZ); #endif +#endif // VK_KHR_shader_draw_parameters is a preprocessor guard. Do not pass it to API calls. @@ -9008,18 +10448,22 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( #define VK_KHR_maintenance1 1 #define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2 #define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1" +// VK_KHR_MAINTENANCE1_SPEC_VERSION is a legacy alias #define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION +// VK_KHR_MAINTENANCE1_EXTENSION_NAME is a legacy alias #define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR( VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); #endif +#endif // VK_KHR_device_group_creation is a preprocessor guard. Do not pass it to API calls. @@ -9034,11 +10478,13 @@ typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR; typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR( VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); #endif +#endif // VK_KHR_external_memory_capabilities is a preprocessor guard. Do not pass it to API calls. @@ -9069,11 +10515,13 @@ typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR; typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); #endif +#endif // VK_KHR_external_memory is a preprocessor guard. Do not pass it to API calls. @@ -9117,17 +10565,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemo typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR( VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR( VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); #endif +#endif // VK_KHR_external_semaphore_capabilities is a preprocessor guard. Do not pass it to API calls. @@ -9149,11 +10601,13 @@ typedef VkExternalSemaphoreProperties VkExternalSemaphorePropertiesKHR; typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); #endif +#endif // VK_KHR_external_semaphore is a preprocessor guard. Do not pass it to API calls. @@ -9192,31 +10646,32 @@ typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR( VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR( VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); #endif +#endif // VK_KHR_push_descriptor is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_push_descriptor 1 #define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2 #define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" -typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t maxPushDescriptors; -} VkPhysicalDevicePushDescriptorPropertiesKHR; +typedef VkPhysicalDevicePushDescriptorProperties VkPhysicalDevicePushDescriptorPropertiesKHR; typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, @@ -9224,7 +10679,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, @@ -9232,6 +10689,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( uint32_t set, const void* pData); #endif +#endif // VK_KHR_shader_float16_int8 is a preprocessor guard. Do not pass it to API calls. @@ -9295,23 +10753,29 @@ typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice devi typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR( VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR( VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); #endif +#endif // VK_KHR_imageless_framebuffer is a preprocessor guard. Do not pass it to API calls. @@ -9352,26 +10816,34 @@ typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); #endif +#endif // VK_KHR_shared_presentable_image is a preprocessor guard. Do not pass it to API calls. @@ -9387,10 +10859,12 @@ typedef struct VkSharedPresentSurfaceCapabilitiesKHR { typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR( VkDevice device, VkSwapchainKHR swapchain); #endif +#endif // VK_KHR_external_fence_capabilities is a preprocessor guard. Do not pass it to API calls. @@ -9412,11 +10886,13 @@ typedef VkExternalFenceProperties VkExternalFencePropertiesKHR; typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); #endif +#endif // VK_KHR_external_fence is a preprocessor guard. Do not pass it to API calls. @@ -9455,15 +10931,19 @@ typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkIm typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR( VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); #endif +#endif // VK_KHR_performance_query is a preprocessor guard. Do not pass it to API calls. @@ -9490,8 +10970,11 @@ typedef enum VkPerformanceCounterScopeKHR { VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0, VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1, VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2, + // VK_QUERY_SCOPE_COMMAND_BUFFER_KHR is a legacy alias VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR, + // VK_QUERY_SCOPE_RENDER_PASS_KHR is a legacy alias VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR, + // VK_QUERY_SCOPE_COMMAND_KHR is a legacy alias VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR, VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF } VkPerformanceCounterScopeKHR; @@ -9509,7 +10992,9 @@ typedef enum VkPerformanceCounterStorageKHR { typedef enum VkPerformanceCounterDescriptionFlagBitsKHR { VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR = 0x00000001, VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR = 0x00000002, + // VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR is a legacy alias VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR, + // VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR is a legacy alias VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR, VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkPerformanceCounterDescriptionFlagBitsKHR; @@ -9586,32 +11071,42 @@ typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, con typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR( VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( VkDevice device); #endif +#endif // VK_KHR_maintenance2 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_maintenance2 1 #define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2" +// VK_KHR_MAINTENANCE2_SPEC_VERSION is a legacy alias #define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION +// VK_KHR_MAINTENANCE2_EXTENSION_NAME is a legacy alias #define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; @@ -9655,17 +11150,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkP typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); #endif +#endif // VK_KHR_variable_pointers is a preprocessor guard. Do not pass it to API calls. @@ -9719,27 +11218,35 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevic typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR( VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR( VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities); #endif +#endif // VK_KHR_dedicated_allocation is a preprocessor guard. Do not pass it to API calls. @@ -9758,6 +11265,20 @@ typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR; #define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" +// VK_KHR_shader_bfloat16 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_bfloat16 1 +#define VK_KHR_SHADER_BFLOAT16_SPEC_VERSION 1 +#define VK_KHR_SHADER_BFLOAT16_EXTENSION_NAME "VK_KHR_shader_bfloat16" +typedef struct VkPhysicalDeviceShaderBfloat16FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderBFloat16Type; + VkBool32 shaderBFloat16DotProduct; + VkBool32 shaderBFloat16CooperativeMatrix; +} VkPhysicalDeviceShaderBfloat16FeaturesKHR; + + + // VK_KHR_relaxed_block_layout is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_relaxed_block_layout 1 #define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 @@ -9783,22 +11304,28 @@ typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR( VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR( VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #endif +#endif // VK_KHR_image_format_list is a preprocessor guard. Do not pass it to API calls. @@ -9837,17 +11364,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice dev typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR( VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR( VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); #endif +#endif // VK_KHR_bind_memory2 is a preprocessor guard. Do not pass it to API calls. @@ -9862,23 +11393,29 @@ typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32 typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR( VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); #endif +#endif // VK_KHR_maintenance3 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_maintenance3 1 #define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3" +// VK_KHR_MAINTENANCE3_SPEC_VERSION is a legacy alias #define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION +// VK_KHR_MAINTENANCE3_EXTENSION_NAME is a legacy alias #define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; @@ -9887,11 +11424,13 @@ typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR( VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); #endif +#endif // VK_KHR_draw_indirect_count is a preprocessor guard. Do not pass it to API calls. @@ -9902,6 +11441,7 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandB typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -9910,7 +11450,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR( VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -9920,6 +11462,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( uint32_t maxDrawCount, uint32_t stride); #endif +#endif // VK_KHR_shader_subgroup_extended_types is a preprocessor guard. Do not pass it to API calls. @@ -10014,39 +11557,16 @@ typedef struct VkVideoDecodeH265DpbSlotInfoKHR { // VK_KHR_global_priority is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_global_priority 1 -#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U #define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 #define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" +#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR VK_MAX_GLOBAL_PRIORITY_SIZE +typedef VkQueueGlobalPriority VkQueueGlobalPriorityKHR; -typedef enum VkQueueGlobalPriorityKHR { - VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, - VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF -} VkQueueGlobalPriorityKHR; -typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkQueueGlobalPriorityKHR globalPriority; -} VkDeviceQueueGlobalPriorityCreateInfoKHR; +typedef VkDeviceQueueGlobalPriorityCreateInfo VkDeviceQueueGlobalPriorityCreateInfoKHR; -typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 globalPriorityQuery; -} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; +typedef VkPhysicalDeviceGlobalPriorityQueryFeatures VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; -typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t priorityCount; - VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; -} VkQueueFamilyGlobalPriorityPropertiesKHR; +typedef VkQueueFamilyGlobalPriorityProperties VkQueueFamilyGlobalPriorityPropertiesKHR; @@ -10121,20 +11641,26 @@ typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkS typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR( VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR( VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR( VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); #endif +#endif // VK_KHR_vulkan_memory_model is a preprocessor guard. Do not pass it to API calls. @@ -10217,60 +11743,97 @@ typedef struct VkPhysicalDeviceFragmentShadingRateKHR { VkExtent2D fragmentSize; } VkPhysicalDeviceFragmentShadingRateKHR; +typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkExtent2D shadingRateAttachmentTexelSize; +} VkRenderingFragmentShadingRateAttachmentInfoKHR; + typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateKHR)(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceFragmentShadingRatesKHR( VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateKHR( VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); #endif +#endif + + +// VK_KHR_shader_constant_data is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_constant_data 1 +#define VK_KHR_SHADER_CONSTANT_DATA_SPEC_VERSION 1 +#define VK_KHR_SHADER_CONSTANT_DATA_EXTENSION_NAME "VK_KHR_shader_constant_data" +typedef struct VkPhysicalDeviceShaderConstantDataFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderConstantData; +} VkPhysicalDeviceShaderConstantDataFeaturesKHR; + // VK_KHR_dynamic_rendering_local_read is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_dynamic_rendering_local_read 1 #define VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_SPEC_VERSION 1 #define VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME "VK_KHR_dynamic_rendering_local_read" -typedef struct VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 dynamicRenderingLocalRead; -} VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR; +typedef VkPhysicalDeviceDynamicRenderingLocalReadFeatures VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR; -typedef struct VkRenderingAttachmentLocationInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t colorAttachmentCount; - const uint32_t* pColorAttachmentLocations; -} VkRenderingAttachmentLocationInfoKHR; +typedef VkRenderingAttachmentLocationInfo VkRenderingAttachmentLocationInfoKHR; -typedef struct VkRenderingInputAttachmentIndexInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t colorAttachmentCount; - const uint32_t* pColorAttachmentInputIndices; - const uint32_t* pDepthInputAttachmentIndex; - const uint32_t* pStencilInputAttachmentIndex; -} VkRenderingInputAttachmentIndexInfoKHR; +typedef VkRenderingInputAttachmentIndexInfo VkRenderingInputAttachmentIndexInfoKHR; -typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingAttachmentLocationsKHR)(VkCommandBuffer commandBuffer, const VkRenderingAttachmentLocationInfoKHR* pLocationInfo); -typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingInputAttachmentIndicesKHR)(VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfoKHR* pLocationInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingAttachmentLocationsKHR)(VkCommandBuffer commandBuffer, const VkRenderingAttachmentLocationInfo* pLocationInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingInputAttachmentIndicesKHR)(VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingAttachmentLocationsKHR( VkCommandBuffer commandBuffer, - const VkRenderingAttachmentLocationInfoKHR* pLocationInfo); + const VkRenderingAttachmentLocationInfo* pLocationInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingInputAttachmentIndicesKHR( VkCommandBuffer commandBuffer, - const VkRenderingInputAttachmentIndexInfoKHR* pLocationInfo); + const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo); #endif +#endif + + +// VK_KHR_shader_abort is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_abort 1 +#define VK_KHR_SHADER_ABORT_SPEC_VERSION 1 +#define VK_KHR_SHADER_ABORT_EXTENSION_NAME "VK_KHR_shader_abort" +typedef struct VkPhysicalDeviceShaderAbortFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderAbort; +} VkPhysicalDeviceShaderAbortFeaturesKHR; + +typedef struct VkDeviceFaultShaderAbortMessageInfoKHR { + VkStructureType sType; + void* pNext; + uint64_t messageDataSize; + void* pMessageData; +} VkDeviceFaultShaderAbortMessageInfoKHR; + +typedef struct VkPhysicalDeviceShaderAbortPropertiesKHR { + VkStructureType sType; + void* pNext; + uint64_t maxShaderAbortMessageSize; +} VkPhysicalDeviceShaderAbortPropertiesKHR; + // VK_KHR_shader_quad_control is a preprocessor guard. Do not pass it to API calls. @@ -10297,7 +11860,7 @@ typedef struct VkPhysicalDeviceShaderQuadControlFeaturesKHR { #define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities" typedef struct VkSurfaceProtectedCapabilitiesKHR { VkStructureType sType; - const void* pNext; + void* pNext; VkBool32 supportsProtected; } VkSurfaceProtectedCapabilitiesKHR; @@ -10328,12 +11891,14 @@ typedef struct VkPhysicalDevicePresentWaitFeaturesKHR { typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR( VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); #endif +#endif // VK_KHR_uniform_buffer_standard_layout is a preprocessor guard. Do not pass it to API calls. @@ -10363,18 +11928,24 @@ typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice de typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR( VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR( VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR( VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); #endif +#endif // VK_KHR_deferred_host_operations is a preprocessor guard. Do not pass it to API calls. @@ -10389,28 +11960,38 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice devic typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR( VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR( VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR( VkDevice device, VkDeferredOperationKHR operation); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR( VkDevice device, VkDeferredOperationKHR operation); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR( VkDevice device, VkDeferredOperationKHR operation); #endif +#endif // VK_KHR_pipeline_executable_properties is a preprocessor guard. Do not pass it to API calls. @@ -10484,64 +12065,60 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableStatisticsKHR)(VkDevice typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableInternalRepresentationsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutablePropertiesKHR( VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableStatisticsKHR( VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR( VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); #endif +#endif // VK_KHR_map_memory2 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_map_memory2 1 #define VK_KHR_MAP_MEMORY_2_SPEC_VERSION 1 #define VK_KHR_MAP_MEMORY_2_EXTENSION_NAME "VK_KHR_map_memory2" +typedef VkMemoryUnmapFlagBits VkMemoryUnmapFlagBitsKHR; -typedef enum VkMemoryUnmapFlagBitsKHR { - VK_MEMORY_UNMAP_RESERVE_BIT_EXT = 0x00000001, - VK_MEMORY_UNMAP_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkMemoryUnmapFlagBitsKHR; -typedef VkFlags VkMemoryUnmapFlagsKHR; -typedef struct VkMemoryMapInfoKHR { - VkStructureType sType; - const void* pNext; - VkMemoryMapFlags flags; - VkDeviceMemory memory; - VkDeviceSize offset; - VkDeviceSize size; -} VkMemoryMapInfoKHR; +typedef VkMemoryUnmapFlags VkMemoryUnmapFlagsKHR; -typedef struct VkMemoryUnmapInfoKHR { - VkStructureType sType; - const void* pNext; - VkMemoryUnmapFlagsKHR flags; - VkDeviceMemory memory; -} VkMemoryUnmapInfoKHR; +typedef VkMemoryMapInfo VkMemoryMapInfoKHR; -typedef VkResult (VKAPI_PTR *PFN_vkMapMemory2KHR)(VkDevice device, const VkMemoryMapInfoKHR* pMemoryMapInfo, void** ppData); -typedef VkResult (VKAPI_PTR *PFN_vkUnmapMemory2KHR)(VkDevice device, const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo); +typedef VkMemoryUnmapInfo VkMemoryUnmapInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory2KHR)(VkDevice device, const VkMemoryMapInfo* pMemoryMapInfo, void** ppData); +typedef VkResult (VKAPI_PTR *PFN_vkUnmapMemory2KHR)(VkDevice device, const VkMemoryUnmapInfo* pMemoryUnmapInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory2KHR( VkDevice device, - const VkMemoryMapInfoKHR* pMemoryMapInfo, + const VkMemoryMapInfo* pMemoryMapInfo, void** ppData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkUnmapMemory2KHR( VkDevice device, - const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo); + const VkMemoryUnmapInfo* pMemoryUnmapInfo); +#endif #endif @@ -10608,6 +12185,9 @@ typedef enum VkVideoEncodeTuningModeKHR { } VkVideoEncodeTuningModeKHR; typedef enum VkVideoEncodeFlagBitsKHR { + VK_VIDEO_ENCODE_INTRA_REFRESH_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_WITH_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_WITH_EMPHASIS_MAP_BIT_KHR = 0x00000002, VK_VIDEO_ENCODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoEncodeFlagBitsKHR; typedef VkFlags VkVideoEncodeFlagsKHR; @@ -10615,6 +12195,8 @@ typedef VkFlags VkVideoEncodeFlagsKHR; typedef enum VkVideoEncodeCapabilityFlagBitsKHR { VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001, VK_VIDEO_ENCODE_CAPABILITY_INSUFFICIENT_BITSTREAM_BUFFER_RANGE_DETECTION_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_CAPABILITY_EMPHASIS_MAP_BIT_KHR = 0x00000008, VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkVideoEncodeCapabilityFlagBitsKHR; typedef VkFlags VkVideoEncodeCapabilityFlagsKHR; @@ -10752,22 +12334,28 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetEncodedVideoSessionParametersKHR)(VkDevice typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo, VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetEncodedVideoSessionParametersKHR( VkDevice device, const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo, VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo, size_t* pDataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR( VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo); #endif +#endif // VK_KHR_synchronization2 is a preprocessor guard. Do not pass it to API calls. @@ -10802,72 +12390,427 @@ typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; -typedef struct VkQueueFamilyCheckpointProperties2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2 checkpointExecutionStageMask; -} VkQueueFamilyCheckpointProperties2NV; - -typedef struct VkCheckpointData2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2 stage; - void* pCheckpointMarker; -} VkCheckpointData2NV; - typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); -typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +#endif +#endif -VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( + +// VK_KHR_device_address_commands is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_device_address_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) +#define VK_KHR_DEVICE_ADDRESS_COMMANDS_SPEC_VERSION 1 +#define VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME "VK_KHR_device_address_commands" + +typedef enum VkAccelerationStructureTypeKHR { + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, + VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2, + VK_ACCELERATION_STRUCTURE_TYPE_OPACITY_MICROMAP_KHR = 1000623000, + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureTypeKHR; + +typedef enum VkAddressCommandFlagBitsKHR { + VK_ADDRESS_COMMAND_PROTECTED_BIT_KHR = 0x00000001, + VK_ADDRESS_COMMAND_FULLY_BOUND_BIT_KHR = 0x00000002, + VK_ADDRESS_COMMAND_STORAGE_BUFFER_USAGE_BIT_KHR = 0x00000004, + VK_ADDRESS_COMMAND_UNKNOWN_STORAGE_BUFFER_USAGE_BIT_KHR = 0x00000008, + VK_ADDRESS_COMMAND_TRANSFORM_FEEDBACK_BUFFER_USAGE_BIT_KHR = 0x00000010, + VK_ADDRESS_COMMAND_UNKNOWN_TRANSFORM_FEEDBACK_BUFFER_USAGE_BIT_KHR = 0x00000020, + VK_ADDRESS_COMMAND_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAddressCommandFlagBitsKHR; +typedef VkFlags VkAddressCommandFlagsKHR; + +typedef enum VkConditionalRenderingFlagBitsEXT { + VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, + VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkConditionalRenderingFlagBitsEXT; +typedef VkFlags VkConditionalRenderingFlagsEXT; + +typedef enum VkAccelerationStructureCreateFlagBitsKHR { + VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001, + VK_ACCELERATION_STRUCTURE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000008, + VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004, + VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureCreateFlagBitsKHR; +typedef VkFlags VkAccelerationStructureCreateFlagsKHR; +typedef struct VkDeviceAddressRangeKHR { + VkDeviceAddress address; + VkDeviceSize size; +} VkDeviceAddressRangeKHR; + +typedef struct VkStridedDeviceAddressRangeKHR { + VkDeviceAddress address; + VkDeviceSize size; + VkDeviceSize stride; +} VkStridedDeviceAddressRangeKHR; + +typedef struct VkDeviceMemoryCopyKHR { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR srcRange; + VkAddressCommandFlagsKHR srcFlags; + VkDeviceAddressRangeKHR dstRange; + VkAddressCommandFlagsKHR dstFlags; +} VkDeviceMemoryCopyKHR; + +typedef struct VkCopyDeviceMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t regionCount; + const VkDeviceMemoryCopyKHR* pRegions; +} VkCopyDeviceMemoryInfoKHR; + +typedef struct VkDeviceMemoryImageCopyKHR { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + uint32_t addressRowLength; + uint32_t addressImageHeight; + VkImageSubresourceLayers imageSubresource; + VkImageLayout imageLayout; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkDeviceMemoryImageCopyKHR; + +typedef struct VkCopyDeviceMemoryImageInfoKHR { + VkStructureType sType; + const void* pNext; + VkImage image; + uint32_t regionCount; + const VkDeviceMemoryImageCopyKHR* pRegions; +} VkCopyDeviceMemoryImageInfoKHR; + +typedef struct VkMemoryRangeBarrierKHR { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; +} VkMemoryRangeBarrierKHR; + +typedef struct VkMemoryRangeBarriersInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t memoryRangeBarrierCount; + const VkMemoryRangeBarrierKHR* pMemoryRangeBarriers; +} VkMemoryRangeBarriersInfoKHR; + +typedef struct VkPhysicalDeviceDeviceAddressCommandsFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 deviceAddressCommands; +} VkPhysicalDeviceDeviceAddressCommandsFeaturesKHR; + +typedef struct VkBindIndexBuffer3InfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + VkIndexType indexType; +} VkBindIndexBuffer3InfoKHR; + +typedef struct VkBindVertexBuffer3InfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 setStride; + VkStridedDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; +} VkBindVertexBuffer3InfoKHR; + +typedef struct VkDrawIndirect2InfoKHR { + VkStructureType sType; + const void* pNext; + VkStridedDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + uint32_t drawCount; +} VkDrawIndirect2InfoKHR; + +typedef struct VkDrawIndirectCount2InfoKHR { + VkStructureType sType; + const void* pNext; + VkStridedDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + VkDeviceAddressRangeKHR countAddressRange; + VkAddressCommandFlagsKHR countAddressFlags; + uint32_t maxDrawCount; +} VkDrawIndirectCount2InfoKHR; + +typedef struct VkDispatchIndirect2InfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; +} VkDispatchIndirect2InfoKHR; + +typedef struct VkConditionalRenderingBeginInfo2EXT { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + VkConditionalRenderingFlagsEXT flags; +} VkConditionalRenderingBeginInfo2EXT; + +typedef struct VkBindTransformFeedbackBuffer2InfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; +} VkBindTransformFeedbackBuffer2InfoEXT; + +typedef struct VkMemoryMarkerInfoAMD { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2KHR stage; + VkDeviceAddressRangeKHR dstRange; + VkAddressCommandFlagsKHR dstFlags; + uint32_t marker; +} VkMemoryMarkerInfoAMD; + +typedef struct VkAccelerationStructureCreateInfo2KHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureCreateFlagsKHR createFlags; + VkDeviceAddressRangeKHR addressRange; + VkAddressCommandFlagsKHR addressFlags; + VkAccelerationStructureTypeKHR type; +} VkAccelerationStructureCreateInfo2KHR; + +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer3KHR)(VkCommandBuffer commandBuffer, const VkBindIndexBuffer3InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers3KHR)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBindVertexBuffer3InfoKHR* pBindingInfos); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect2KHR)(VkCommandBuffer commandBuffer, const VkDrawIndirect2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect2KHR)(VkCommandBuffer commandBuffer, const VkDrawIndirect2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect2KHR)(VkCommandBuffer commandBuffer, const VkDispatchIndirect2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyDeviceMemoryInfoKHR* pCopyMemoryInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToImageKHR)(VkCommandBuffer commandBuffer, const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateMemoryKHR)(VkCommandBuffer commandBuffer, const VkDeviceAddressRangeKHR* pDstRange, VkAddressCommandFlagsKHR dstFlags, VkDeviceSize dataSize, const void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillMemoryKHR)(VkCommandBuffer commandBuffer, const VkDeviceAddressRangeKHR* pDstRange, VkAddressCommandFlagsKHR dstFlags, uint32_t data); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResultsToMemoryKHR)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, const VkStridedDeviceAddressRangeKHR* pDstRange, VkAddressCommandFlagsKHR dstFlags, VkQueryResultFlags queryResultFlags); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount2KHR)(VkCommandBuffer commandBuffer, const VkDrawIndirectCount2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount2KHR)(VkCommandBuffer commandBuffer, const VkDrawIndirectCount2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRendering2EXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfo2EXT* pConditionalRenderingBegin); +typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffers2EXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBindTransformFeedbackBuffer2InfoEXT* pBindingInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedback2EXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterRange, uint32_t counterRangeCount, const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos); +typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedback2EXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterRange, uint32_t counterRangeCount, const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCount2EXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfo, uint32_t counterOffset, uint32_t vertexStride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirect2EXT)(VkCommandBuffer commandBuffer, const VkDrawIndirect2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCount2EXT)(VkCommandBuffer commandBuffer, const VkDrawIndirectCount2InfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteMarkerToMemoryAMD)(VkCommandBuffer commandBuffer, const VkMemoryMarkerInfoAMD* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructure2KHR)(VkDevice device, const VkAccelerationStructureCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer3KHR( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2 stage, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - uint32_t marker); + const VkBindIndexBuffer3InfoKHR* pInfo); +#endif -VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( - VkQueue queue, - uint32_t* pCheckpointDataCount, - VkCheckpointData2NV* pCheckpointData); +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers3KHR( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBindVertexBuffer3InfoKHR* pBindingInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect2KHR( + VkCommandBuffer commandBuffer, + const VkDrawIndirect2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect2KHR( + VkCommandBuffer commandBuffer, + const VkDrawIndirect2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect2KHR( + VkCommandBuffer commandBuffer, + const VkDispatchIndirect2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyDeviceMemoryInfoKHR* pCopyMemoryInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageKHR( + VkCommandBuffer commandBuffer, + const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdUpdateMemoryKHR( + VkCommandBuffer commandBuffer, + const VkDeviceAddressRangeKHR* pDstRange, + VkAddressCommandFlagsKHR dstFlags, + VkDeviceSize dataSize, + const void* pData); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdFillMemoryKHR( + VkCommandBuffer commandBuffer, + const VkDeviceAddressRangeKHR* pDstRange, + VkAddressCommandFlagsKHR dstFlags, + uint32_t data); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResultsToMemoryKHR( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + const VkStridedDeviceAddressRangeKHR* pDstRange, + VkAddressCommandFlagsKHR dstFlags, + VkQueryResultFlags queryResultFlags); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount2KHR( + VkCommandBuffer commandBuffer, + const VkDrawIndirectCount2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount2KHR( + VkCommandBuffer commandBuffer, + const VkDrawIndirectCount2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRendering2EXT( + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfo2EXT* pConditionalRenderingBegin); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffers2EXT( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBindTransformFeedbackBuffer2InfoEXT* pBindingInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedback2EXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterRange, + uint32_t counterRangeCount, + const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedback2EXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterRange, + uint32_t counterRangeCount, + const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCount2EXT( + VkCommandBuffer commandBuffer, + uint32_t instanceCount, + uint32_t firstInstance, + const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfo, + uint32_t counterOffset, + uint32_t vertexStride); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirect2EXT( + VkCommandBuffer commandBuffer, + const VkDrawIndirect2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCount2EXT( + VkCommandBuffer commandBuffer, + const VkDrawIndirectCount2InfoKHR* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdWriteMarkerToMemoryAMD( + VkCommandBuffer commandBuffer, + const VkMemoryMarkerInfoAMD* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructure2KHR( + VkDevice device, + const VkAccelerationStructureCreateInfo2KHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure); +#endif #endif @@ -10958,30 +12901,42 @@ typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); #endif +#endif // VK_KHR_format_feature_flags2 is a preprocessor guard. Do not pass it to API calls. @@ -11027,10 +12982,24 @@ typedef struct VkTraceRaysIndirectCommand2KHR { typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirect2KHR)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirect2KHR( VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress); #endif +#endif + + +// VK_KHR_shader_untyped_pointers is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_untyped_pointers 1 +#define VK_KHR_SHADER_UNTYPED_POINTERS_SPEC_VERSION 1 +#define VK_KHR_SHADER_UNTYPED_POINTERS_EXTENSION_NAME "VK_KHR_shader_untyped_pointers" +typedef struct VkPhysicalDeviceShaderUntypedPointersFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderUntypedPointers; +} VkPhysicalDeviceShaderUntypedPointersFeaturesKHR; + // VK_KHR_portability_enumeration is a preprocessor guard. Do not pass it to API calls. @@ -11056,34 +13025,35 @@ typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice dev typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #endif +#endif // VK_KHR_shader_subgroup_rotate is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_shader_subgroup_rotate 1 #define VK_KHR_SHADER_SUBGROUP_ROTATE_SPEC_VERSION 2 #define VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME "VK_KHR_shader_subgroup_rotate" -typedef struct VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupRotate; - VkBool32 shaderSubgroupRotateClustered; -} VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR; +typedef VkPhysicalDeviceShaderSubgroupRotateFeatures VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR; @@ -11103,160 +13073,126 @@ typedef struct VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR { #define VK_KHR_maintenance5 1 #define VK_KHR_MAINTENANCE_5_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE_5_EXTENSION_NAME "VK_KHR_maintenance5" -typedef VkFlags64 VkPipelineCreateFlags2KHR; +typedef VkPipelineCreateFlags2 VkPipelineCreateFlags2KHR; -// Flag bits for VkPipelineCreateFlagBits2KHR -typedef VkFlags64 VkPipelineCreateFlagBits2KHR; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT_KHR = 0x00000001ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR = 0x00000002ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR = 0x00000004ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT_KHR = 0x00000010ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DEFER_COMPILE_BIT_NV = 0x00000020ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_CAPTURE_STATISTICS_BIT_KHR = 0x00000040ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR = 0x00000100ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR = 0x00000200ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR = 0x00000800ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_INDIRECT_BINDABLE_BIT_NV = 0x00040000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000ULL; -static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DESCRIPTOR_BUFFER_BIT_EXT = 0x20000000ULL; +typedef VkPipelineCreateFlagBits2 VkPipelineCreateFlagBits2KHR; -typedef VkFlags64 VkBufferUsageFlags2KHR; +typedef VkBufferUsageFlags2 VkBufferUsageFlags2KHR; -// Flag bits for VkBufferUsageFlagBits2KHR -typedef VkFlags64 VkBufferUsageFlagBits2KHR; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT_KHR = 0x00000001ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFER_DST_BIT_KHR = 0x00000002ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000004ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT_KHR = 0x00000010ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR = 0x00000020ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT_KHR = 0x00000040ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT_KHR = 0x00000080ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT_KHR = 0x00000100ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_EXECUTION_GRAPH_SCRATCH_BIT_AMDX = 0x02000000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_RAY_TRACING_BIT_NV = 0x00000400ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR = 0x00004000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT = 0x00200000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00400000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT = 0x04000000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000ULL; -static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_MICROMAP_STORAGE_BIT_EXT = 0x01000000ULL; +typedef VkBufferUsageFlagBits2 VkBufferUsageFlagBits2KHR; -typedef struct VkPhysicalDeviceMaintenance5FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 maintenance5; -} VkPhysicalDeviceMaintenance5FeaturesKHR; +typedef VkPhysicalDeviceMaintenance5Features VkPhysicalDeviceMaintenance5FeaturesKHR; -typedef struct VkPhysicalDeviceMaintenance5PropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting; - VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting; - VkBool32 depthStencilSwizzleOneSupport; - VkBool32 polygonModePointSize; - VkBool32 nonStrictSinglePixelWideLinesUseParallelogram; - VkBool32 nonStrictWideLinesUseParallelogram; -} VkPhysicalDeviceMaintenance5PropertiesKHR; +typedef VkPhysicalDeviceMaintenance5Properties VkPhysicalDeviceMaintenance5PropertiesKHR; -typedef struct VkRenderingAreaInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat* pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; -} VkRenderingAreaInfoKHR; +typedef VkRenderingAreaInfo VkRenderingAreaInfoKHR; -typedef struct VkImageSubresource2KHR { - VkStructureType sType; - void* pNext; - VkImageSubresource imageSubresource; -} VkImageSubresource2KHR; +typedef VkDeviceImageSubresourceInfo VkDeviceImageSubresourceInfoKHR; -typedef struct VkDeviceImageSubresourceInfoKHR { - VkStructureType sType; - const void* pNext; - const VkImageCreateInfo* pCreateInfo; - const VkImageSubresource2KHR* pSubresource; -} VkDeviceImageSubresourceInfoKHR; +typedef VkImageSubresource2 VkImageSubresource2KHR; -typedef struct VkSubresourceLayout2KHR { - VkStructureType sType; - void* pNext; - VkSubresourceLayout subresourceLayout; -} VkSubresourceLayout2KHR; +typedef VkSubresourceLayout2 VkSubresourceLayout2KHR; -typedef struct VkPipelineCreateFlags2CreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags2KHR flags; -} VkPipelineCreateFlags2CreateInfoKHR; +typedef VkPipelineCreateFlags2CreateInfo VkPipelineCreateFlags2CreateInfoKHR; -typedef struct VkBufferUsageFlags2CreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkBufferUsageFlags2KHR usage; -} VkBufferUsageFlags2CreateInfoKHR; +typedef VkBufferUsageFlags2CreateInfo VkBufferUsageFlags2CreateInfoKHR; typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer2KHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkIndexType indexType); -typedef void (VKAPI_PTR *PFN_vkGetRenderingAreaGranularityKHR)(VkDevice device, const VkRenderingAreaInfoKHR* pRenderingAreaInfo, VkExtent2D* pGranularity); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSubresourceLayoutKHR)(VkDevice device, const VkDeviceImageSubresourceInfoKHR* pInfo, VkSubresourceLayout2KHR* pLayout); -typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2KHR)(VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource, VkSubresourceLayout2KHR* pLayout); +typedef void (VKAPI_PTR *PFN_vkGetRenderingAreaGranularityKHR)(VkDevice device, const VkRenderingAreaInfo* pRenderingAreaInfo, VkExtent2D* pGranularity); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSubresourceLayoutKHR)(VkDevice device, const VkDeviceImageSubresourceInfo* pInfo, VkSubresourceLayout2* pLayout); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2KHR)(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource, VkSubresourceLayout2* pLayout); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer2KHR( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkIndexType indexType); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetRenderingAreaGranularityKHR( VkDevice device, - const VkRenderingAreaInfoKHR* pRenderingAreaInfo, + const VkRenderingAreaInfo* pRenderingAreaInfo, VkExtent2D* pGranularity); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSubresourceLayoutKHR( VkDevice device, - const VkDeviceImageSubresourceInfoKHR* pInfo, - VkSubresourceLayout2KHR* pLayout); + const VkDeviceImageSubresourceInfo* pInfo, + VkSubresourceLayout2* pLayout); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2KHR( VkDevice device, VkImage image, - const VkImageSubresource2KHR* pSubresource, - VkSubresourceLayout2KHR* pLayout); + const VkImageSubresource2* pSubresource, + VkSubresourceLayout2* pLayout); +#endif +#endif + + +// VK_KHR_present_id2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_present_id2 1 +#define VK_KHR_PRESENT_ID_2_SPEC_VERSION 1 +#define VK_KHR_PRESENT_ID_2_EXTENSION_NAME "VK_KHR_present_id2" +typedef struct VkSurfaceCapabilitiesPresentId2KHR { + VkStructureType sType; + void* pNext; + VkBool32 presentId2Supported; +} VkSurfaceCapabilitiesPresentId2KHR; + +typedef struct VkPresentId2KHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const uint64_t* pPresentIds; +} VkPresentId2KHR; + +typedef struct VkPhysicalDevicePresentId2FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentId2; +} VkPhysicalDevicePresentId2FeaturesKHR; + + + +// VK_KHR_present_wait2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_present_wait2 1 +#define VK_KHR_PRESENT_WAIT_2_SPEC_VERSION 1 +#define VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME "VK_KHR_present_wait2" +typedef struct VkSurfaceCapabilitiesPresentWait2KHR { + VkStructureType sType; + void* pNext; + VkBool32 presentWait2Supported; +} VkSurfaceCapabilitiesPresentWait2KHR; + +typedef struct VkPhysicalDevicePresentWait2FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentWait2; +} VkPhysicalDevicePresentWait2FeaturesKHR; + +typedef struct VkPresentWait2InfoKHR { + VkStructureType sType; + const void* pNext; + uint64_t presentId; + uint64_t timeout; +} VkPresentWait2InfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresent2KHR)(VkDevice device, VkSwapchainKHR swapchain, const VkPresentWait2InfoKHR* pPresentWait2Info); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresent2KHR( + VkDevice device, + VkSwapchainKHR swapchain, + const VkPresentWait2InfoKHR* pPresentWait2Info); +#endif #endif @@ -11272,6 +13208,259 @@ typedef struct VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR { +// VK_KHR_pipeline_binary is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_pipeline_binary 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineBinaryKHR) +#define VK_MAX_PIPELINE_BINARY_KEY_SIZE_KHR 32U +#define VK_KHR_PIPELINE_BINARY_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_BINARY_EXTENSION_NAME "VK_KHR_pipeline_binary" +typedef struct VkPhysicalDevicePipelineBinaryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 pipelineBinaries; +} VkPhysicalDevicePipelineBinaryFeaturesKHR; + +typedef struct VkPhysicalDevicePipelineBinaryPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 pipelineBinaryInternalCache; + VkBool32 pipelineBinaryInternalCacheControl; + VkBool32 pipelineBinaryPrefersInternalCache; + VkBool32 pipelineBinaryPrecompiledInternalCache; + VkBool32 pipelineBinaryCompressedData; +} VkPhysicalDevicePipelineBinaryPropertiesKHR; + +typedef struct VkDevicePipelineBinaryInternalCacheControlKHR { + VkStructureType sType; + const void* pNext; + VkBool32 disableInternalCache; +} VkDevicePipelineBinaryInternalCacheControlKHR; + +typedef struct VkPipelineBinaryKeyKHR { + VkStructureType sType; + void* pNext; + uint32_t keySize; + uint8_t key[VK_MAX_PIPELINE_BINARY_KEY_SIZE_KHR]; +} VkPipelineBinaryKeyKHR; + +typedef struct VkPipelineBinaryDataKHR { + size_t dataSize; + void* pData; +} VkPipelineBinaryDataKHR; + +typedef struct VkPipelineBinaryKeysAndDataKHR { + uint32_t binaryCount; + const VkPipelineBinaryKeyKHR* pPipelineBinaryKeys; + const VkPipelineBinaryDataKHR* pPipelineBinaryData; +} VkPipelineBinaryKeysAndDataKHR; + +typedef struct VkPipelineCreateInfoKHR { + VkStructureType sType; + void* pNext; +} VkPipelineCreateInfoKHR; + +typedef struct VkPipelineBinaryCreateInfoKHR { + VkStructureType sType; + const void* pNext; + const VkPipelineBinaryKeysAndDataKHR* pKeysAndDataInfo; + VkPipeline pipeline; + const VkPipelineCreateInfoKHR* pPipelineCreateInfo; +} VkPipelineBinaryCreateInfoKHR; + +typedef struct VkPipelineBinaryInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t binaryCount; + const VkPipelineBinaryKHR* pPipelineBinaries; +} VkPipelineBinaryInfoKHR; + +typedef struct VkReleaseCapturedPipelineDataInfoKHR { + VkStructureType sType; + void* pNext; + VkPipeline pipeline; +} VkReleaseCapturedPipelineDataInfoKHR; + +typedef struct VkPipelineBinaryDataInfoKHR { + VkStructureType sType; + void* pNext; + VkPipelineBinaryKHR pipelineBinary; +} VkPipelineBinaryDataInfoKHR; + +typedef struct VkPipelineBinaryHandlesInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t pipelineBinaryCount; + VkPipelineBinaryKHR* pPipelineBinaries; +} VkPipelineBinaryHandlesInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineBinariesKHR)(VkDevice device, const VkPipelineBinaryCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineBinaryHandlesInfoKHR* pBinaries); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineBinaryKHR)(VkDevice device, VkPipelineBinaryKHR pipelineBinary, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineKeyKHR)(VkDevice device, const VkPipelineCreateInfoKHR* pPipelineCreateInfo, VkPipelineBinaryKeyKHR* pPipelineKey); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineBinaryDataKHR)(VkDevice device, const VkPipelineBinaryDataInfoKHR* pInfo, VkPipelineBinaryKeyKHR* pPipelineBinaryKey, size_t* pPipelineBinaryDataSize, void* pPipelineBinaryData); +typedef VkResult (VKAPI_PTR *PFN_vkReleaseCapturedPipelineDataKHR)(VkDevice device, const VkReleaseCapturedPipelineDataInfoKHR* pInfo, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineBinariesKHR( + VkDevice device, + const VkPipelineBinaryCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineBinaryHandlesInfoKHR* pBinaries); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineBinaryKHR( + VkDevice device, + VkPipelineBinaryKHR pipelineBinary, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineKeyKHR( + VkDevice device, + const VkPipelineCreateInfoKHR* pPipelineCreateInfo, + VkPipelineBinaryKeyKHR* pPipelineKey); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineBinaryDataKHR( + VkDevice device, + const VkPipelineBinaryDataInfoKHR* pInfo, + VkPipelineBinaryKeyKHR* pPipelineBinaryKey, + size_t* pPipelineBinaryDataSize, + void* pPipelineBinaryData); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseCapturedPipelineDataKHR( + VkDevice device, + const VkReleaseCapturedPipelineDataInfoKHR* pInfo, + const VkAllocationCallbacks* pAllocator); +#endif +#endif + + +// VK_KHR_surface_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_surface_maintenance1 1 +#define VK_KHR_SURFACE_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_surface_maintenance1" + +typedef enum VkPresentScalingFlagBitsKHR { + VK_PRESENT_SCALING_ONE_TO_ONE_BIT_KHR = 0x00000001, + VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_KHR = 0x00000002, + VK_PRESENT_SCALING_STRETCH_BIT_KHR = 0x00000004, + VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT = VK_PRESENT_SCALING_ONE_TO_ONE_BIT_KHR, + VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT = VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_KHR, + VK_PRESENT_SCALING_STRETCH_BIT_EXT = VK_PRESENT_SCALING_STRETCH_BIT_KHR, + VK_PRESENT_SCALING_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentScalingFlagBitsKHR; +typedef VkFlags VkPresentScalingFlagsKHR; + +typedef enum VkPresentGravityFlagBitsKHR { + VK_PRESENT_GRAVITY_MIN_BIT_KHR = 0x00000001, + VK_PRESENT_GRAVITY_MAX_BIT_KHR = 0x00000002, + VK_PRESENT_GRAVITY_CENTERED_BIT_KHR = 0x00000004, + VK_PRESENT_GRAVITY_MIN_BIT_EXT = VK_PRESENT_GRAVITY_MIN_BIT_KHR, + VK_PRESENT_GRAVITY_MAX_BIT_EXT = VK_PRESENT_GRAVITY_MAX_BIT_KHR, + VK_PRESENT_GRAVITY_CENTERED_BIT_EXT = VK_PRESENT_GRAVITY_CENTERED_BIT_KHR, + VK_PRESENT_GRAVITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentGravityFlagBitsKHR; +typedef VkFlags VkPresentGravityFlagsKHR; +typedef struct VkSurfacePresentModeKHR { + VkStructureType sType; + void* pNext; + VkPresentModeKHR presentMode; +} VkSurfacePresentModeKHR; + +typedef struct VkSurfacePresentScalingCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkPresentScalingFlagsKHR supportedPresentScaling; + VkPresentGravityFlagsKHR supportedPresentGravityX; + VkPresentGravityFlagsKHR supportedPresentGravityY; + VkExtent2D minScaledImageExtent; + VkExtent2D maxScaledImageExtent; +} VkSurfacePresentScalingCapabilitiesKHR; + +typedef struct VkSurfacePresentModeCompatibilityKHR { + VkStructureType sType; + void* pNext; + uint32_t presentModeCount; + VkPresentModeKHR* pPresentModes; +} VkSurfacePresentModeCompatibilityKHR; + + + +// VK_KHR_swapchain_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_swapchain_maintenance1 1 +#define VK_KHR_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_swapchain_maintenance1" +typedef struct VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 swapchainMaintenance1; +} VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR; + +typedef struct VkSwapchainPresentFenceInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkFence* pFences; +} VkSwapchainPresentFenceInfoKHR; + +typedef struct VkSwapchainPresentModesCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t presentModeCount; + const VkPresentModeKHR* pPresentModes; +} VkSwapchainPresentModesCreateInfoKHR; + +typedef struct VkSwapchainPresentModeInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentModeKHR* pPresentModes; +} VkSwapchainPresentModeInfoKHR; + +typedef struct VkSwapchainPresentScalingCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkPresentScalingFlagsKHR scalingBehavior; + VkPresentGravityFlagsKHR presentGravityX; + VkPresentGravityFlagsKHR presentGravityY; +} VkSwapchainPresentScalingCreateInfoKHR; + +typedef struct VkReleaseSwapchainImagesInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint32_t imageIndexCount; + const uint32_t* pImageIndices; +} VkReleaseSwapchainImagesInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkReleaseSwapchainImagesKHR)(VkDevice device, const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseSwapchainImagesKHR( + VkDevice device, + const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo); +#endif +#endif + + +// VK_KHR_internally_synchronized_queues is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_internally_synchronized_queues 1 +#define VK_KHR_INTERNALLY_SYNCHRONIZED_QUEUES_SPEC_VERSION 1 +#define VK_KHR_INTERNALLY_SYNCHRONIZED_QUEUES_EXTENSION_NAME "VK_KHR_internally_synchronized_queues" +typedef struct VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 internallySynchronizedQueues; +} VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR; + + + // VK_KHR_cooperative_matrix is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_cooperative_matrix 1 #define VK_KHR_COOPERATIVE_MATRIX_SPEC_VERSION 2 @@ -11289,6 +13478,11 @@ typedef enum VkComponentTypeKHR { VK_COMPONENT_TYPE_UINT16_KHR = 8, VK_COMPONENT_TYPE_UINT32_KHR = 9, VK_COMPONENT_TYPE_UINT64_KHR = 10, + VK_COMPONENT_TYPE_BFLOAT16_KHR = 1000141000, + VK_COMPONENT_TYPE_SINT8_PACKED_NV = 1000491000, + VK_COMPONENT_TYPE_UINT8_PACKED_NV = 1000491001, + VK_COMPONENT_TYPE_FLOAT8_E4M3_EXT = 1000491002, + VK_COMPONENT_TYPE_FLOAT8_E5M2_EXT = 1000491003, VK_COMPONENT_TYPE_FLOAT16_NV = VK_COMPONENT_TYPE_FLOAT16_KHR, VK_COMPONENT_TYPE_FLOAT32_NV = VK_COMPONENT_TYPE_FLOAT32_KHR, VK_COMPONENT_TYPE_FLOAT64_NV = VK_COMPONENT_TYPE_FLOAT64_KHR, @@ -11300,6 +13494,8 @@ typedef enum VkComponentTypeKHR { VK_COMPONENT_TYPE_UINT16_NV = VK_COMPONENT_TYPE_UINT16_KHR, VK_COMPONENT_TYPE_UINT32_NV = VK_COMPONENT_TYPE_UINT32_KHR, VK_COMPONENT_TYPE_UINT64_NV = VK_COMPONENT_TYPE_UINT64_KHR, + VK_COMPONENT_TYPE_FLOAT_E4M3_NV = VK_COMPONENT_TYPE_FLOAT8_E4M3_EXT, + VK_COMPONENT_TYPE_FLOAT_E5M2_NV = VK_COMPONENT_TYPE_FLOAT8_E5M2_EXT, VK_COMPONENT_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF } VkComponentTypeKHR; @@ -11344,11 +13540,32 @@ typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesKHR { typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesKHR* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesKHR* pProperties); #endif +#endif + + +// VK_KHR_compute_shader_derivatives is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_compute_shader_derivatives 1 +#define VK_KHR_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 +#define VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_KHR_compute_shader_derivatives" +typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 computeDerivativeGroupQuads; + VkBool32 computeDerivativeGroupLinear; +} VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR; + +typedef struct VkPhysicalDeviceComputeShaderDerivativesPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 meshAndTaskShaderDerivatives; +} VkPhysicalDeviceComputeShaderDerivativesPropertiesKHR; + // VK_KHR_video_decode_av1 is a preprocessor guard. Do not pass it to API calls. @@ -11396,6 +13613,238 @@ typedef struct VkVideoDecodeAV1DpbSlotInfoKHR { +// VK_KHR_video_encode_av1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_av1 1 +#include "../vk_video/vulkan_video_codec_av1std_encode.h" +#define VK_KHR_VIDEO_ENCODE_AV1_SPEC_VERSION 1 +#define VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME "VK_KHR_video_encode_av1" + +typedef enum VkVideoEncodeAV1PredictionModeKHR { + VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_INTRA_ONLY_KHR = 0, + VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_SINGLE_REFERENCE_KHR = 1, + VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_UNIDIRECTIONAL_COMPOUND_KHR = 2, + VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_BIDIRECTIONAL_COMPOUND_KHR = 3, + VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1PredictionModeKHR; + +typedef enum VkVideoEncodeAV1RateControlGroupKHR { + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_INTRA_KHR = 0, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_PREDICTIVE_KHR = 1, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_BIPREDICTIVE_KHR = 2, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1RateControlGroupKHR; + +typedef enum VkVideoEncodeAV1CapabilityFlagBitsKHR { + VK_VIDEO_ENCODE_AV1_CAPABILITY_PER_RATE_CONTROL_GROUP_MIN_MAX_Q_INDEX_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_AV1_CAPABILITY_GENERATE_OBU_EXTENSION_HEADER_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_AV1_CAPABILITY_PRIMARY_REFERENCE_CDF_ONLY_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_AV1_CAPABILITY_FRAME_SIZE_OVERRIDE_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_AV1_CAPABILITY_MOTION_VECTOR_SCALING_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_AV1_CAPABILITY_COMPOUND_PREDICTION_INTRA_REFRESH_BIT_KHR = 0x00000020, + VK_VIDEO_ENCODE_AV1_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1CapabilityFlagBitsKHR; +typedef VkFlags VkVideoEncodeAV1CapabilityFlagsKHR; + +typedef enum VkVideoEncodeAV1StdFlagBitsKHR { + VK_VIDEO_ENCODE_AV1_STD_UNIFORM_TILE_SPACING_FLAG_SET_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_AV1_STD_SKIP_MODE_PRESENT_UNSET_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_AV1_STD_PRIMARY_REF_FRAME_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_AV1_STD_DELTA_Q_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_AV1_STD_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1StdFlagBitsKHR; +typedef VkFlags VkVideoEncodeAV1StdFlagsKHR; + +typedef enum VkVideoEncodeAV1SuperblockSizeFlagBitsKHR { + VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_128_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1SuperblockSizeFlagBitsKHR; +typedef VkFlags VkVideoEncodeAV1SuperblockSizeFlagsKHR; + +typedef enum VkVideoEncodeAV1RateControlFlagBitsKHR { + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_REGULAR_GOP_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_TEMPORAL_LAYER_PATTERN_DYADIC_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_AV1_RATE_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeAV1RateControlFlagBitsKHR; +typedef VkFlags VkVideoEncodeAV1RateControlFlagsKHR; +typedef struct VkPhysicalDeviceVideoEncodeAV1FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoEncodeAV1; +} VkPhysicalDeviceVideoEncodeAV1FeaturesKHR; + +typedef struct VkVideoEncodeAV1CapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeAV1CapabilityFlagsKHR flags; + StdVideoAV1Level maxLevel; + VkExtent2D codedPictureAlignment; + VkExtent2D maxTiles; + VkExtent2D minTileSize; + VkExtent2D maxTileSize; + VkVideoEncodeAV1SuperblockSizeFlagsKHR superblockSizes; + uint32_t maxSingleReferenceCount; + uint32_t singleReferenceNameMask; + uint32_t maxUnidirectionalCompoundReferenceCount; + uint32_t maxUnidirectionalCompoundGroup1ReferenceCount; + uint32_t unidirectionalCompoundReferenceNameMask; + uint32_t maxBidirectionalCompoundReferenceCount; + uint32_t maxBidirectionalCompoundGroup1ReferenceCount; + uint32_t maxBidirectionalCompoundGroup2ReferenceCount; + uint32_t bidirectionalCompoundReferenceNameMask; + uint32_t maxTemporalLayerCount; + uint32_t maxSpatialLayerCount; + uint32_t maxOperatingPoints; + uint32_t minQIndex; + uint32_t maxQIndex; + VkBool32 prefersGopRemainingFrames; + VkBool32 requiresGopRemainingFrames; + VkVideoEncodeAV1StdFlagsKHR stdSyntaxFlags; +} VkVideoEncodeAV1CapabilitiesKHR; + +typedef struct VkVideoEncodeAV1QIndexKHR { + uint32_t intraQIndex; + uint32_t predictiveQIndex; + uint32_t bipredictiveQIndex; +} VkVideoEncodeAV1QIndexKHR; + +typedef struct VkVideoEncodeAV1QualityLevelPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeAV1RateControlFlagsKHR preferredRateControlFlags; + uint32_t preferredGopFrameCount; + uint32_t preferredKeyFramePeriod; + uint32_t preferredConsecutiveBipredictiveFrameCount; + uint32_t preferredTemporalLayerCount; + VkVideoEncodeAV1QIndexKHR preferredConstantQIndex; + uint32_t preferredMaxSingleReferenceCount; + uint32_t preferredSingleReferenceNameMask; + uint32_t preferredMaxUnidirectionalCompoundReferenceCount; + uint32_t preferredMaxUnidirectionalCompoundGroup1ReferenceCount; + uint32_t preferredUnidirectionalCompoundReferenceNameMask; + uint32_t preferredMaxBidirectionalCompoundReferenceCount; + uint32_t preferredMaxBidirectionalCompoundGroup1ReferenceCount; + uint32_t preferredMaxBidirectionalCompoundGroup2ReferenceCount; + uint32_t preferredBidirectionalCompoundReferenceNameMask; +} VkVideoEncodeAV1QualityLevelPropertiesKHR; + +typedef struct VkVideoEncodeAV1SessionCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMaxLevel; + StdVideoAV1Level maxLevel; +} VkVideoEncodeAV1SessionCreateInfoKHR; + +typedef struct VkVideoEncodeAV1SessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoAV1SequenceHeader* pStdSequenceHeader; + const StdVideoEncodeAV1DecoderModelInfo* pStdDecoderModelInfo; + uint32_t stdOperatingPointCount; + const StdVideoEncodeAV1OperatingPointInfo* pStdOperatingPoints; +} VkVideoEncodeAV1SessionParametersCreateInfoKHR; + +typedef struct VkVideoEncodeAV1PictureInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeAV1PredictionModeKHR predictionMode; + VkVideoEncodeAV1RateControlGroupKHR rateControlGroup; + uint32_t constantQIndex; + const StdVideoEncodeAV1PictureInfo* pStdPictureInfo; + int32_t referenceNameSlotIndices[VK_MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR]; + VkBool32 primaryReferenceCdfOnly; + VkBool32 generateObuExtensionHeader; +} VkVideoEncodeAV1PictureInfoKHR; + +typedef struct VkVideoEncodeAV1DpbSlotInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoEncodeAV1ReferenceInfo* pStdReferenceInfo; +} VkVideoEncodeAV1DpbSlotInfoKHR; + +typedef struct VkVideoEncodeAV1ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoAV1Profile stdProfile; +} VkVideoEncodeAV1ProfileInfoKHR; + +typedef struct VkVideoEncodeAV1FrameSizeKHR { + uint32_t intraFrameSize; + uint32_t predictiveFrameSize; + uint32_t bipredictiveFrameSize; +} VkVideoEncodeAV1FrameSizeKHR; + +typedef struct VkVideoEncodeAV1GopRemainingFrameInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useGopRemainingFrames; + uint32_t gopRemainingIntra; + uint32_t gopRemainingPredictive; + uint32_t gopRemainingBipredictive; +} VkVideoEncodeAV1GopRemainingFrameInfoKHR; + +typedef struct VkVideoEncodeAV1RateControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeAV1RateControlFlagsKHR flags; + uint32_t gopFrameCount; + uint32_t keyFramePeriod; + uint32_t consecutiveBipredictiveFrameCount; + uint32_t temporalLayerCount; +} VkVideoEncodeAV1RateControlInfoKHR; + +typedef struct VkVideoEncodeAV1RateControlLayerInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMinQIndex; + VkVideoEncodeAV1QIndexKHR minQIndex; + VkBool32 useMaxQIndex; + VkVideoEncodeAV1QIndexKHR maxQIndex; + VkBool32 useMaxFrameSize; + VkVideoEncodeAV1FrameSizeKHR maxFrameSize; +} VkVideoEncodeAV1RateControlLayerInfoKHR; + + + +// VK_KHR_video_decode_vp9 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_decode_vp9 1 +#include "../vk_video/vulkan_video_codec_vp9std.h" +#include "../vk_video/vulkan_video_codec_vp9std_decode.h" +#define VK_MAX_VIDEO_VP9_REFERENCES_PER_FRAME_KHR 3U +#define VK_KHR_VIDEO_DECODE_VP9_SPEC_VERSION 1 +#define VK_KHR_VIDEO_DECODE_VP9_EXTENSION_NAME "VK_KHR_video_decode_vp9" +typedef struct VkPhysicalDeviceVideoDecodeVP9FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoDecodeVP9; +} VkPhysicalDeviceVideoDecodeVP9FeaturesKHR; + +typedef struct VkVideoDecodeVP9ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoVP9Profile stdProfile; +} VkVideoDecodeVP9ProfileInfoKHR; + +typedef struct VkVideoDecodeVP9CapabilitiesKHR { + VkStructureType sType; + void* pNext; + StdVideoVP9Level maxLevel; +} VkVideoDecodeVP9CapabilitiesKHR; + +typedef struct VkVideoDecodeVP9PictureInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeVP9PictureInfo* pStdPictureInfo; + int32_t referenceNameSlotIndices[VK_MAX_VIDEO_VP9_REFERENCES_PER_FRAME_KHR]; + uint32_t uncompressedHeaderOffset; + uint32_t compressedHeaderOffset; + uint32_t tilesOffset; +} VkVideoDecodeVP9PictureInfoKHR; + + + // VK_KHR_video_maintenance1 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_video_maintenance1 1 #define VK_KHR_VIDEO_MAINTENANCE_1_SPEC_VERSION 1 @@ -11420,31 +13869,13 @@ typedef struct VkVideoInlineQueryInfoKHR { #define VK_KHR_vertex_attribute_divisor 1 #define VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 1 #define VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_KHR_vertex_attribute_divisor" -typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t maxVertexAttribDivisor; - VkBool32 supportsNonZeroFirstInstance; -} VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR; +typedef VkPhysicalDeviceVertexAttributeDivisorProperties VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR; -typedef struct VkVertexInputBindingDivisorDescriptionKHR { - uint32_t binding; - uint32_t divisor; -} VkVertexInputBindingDivisorDescriptionKHR; +typedef VkVertexInputBindingDivisorDescription VkVertexInputBindingDivisorDescriptionKHR; -typedef struct VkPipelineVertexInputDivisorStateCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t vertexBindingDivisorCount; - const VkVertexInputBindingDivisorDescriptionKHR* pVertexBindingDivisors; -} VkPipelineVertexInputDivisorStateCreateInfoKHR; +typedef VkPipelineVertexInputDivisorStateCreateInfo VkPipelineVertexInputDivisorStateCreateInfoKHR; -typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 vertexAttributeInstanceRateDivisor; - VkBool32 vertexAttributeInstanceRateZeroDivisor; -} VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR; +typedef VkPhysicalDeviceVertexAttributeDivisorFeatures VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR; @@ -11454,15 +13885,30 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR { #define VK_KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_KHR_load_store_op_none" +// VK_KHR_unified_image_layouts is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_unified_image_layouts 1 +#define VK_KHR_UNIFIED_IMAGE_LAYOUTS_SPEC_VERSION 1 +#define VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME "VK_KHR_unified_image_layouts" +typedef struct VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 unifiedImageLayouts; + VkBool32 unifiedImageLayoutsVideo; +} VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR; + +typedef struct VkAttachmentFeedbackLoopInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 feedbackLoopEnable; +} VkAttachmentFeedbackLoopInfoEXT; + + + // VK_KHR_shader_float_controls2 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_shader_float_controls2 1 #define VK_KHR_SHADER_FLOAT_CONTROLS_2_SPEC_VERSION 1 #define VK_KHR_SHADER_FLOAT_CONTROLS_2_EXTENSION_NAME "VK_KHR_shader_float_controls2" -typedef struct VkPhysicalDeviceShaderFloatControls2FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderFloatControls2; -} VkPhysicalDeviceShaderFloatControls2FeaturesKHR; +typedef VkPhysicalDeviceShaderFloatControls2Features VkPhysicalDeviceShaderFloatControls2FeaturesKHR; @@ -11470,11 +13916,7 @@ typedef struct VkPhysicalDeviceShaderFloatControls2FeaturesKHR { #define VK_KHR_index_type_uint8 1 #define VK_KHR_INDEX_TYPE_UINT8_SPEC_VERSION 1 #define VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_KHR_index_type_uint8" -typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 indexTypeUint8; -} VkPhysicalDeviceIndexTypeUint8FeaturesKHR; +typedef VkPhysicalDeviceIndexTypeUint8Features VkPhysicalDeviceIndexTypeUint8FeaturesKHR; @@ -11482,52 +13924,24 @@ typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesKHR { #define VK_KHR_line_rasterization 1 #define VK_KHR_LINE_RASTERIZATION_SPEC_VERSION 1 #define VK_KHR_LINE_RASTERIZATION_EXTENSION_NAME "VK_KHR_line_rasterization" +typedef VkLineRasterizationMode VkLineRasterizationModeKHR; -typedef enum VkLineRasterizationModeKHR { - VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR = 0, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_KHR = 1, - VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR = 2, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR = 3, - VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_KHR, - VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR, - VK_LINE_RASTERIZATION_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkLineRasterizationModeKHR; -typedef struct VkPhysicalDeviceLineRasterizationFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 rectangularLines; - VkBool32 bresenhamLines; - VkBool32 smoothLines; - VkBool32 stippledRectangularLines; - VkBool32 stippledBresenhamLines; - VkBool32 stippledSmoothLines; -} VkPhysicalDeviceLineRasterizationFeaturesKHR; +typedef VkPhysicalDeviceLineRasterizationFeatures VkPhysicalDeviceLineRasterizationFeaturesKHR; -typedef struct VkPhysicalDeviceLineRasterizationPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t lineSubPixelPrecisionBits; -} VkPhysicalDeviceLineRasterizationPropertiesKHR; +typedef VkPhysicalDeviceLineRasterizationProperties VkPhysicalDeviceLineRasterizationPropertiesKHR; -typedef struct VkPipelineRasterizationLineStateCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkLineRasterizationModeKHR lineRasterizationMode; - VkBool32 stippledLineEnable; - uint32_t lineStippleFactor; - uint16_t lineStipplePattern; -} VkPipelineRasterizationLineStateCreateInfoKHR; +typedef VkPipelineRasterizationLineStateCreateInfo VkPipelineRasterizationLineStateCreateInfoKHR; typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleKHR)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleKHR( VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); #endif +#endif // VK_KHR_calibrated_timestamps is a preprocessor guard. Do not pass it to API calls. @@ -11540,6 +13954,8 @@ typedef enum VkTimeDomainKHR { VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR = 1, VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR = 2, VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR = 3, + VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT = 1000208000, + VK_TIME_DOMAIN_SWAPCHAIN_LOCAL_EXT = 1000208001, VK_TIME_DOMAIN_DEVICE_EXT = VK_TIME_DOMAIN_DEVICE_KHR, VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR, VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR, @@ -11556,11 +13972,14 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR) typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsKHR)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsKHR( VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainKHR* pTimeDomains); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsKHR( VkDevice device, uint32_t timestampCount, @@ -11568,17 +13987,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsKHR( uint64_t* pTimestamps, uint64_t* pMaxDeviation); #endif +#endif // VK_KHR_shader_expect_assume is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_shader_expect_assume 1 #define VK_KHR_SHADER_EXPECT_ASSUME_SPEC_VERSION 1 #define VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME "VK_KHR_shader_expect_assume" -typedef struct VkPhysicalDeviceShaderExpectAssumeFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderExpectAssume; -} VkPhysicalDeviceShaderExpectAssumeFeaturesKHR; +typedef VkPhysicalDeviceShaderExpectAssumeFeatures VkPhysicalDeviceShaderExpectAssumeFeaturesKHR; @@ -11586,66 +14002,19 @@ typedef struct VkPhysicalDeviceShaderExpectAssumeFeaturesKHR { #define VK_KHR_maintenance6 1 #define VK_KHR_MAINTENANCE_6_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE_6_EXTENSION_NAME "VK_KHR_maintenance6" -typedef struct VkPhysicalDeviceMaintenance6FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 maintenance6; -} VkPhysicalDeviceMaintenance6FeaturesKHR; +typedef VkPhysicalDeviceMaintenance6Features VkPhysicalDeviceMaintenance6FeaturesKHR; -typedef struct VkPhysicalDeviceMaintenance6PropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 blockTexelViewCompatibleMultipleLayers; - uint32_t maxCombinedImageSamplerDescriptorCount; - VkBool32 fragmentShadingRateClampCombinerInputs; -} VkPhysicalDeviceMaintenance6PropertiesKHR; +typedef VkPhysicalDeviceMaintenance6Properties VkPhysicalDeviceMaintenance6PropertiesKHR; -typedef struct VkBindMemoryStatusKHR { - VkStructureType sType; - const void* pNext; - VkResult* pResult; -} VkBindMemoryStatusKHR; +typedef VkBindMemoryStatus VkBindMemoryStatusKHR; -typedef struct VkBindDescriptorSetsInfoKHR { - VkStructureType sType; - const void* pNext; - VkShaderStageFlags stageFlags; - VkPipelineLayout layout; - uint32_t firstSet; - uint32_t descriptorSetCount; - const VkDescriptorSet* pDescriptorSets; - uint32_t dynamicOffsetCount; - const uint32_t* pDynamicOffsets; -} VkBindDescriptorSetsInfoKHR; +typedef VkBindDescriptorSetsInfo VkBindDescriptorSetsInfoKHR; -typedef struct VkPushConstantsInfoKHR { - VkStructureType sType; - const void* pNext; - VkPipelineLayout layout; - VkShaderStageFlags stageFlags; - uint32_t offset; - uint32_t size; - const void* pValues; -} VkPushConstantsInfoKHR; +typedef VkPushConstantsInfo VkPushConstantsInfoKHR; -typedef struct VkPushDescriptorSetInfoKHR { - VkStructureType sType; - const void* pNext; - VkShaderStageFlags stageFlags; - VkPipelineLayout layout; - uint32_t set; - uint32_t descriptorWriteCount; - const VkWriteDescriptorSet* pDescriptorWrites; -} VkPushDescriptorSetInfoKHR; +typedef VkPushDescriptorSetInfo VkPushDescriptorSetInfoKHR; -typedef struct VkPushDescriptorSetWithTemplateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDescriptorUpdateTemplate descriptorUpdateTemplate; - VkPipelineLayout layout; - uint32_t set; - const void* pData; -} VkPushDescriptorSetWithTemplateInfoKHR; +typedef VkPushDescriptorSetWithTemplateInfo VkPushDescriptorSetWithTemplateInfoKHR; typedef struct VkSetDescriptorBufferOffsetsInfoEXT { VkStructureType sType; @@ -11666,38 +14035,744 @@ typedef struct VkBindDescriptorBufferEmbeddedSamplersInfoEXT { uint32_t set; } VkBindDescriptorBufferEmbeddedSamplersInfoEXT; -typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets2KHR)(VkCommandBuffer commandBuffer, const VkBindDescriptorSetsInfoKHR* pBindDescriptorSetsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdPushConstants2KHR)(VkCommandBuffer commandBuffer, const VkPushConstantsInfoKHR* pPushConstantsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSet2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetInfoKHR* pPushDescriptorSetInfo); -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplate2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfoKHR* pPushDescriptorSetWithTemplateInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets2KHR)(VkCommandBuffer commandBuffer, const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants2KHR)(VkCommandBuffer commandBuffer, const VkPushConstantsInfo* pPushConstantsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSet2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetInfo* pPushDescriptorSetInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplate2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo); typedef void (VKAPI_PTR *PFN_vkCmdSetDescriptorBufferOffsets2EXT)(VkCommandBuffer commandBuffer, const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo); typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT)(VkCommandBuffer commandBuffer, const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets2KHR( VkCommandBuffer commandBuffer, - const VkBindDescriptorSetsInfoKHR* pBindDescriptorSetsInfo); + const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants2KHR( VkCommandBuffer commandBuffer, - const VkPushConstantsInfoKHR* pPushConstantsInfo); + const VkPushConstantsInfo* pPushConstantsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet2KHR( VkCommandBuffer commandBuffer, - const VkPushDescriptorSetInfoKHR* pPushDescriptorSetInfo); + const VkPushDescriptorSetInfo* pPushDescriptorSetInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate2KHR( VkCommandBuffer commandBuffer, - const VkPushDescriptorSetWithTemplateInfoKHR* pPushDescriptorSetWithTemplateInfo); + const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDescriptorBufferOffsets2EXT( VkCommandBuffer commandBuffer, const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBufferEmbeddedSamplers2EXT( VkCommandBuffer commandBuffer, const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo); #endif +#endif + + +// VK_KHR_copy_memory_indirect is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_copy_memory_indirect 1 +#define VK_KHR_COPY_MEMORY_INDIRECT_SPEC_VERSION 1 +#define VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME "VK_KHR_copy_memory_indirect" + +typedef enum VkAddressCopyFlagBitsKHR { + VK_ADDRESS_COPY_DEVICE_LOCAL_BIT_KHR = 0x00000001, + VK_ADDRESS_COPY_SPARSE_BIT_KHR = 0x00000002, + VK_ADDRESS_COPY_PROTECTED_BIT_KHR = 0x00000004, + VK_ADDRESS_COPY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAddressCopyFlagBitsKHR; +typedef VkFlags VkAddressCopyFlagsKHR; +typedef struct VkCopyMemoryIndirectCommandKHR { + VkDeviceAddress srcAddress; + VkDeviceAddress dstAddress; + VkDeviceSize size; +} VkCopyMemoryIndirectCommandKHR; + +typedef struct VkCopyMemoryIndirectInfoKHR { + VkStructureType sType; + const void* pNext; + VkAddressCopyFlagsKHR srcCopyFlags; + VkAddressCopyFlagsKHR dstCopyFlags; + uint32_t copyCount; + VkStridedDeviceAddressRangeKHR copyAddressRange; +} VkCopyMemoryIndirectInfoKHR; + +typedef struct VkCopyMemoryToImageIndirectCommandKHR { + VkDeviceAddress srcAddress; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkCopyMemoryToImageIndirectCommandKHR; + +typedef struct VkCopyMemoryToImageIndirectInfoKHR { + VkStructureType sType; + const void* pNext; + VkAddressCopyFlagsKHR srcCopyFlags; + uint32_t copyCount; + VkStridedDeviceAddressRangeKHR copyAddressRange; + VkImage dstImage; + VkImageLayout dstImageLayout; + const VkImageSubresourceLayers* pImageSubresources; +} VkCopyMemoryToImageIndirectInfoKHR; + +typedef struct VkPhysicalDeviceCopyMemoryIndirectFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 indirectMemoryCopy; + VkBool32 indirectMemoryToImageCopy; +} VkPhysicalDeviceCopyMemoryIndirectFeaturesKHR; + +typedef struct VkPhysicalDeviceCopyMemoryIndirectPropertiesKHR { + VkStructureType sType; + void* pNext; + VkQueueFlags supportedQueues; +} VkPhysicalDeviceCopyMemoryIndirectPropertiesKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryIndirectKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryIndirectInfoKHR* pCopyMemoryIndirectInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToImageIndirectKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToImageIndirectInfoKHR* pCopyMemoryToImageIndirectInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryIndirectKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryIndirectInfoKHR* pCopyMemoryIndirectInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageIndirectKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToImageIndirectInfoKHR* pCopyMemoryToImageIndirectInfo); +#endif +#endif + + +// VK_KHR_video_encode_intra_refresh is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_intra_refresh 1 +#define VK_KHR_VIDEO_ENCODE_INTRA_REFRESH_SPEC_VERSION 1 +#define VK_KHR_VIDEO_ENCODE_INTRA_REFRESH_EXTENSION_NAME "VK_KHR_video_encode_intra_refresh" + +typedef enum VkVideoEncodeIntraRefreshModeFlagBitsKHR { + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_NONE_KHR = 0, + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_PER_PICTURE_PARTITION_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_BASED_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_ROW_BASED_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_COLUMN_BASED_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeIntraRefreshModeFlagBitsKHR; +typedef VkFlags VkVideoEncodeIntraRefreshModeFlagsKHR; +typedef struct VkVideoEncodeIntraRefreshCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeIntraRefreshModeFlagsKHR intraRefreshModes; + uint32_t maxIntraRefreshCycleDuration; + uint32_t maxIntraRefreshActiveReferencePictures; + VkBool32 partitionIndependentIntraRefreshRegions; + VkBool32 nonRectangularIntraRefreshRegions; +} VkVideoEncodeIntraRefreshCapabilitiesKHR; + +typedef struct VkVideoEncodeSessionIntraRefreshCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeIntraRefreshModeFlagBitsKHR intraRefreshMode; +} VkVideoEncodeSessionIntraRefreshCreateInfoKHR; + +typedef struct VkVideoEncodeIntraRefreshInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t intraRefreshCycleDuration; + uint32_t intraRefreshIndex; +} VkVideoEncodeIntraRefreshInfoKHR; + +typedef struct VkVideoReferenceIntraRefreshInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t dirtyIntraRefreshRegions; +} VkVideoReferenceIntraRefreshInfoKHR; + +typedef struct VkPhysicalDeviceVideoEncodeIntraRefreshFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoEncodeIntraRefresh; +} VkPhysicalDeviceVideoEncodeIntraRefreshFeaturesKHR; + + + +// VK_KHR_video_encode_quantization_map is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_quantization_map 1 +#define VK_KHR_VIDEO_ENCODE_QUANTIZATION_MAP_SPEC_VERSION 2 +#define VK_KHR_VIDEO_ENCODE_QUANTIZATION_MAP_EXTENSION_NAME "VK_KHR_video_encode_quantization_map" +typedef struct VkVideoEncodeQuantizationMapCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkExtent2D maxQuantizationMapExtent; +} VkVideoEncodeQuantizationMapCapabilitiesKHR; + +typedef struct VkVideoFormatQuantizationMapPropertiesKHR { + VkStructureType sType; + void* pNext; + VkExtent2D quantizationMapTexelSize; +} VkVideoFormatQuantizationMapPropertiesKHR; + +typedef struct VkVideoEncodeQuantizationMapInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageView quantizationMap; + VkExtent2D quantizationMapExtent; +} VkVideoEncodeQuantizationMapInfoKHR; + +typedef struct VkVideoEncodeQuantizationMapSessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkExtent2D quantizationMapTexelSize; +} VkVideoEncodeQuantizationMapSessionParametersCreateInfoKHR; + +typedef struct VkPhysicalDeviceVideoEncodeQuantizationMapFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoEncodeQuantizationMap; +} VkPhysicalDeviceVideoEncodeQuantizationMapFeaturesKHR; + +typedef struct VkVideoEncodeH264QuantizationMapCapabilitiesKHR { + VkStructureType sType; + void* pNext; + int32_t minQpDelta; + int32_t maxQpDelta; +} VkVideoEncodeH264QuantizationMapCapabilitiesKHR; + +typedef struct VkVideoEncodeH265QuantizationMapCapabilitiesKHR { + VkStructureType sType; + void* pNext; + int32_t minQpDelta; + int32_t maxQpDelta; +} VkVideoEncodeH265QuantizationMapCapabilitiesKHR; + +typedef struct VkVideoFormatH265QuantizationMapPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeH265CtbSizeFlagsKHR compatibleCtbSizes; +} VkVideoFormatH265QuantizationMapPropertiesKHR; + +typedef struct VkVideoEncodeAV1QuantizationMapCapabilitiesKHR { + VkStructureType sType; + void* pNext; + int32_t minQIndexDelta; + int32_t maxQIndexDelta; +} VkVideoEncodeAV1QuantizationMapCapabilitiesKHR; + +typedef struct VkVideoFormatAV1QuantizationMapPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeAV1SuperblockSizeFlagsKHR compatibleSuperblockSizes; +} VkVideoFormatAV1QuantizationMapPropertiesKHR; + + + +// VK_KHR_shader_relaxed_extended_instruction is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_relaxed_extended_instruction 1 +#define VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_SPEC_VERSION 1 +#define VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME "VK_KHR_shader_relaxed_extended_instruction" +typedef struct VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderRelaxedExtendedInstruction; +} VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR; + + + +// VK_KHR_maintenance7 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance7 1 +#define VK_KHR_MAINTENANCE_7_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_7_EXTENSION_NAME "VK_KHR_maintenance7" + +typedef enum VkPhysicalDeviceLayeredApiKHR { + VK_PHYSICAL_DEVICE_LAYERED_API_VULKAN_KHR = 0, + VK_PHYSICAL_DEVICE_LAYERED_API_D3D12_KHR = 1, + VK_PHYSICAL_DEVICE_LAYERED_API_METAL_KHR = 2, + VK_PHYSICAL_DEVICE_LAYERED_API_OPENGL_KHR = 3, + VK_PHYSICAL_DEVICE_LAYERED_API_OPENGLES_KHR = 4, + VK_PHYSICAL_DEVICE_LAYERED_API_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPhysicalDeviceLayeredApiKHR; +typedef struct VkPhysicalDeviceMaintenance7FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance7; +} VkPhysicalDeviceMaintenance7FeaturesKHR; + +typedef struct VkPhysicalDeviceMaintenance7PropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 robustFragmentShadingRateAttachmentAccess; + VkBool32 separateDepthStencilAttachmentAccess; + uint32_t maxDescriptorSetTotalUniformBuffersDynamic; + uint32_t maxDescriptorSetTotalStorageBuffersDynamic; + uint32_t maxDescriptorSetTotalBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindTotalBuffersDynamic; +} VkPhysicalDeviceMaintenance7PropertiesKHR; + +typedef struct VkPhysicalDeviceLayeredApiPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceLayeredApiKHR layeredAPI; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; +} VkPhysicalDeviceLayeredApiPropertiesKHR; + +typedef struct VkPhysicalDeviceLayeredApiPropertiesListKHR { + VkStructureType sType; + void* pNext; + uint32_t layeredApiCount; + VkPhysicalDeviceLayeredApiPropertiesKHR* pLayeredApis; +} VkPhysicalDeviceLayeredApiPropertiesListKHR; + +typedef struct VkPhysicalDeviceLayeredApiVulkanPropertiesKHR { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceProperties2 properties; +} VkPhysicalDeviceLayeredApiVulkanPropertiesKHR; + + + +// VK_KHR_device_fault is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_device_fault 1 +#define VK_KHR_DEVICE_FAULT_SPEC_VERSION 1 +#define VK_KHR_DEVICE_FAULT_EXTENSION_NAME "VK_KHR_device_fault" + +typedef enum VkDeviceFaultAddressTypeKHR { + VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_KHR = 0, + VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_KHR = 1, + VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_KHR = 2, + VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_KHR = 3, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_KHR = 4, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_KHR = 5, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_KHR = 6, + VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_KHR, + VK_DEVICE_FAULT_ADDRESS_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDeviceFaultAddressTypeKHR; + +typedef enum VkDeviceFaultVendorBinaryHeaderVersionKHR { + VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_KHR = 1, + VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT = VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_KHR, + VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDeviceFaultVendorBinaryHeaderVersionKHR; + +typedef enum VkDeviceFaultFlagBitsKHR { + VK_DEVICE_FAULT_FLAG_DEVICE_LOST_KHR = 0x00000001, + VK_DEVICE_FAULT_FLAG_MEMORY_ADDRESS_KHR = 0x00000002, + VK_DEVICE_FAULT_FLAG_INSTRUCTION_ADDRESS_KHR = 0x00000004, + VK_DEVICE_FAULT_FLAG_VENDOR_KHR = 0x00000008, + VK_DEVICE_FAULT_FLAG_WATCHDOG_TIMEOUT_KHR = 0x00000010, + VK_DEVICE_FAULT_FLAG_OVERFLOW_KHR = 0x00000020, + VK_DEVICE_FAULT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDeviceFaultFlagBitsKHR; +typedef VkFlags VkDeviceFaultFlagsKHR; +typedef struct VkPhysicalDeviceFaultFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 deviceFault; + VkBool32 deviceFaultVendorBinary; + VkBool32 deviceFaultReportMasked; + VkBool32 deviceFaultDeviceLostOnMasked; +} VkPhysicalDeviceFaultFeaturesKHR; + +typedef struct VkPhysicalDeviceFaultPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t maxDeviceFaultCount; +} VkPhysicalDeviceFaultPropertiesKHR; + +typedef struct VkDeviceFaultAddressInfoKHR { + VkDeviceFaultAddressTypeKHR addressType; + VkDeviceAddress reportedAddress; + VkDeviceSize addressPrecision; +} VkDeviceFaultAddressInfoKHR; + +typedef struct VkDeviceFaultVendorInfoKHR { + char description[VK_MAX_DESCRIPTION_SIZE]; + uint64_t vendorFaultCode; + uint64_t vendorFaultData; +} VkDeviceFaultVendorInfoKHR; + +typedef struct VkDeviceFaultInfoKHR { + VkStructureType sType; + void* pNext; + VkDeviceFaultFlagsKHR flags; + uint64_t groupId; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkDeviceFaultAddressInfoKHR faultAddressInfo; + VkDeviceFaultAddressInfoKHR instructionAddressInfo; + VkDeviceFaultVendorInfoKHR vendorInfo; +} VkDeviceFaultInfoKHR; + +typedef struct VkDeviceFaultDebugInfoKHR { + VkStructureType sType; + void* pNext; + uint32_t vendorBinarySize; + void* pVendorBinaryData; +} VkDeviceFaultDebugInfoKHR; + +typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneKHR { + uint32_t headerSize; + VkDeviceFaultVendorBinaryHeaderVersionKHR headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint32_t driverVersion; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + uint32_t applicationNameOffset; + uint32_t applicationVersion; + uint32_t engineNameOffset; + uint32_t engineVersion; + uint32_t apiVersion; +} VkDeviceFaultVendorBinaryHeaderVersionOneKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultReportsKHR)(VkDevice device, uint64_t timeout, uint32_t* pFaultCounts, VkDeviceFaultInfoKHR* pFaultInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultDebugInfoKHR)(VkDevice device, VkDeviceFaultDebugInfoKHR* pDebugInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultReportsKHR( + VkDevice device, + uint64_t timeout, + uint32_t* pFaultCounts, + VkDeviceFaultInfoKHR* pFaultInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultDebugInfoKHR( + VkDevice device, + VkDeviceFaultDebugInfoKHR* pDebugInfo); +#endif +#endif + + +// VK_KHR_maintenance8 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance8 1 +#define VK_KHR_MAINTENANCE_8_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_8_EXTENSION_NAME "VK_KHR_maintenance8" +typedef VkFlags64 VkAccessFlags3KHR; + +// Flag bits for VkAccessFlagBits3KHR +typedef VkFlags64 VkAccessFlagBits3KHR; +static const VkAccessFlagBits3KHR VK_ACCESS_3_NONE_KHR = 0ULL; + +typedef struct VkMemoryBarrierAccessFlags3KHR { + VkStructureType sType; + const void* pNext; + VkAccessFlags3KHR srcAccessMask3; + VkAccessFlags3KHR dstAccessMask3; +} VkMemoryBarrierAccessFlags3KHR; + +typedef struct VkPhysicalDeviceMaintenance8FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance8; +} VkPhysicalDeviceMaintenance8FeaturesKHR; + + + +// VK_KHR_shader_fma is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_fma 1 +#define VK_KHR_SHADER_FMA_SPEC_VERSION 1 +#define VK_KHR_SHADER_FMA_EXTENSION_NAME "VK_KHR_shader_fma" +typedef struct VkPhysicalDeviceShaderFmaFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderFmaFloat16; + VkBool32 shaderFmaFloat32; + VkBool32 shaderFmaFloat64; +} VkPhysicalDeviceShaderFmaFeaturesKHR; + + + +// VK_KHR_maintenance9 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance9 1 +#define VK_KHR_MAINTENANCE_9_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_9_EXTENSION_NAME "VK_KHR_maintenance9" + +typedef enum VkDefaultVertexAttributeValueKHR { + VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_ZERO_ZERO_ZERO_ZERO_KHR = 0, + VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_ZERO_ZERO_ZERO_ONE_KHR = 1, + VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDefaultVertexAttributeValueKHR; +typedef struct VkPhysicalDeviceMaintenance9FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance9; +} VkPhysicalDeviceMaintenance9FeaturesKHR; + +typedef struct VkPhysicalDeviceMaintenance9PropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 image2DViewOf3DSparse; + VkDefaultVertexAttributeValueKHR defaultVertexAttributeValue; +} VkPhysicalDeviceMaintenance9PropertiesKHR; + +typedef struct VkQueueFamilyOwnershipTransferPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t optimalImageTransferToQueueFamilies; +} VkQueueFamilyOwnershipTransferPropertiesKHR; + + + +// VK_KHR_video_maintenance2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_maintenance2 1 +#define VK_KHR_VIDEO_MAINTENANCE_2_SPEC_VERSION 1 +#define VK_KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_video_maintenance2" +typedef struct VkPhysicalDeviceVideoMaintenance2FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoMaintenance2; +} VkPhysicalDeviceVideoMaintenance2FeaturesKHR; + +typedef struct VkVideoDecodeH264InlineSessionParametersInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoH264SequenceParameterSet* pStdSPS; + const StdVideoH264PictureParameterSet* pStdPPS; +} VkVideoDecodeH264InlineSessionParametersInfoKHR; + +typedef struct VkVideoDecodeH265InlineSessionParametersInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoH265VideoParameterSet* pStdVPS; + const StdVideoH265SequenceParameterSet* pStdSPS; + const StdVideoH265PictureParameterSet* pStdPPS; +} VkVideoDecodeH265InlineSessionParametersInfoKHR; + +typedef struct VkVideoDecodeAV1InlineSessionParametersInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoAV1SequenceHeader* pStdSequenceHeader; +} VkVideoDecodeAV1InlineSessionParametersInfoKHR; + + + +// VK_KHR_depth_clamp_zero_one is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_depth_clamp_zero_one 1 +#define VK_KHR_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION 1 +#define VK_KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME "VK_KHR_depth_clamp_zero_one" +typedef struct VkPhysicalDeviceDepthClampZeroOneFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 depthClampZeroOne; +} VkPhysicalDeviceDepthClampZeroOneFeaturesKHR; + + + +// VK_KHR_robustness2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_robustness2 1 +#define VK_KHR_ROBUSTNESS_2_SPEC_VERSION 1 +#define VK_KHR_ROBUSTNESS_2_EXTENSION_NAME "VK_KHR_robustness2" +typedef struct VkPhysicalDeviceRobustness2FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 robustBufferAccess2; + VkBool32 robustImageAccess2; + VkBool32 nullDescriptor; +} VkPhysicalDeviceRobustness2FeaturesKHR; + +typedef struct VkPhysicalDeviceRobustness2PropertiesKHR { + VkStructureType sType; + void* pNext; + VkDeviceSize robustStorageBufferAccessSizeAlignment; + VkDeviceSize robustUniformBufferAccessSizeAlignment; +} VkPhysicalDeviceRobustness2PropertiesKHR; + + + +// VK_KHR_present_mode_fifo_latest_ready is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_present_mode_fifo_latest_ready 1 +#define VK_KHR_PRESENT_MODE_FIFO_LATEST_READY_SPEC_VERSION 1 +#define VK_KHR_PRESENT_MODE_FIFO_LATEST_READY_EXTENSION_NAME "VK_KHR_present_mode_fifo_latest_ready" +typedef struct VkPhysicalDevicePresentModeFifoLatestReadyFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentModeFifoLatestReady; +} VkPhysicalDevicePresentModeFifoLatestReadyFeaturesKHR; + + + +// VK_KHR_opacity_micromap is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_opacity_micromap 1 +#define VK_KHR_OPACITY_MICROMAP_SPEC_VERSION 1 +#define VK_KHR_OPACITY_MICROMAP_EXTENSION_NAME "VK_KHR_opacity_micromap" + +typedef enum VkOpacityMicromapFormatKHR { + VK_OPACITY_MICROMAP_FORMAT_2_STATE_KHR = 1, + VK_OPACITY_MICROMAP_FORMAT_4_STATE_KHR = 2, + VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT = VK_OPACITY_MICROMAP_FORMAT_2_STATE_KHR, + VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT = VK_OPACITY_MICROMAP_FORMAT_4_STATE_KHR, + VK_OPACITY_MICROMAP_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkOpacityMicromapFormatKHR; + +typedef enum VkOpacityMicromapSpecialIndexKHR { + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_KHR = -1, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_KHR = -2, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_KHR = -3, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_KHR = -4, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_CLUSTER_GEOMETRY_DISABLE_OPACITY_MICROMAP_NV = -5, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT = VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_KHR, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT = VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_KHR, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT = VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_KHR, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT = VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_KHR, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_MAX_ENUM_KHR = 0x7FFFFFFF +} VkOpacityMicromapSpecialIndexKHR; + +typedef enum VkAccelerationStructureSerializedBlockTypeKHR { + VK_ACCELERATION_STRUCTURE_SERIALIZED_BLOCK_TYPE_OPACITY_MICROMAP_KHR = 0, + VK_ACCELERATION_STRUCTURE_SERIALIZED_BLOCK_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureSerializedBlockTypeKHR; +typedef struct VkMicromapUsageKHR { + uint32_t count; + uint32_t subdivisionLevel; + VkOpacityMicromapFormatKHR format; +} VkMicromapUsageKHR; + +typedef struct VkAccelerationStructureGeometryMicromapDataKHR { + VkStructureType sType; + const void* pNext; + uint32_t usageCountsCount; + const VkMicromapUsageKHR* pUsageCounts; + const VkMicromapUsageKHR* const* ppUsageCounts; + VkDeviceAddress data; + VkDeviceAddress triangleArray; + VkDeviceSize triangleArrayStride; +} VkAccelerationStructureGeometryMicromapDataKHR; + +typedef struct VkPhysicalDeviceOpacityMicromapFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 micromap; +} VkPhysicalDeviceOpacityMicromapFeaturesKHR; + +typedef struct VkPhysicalDeviceOpacityMicromapPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t maxOpacity2StateSubdivisionLevel; + uint32_t maxOpacity4StateSubdivisionLevel; + uint32_t maxOpacityLossy4StateSubdivisionLevel; + uint64_t maxMicromapTriangles; +} VkPhysicalDeviceOpacityMicromapPropertiesKHR; + +typedef struct VkMicromapTriangleKHR { + uint32_t dataOffset; + uint16_t subdivisionLevel; + uint16_t format; +} VkMicromapTriangleKHR; + +typedef struct VkAccelerationStructureTrianglesOpacityMicromapKHR { + VkStructureType sType; + void* pNext; + VkIndexType indexType; + VkDeviceAddress indexBuffer; + VkDeviceSize indexStride; + uint32_t baseTriangle; + VkAccelerationStructureKHR micromap; +} VkAccelerationStructureTrianglesOpacityMicromapKHR; + + + +// VK_KHR_maintenance10 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance10 1 +#define VK_KHR_MAINTENANCE_10_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_10_EXTENSION_NAME "VK_KHR_maintenance10" + +typedef enum VkRenderingAttachmentFlagBitsKHR { + VK_RENDERING_ATTACHMENT_INPUT_ATTACHMENT_FEEDBACK_BIT_KHR = 0x00000001, + VK_RENDERING_ATTACHMENT_RESOLVE_SKIP_TRANSFER_FUNCTION_BIT_KHR = 0x00000002, + VK_RENDERING_ATTACHMENT_RESOLVE_ENABLE_TRANSFER_FUNCTION_BIT_KHR = 0x00000004, + VK_RENDERING_ATTACHMENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkRenderingAttachmentFlagBitsKHR; +typedef VkFlags VkRenderingAttachmentFlagsKHR; + +typedef enum VkResolveImageFlagBitsKHR { + VK_RESOLVE_IMAGE_SKIP_TRANSFER_FUNCTION_BIT_KHR = 0x00000001, + VK_RESOLVE_IMAGE_ENABLE_TRANSFER_FUNCTION_BIT_KHR = 0x00000002, + VK_RESOLVE_IMAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkResolveImageFlagBitsKHR; +typedef VkFlags VkResolveImageFlagsKHR; +typedef struct VkPhysicalDeviceMaintenance10FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance10; +} VkPhysicalDeviceMaintenance10FeaturesKHR; + +typedef struct VkPhysicalDeviceMaintenance10PropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rgba4OpaqueBlackSwizzled; + VkBool32 resolveSrgbFormatAppliesTransferFunction; + VkBool32 resolveSrgbFormatSupportsTransferFunctionControl; +} VkPhysicalDeviceMaintenance10PropertiesKHR; + +typedef struct VkRenderingEndInfoKHR { + VkStructureType sType; + const void* pNext; +} VkRenderingEndInfoKHR; + +typedef struct VkRenderingAttachmentFlagsInfoKHR { + VkStructureType sType; + const void* pNext; + VkRenderingAttachmentFlagsKHR flags; +} VkRenderingAttachmentFlagsInfoKHR; + +typedef struct VkResolveImageModeInfoKHR { + VkStructureType sType; + const void* pNext; + VkResolveImageFlagsKHR flags; + VkResolveModeFlagBits resolveMode; + VkResolveModeFlagBits stencilResolveMode; +} VkResolveImageModeInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering2KHR)(VkCommandBuffer commandBuffer, const VkRenderingEndInfoKHR* pRenderingEndInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering2KHR( + VkCommandBuffer commandBuffer, + const VkRenderingEndInfoKHR* pRenderingEndInfo); +#endif +#endif + + +// VK_KHR_maintenance11 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance11 1 +#define VK_KHR_MAINTENANCE_11_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_11_EXTENSION_NAME "VK_KHR_maintenance11" +typedef struct VkPhysicalDeviceMaintenance11FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance11; +} VkPhysicalDeviceMaintenance11FeaturesKHR; + +typedef struct VkQueueFamilyOptimalImageTransferGranularityPropertiesKHR { + VkStructureType sType; + void* pNext; + VkExtent3D optimalImageTransferGranularity; +} VkQueueFamilyOptimalImageTransferGranularityPropertiesKHR; + // VK_EXT_debug_report is a preprocessor guard. Do not pass it to API calls. @@ -11748,7 +14823,9 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT = 1000307000, VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT = 1000307001, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000, + // VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT is a legacy alias VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, + // VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT is a legacy alias VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, @@ -11787,17 +14864,22 @@ typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instanc 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 +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( VkInstance instance, VkDebugReportFlagsEXT flags, @@ -11808,6 +14890,7 @@ VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( const char* pLayerPrefix, const char* pMessage); #endif +#endif // VK_NV_glsl_shader is a preprocessor guard. Do not pass it to API calls. @@ -11894,25 +14977,35 @@ typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuff typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( VkCommandBuffer commandBuffer); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); #endif +#endif // VK_AMD_gcn_shader is a preprocessor guard. Do not pass it to API calls. @@ -11988,6 +15081,7 @@ typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuf typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT( VkCommandBuffer commandBuffer, uint32_t firstBinding, @@ -11995,34 +15089,44 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT( const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT( VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT( VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( VkCommandBuffer commandBuffer, uint32_t instanceCount, @@ -12032,13 +15136,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( uint32_t counterOffset, uint32_t vertexStride); #endif +#endif // VK_NVX_binary_import is a preprocessor guard. Do not pass it to API calls. #define VK_NVX_binary_import 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX) -#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 1 +#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 2 #define VK_NVX_BINARY_IMPORT_EXTENSION_NAME "VK_NVX_binary_import" typedef struct VkCuModuleCreateInfoNVX { VkStructureType sType; @@ -12047,6 +15152,12 @@ typedef struct VkCuModuleCreateInfoNVX { const void* pData; } VkCuModuleCreateInfoNVX; +typedef struct VkCuModuleTexturingModeCreateInfoNVX { + VkStructureType sType; + const void* pNext; + VkBool32 use64bitTexturing; +} VkCuModuleTexturingModeCreateInfoNVX; + typedef struct VkCuFunctionCreateInfoNVX { VkStructureType sType; const void* pNext; @@ -12078,37 +15189,47 @@ typedef void (VKAPI_PTR *PFN_vkDestroyCuFunctionNVX)(VkDevice device, VkCuFuncti typedef void (VKAPI_PTR *PFN_vkCmdCuLaunchKernelNVX)(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuModuleNVX( VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuFunctionNVX( VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyCuModuleNVX( VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyCuFunctionNVX( VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCuLaunchKernelNVX( VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo); #endif +#endif // VK_NVX_image_view_handle is a preprocessor guard. Do not pass it to API calls. #define VK_NVX_image_view_handle 1 -#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2 +#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 4 #define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle" typedef struct VkImageViewHandleInfoNVX { VkStructureType sType; @@ -12126,19 +15247,38 @@ typedef struct VkImageViewAddressPropertiesNVX { } VkImageViewAddressPropertiesNVX; typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetImageViewHandle64NVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceCombinedImageSamplerIndexNVX)(VkDevice device, uint64_t imageViewIndex, uint64_t samplerIndex); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX( VkDevice device, const VkImageViewHandleInfoNVX* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR uint64_t VKAPI_CALL vkGetImageViewHandle64NVX( + VkDevice device, + const VkImageViewHandleInfoNVX* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX( VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); #endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceCombinedImageSamplerIndexNVX( + VkDevice device, + uint64_t imageViewIndex, + uint64_t samplerIndex); +#endif +#endif + // VK_AMD_draw_indirect_count is a preprocessor guard. Do not pass it to API calls. #define VK_AMD_draw_indirect_count 1 @@ -12148,6 +15288,7 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandB typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -12156,7 +15297,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -12166,6 +15309,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( uint32_t maxDrawCount, uint32_t stride); #endif +#endif // VK_AMD_negative_viewport_height is a preprocessor guard. Do not pass it to API calls. @@ -12230,6 +15374,7 @@ typedef struct VkShaderStatisticsInfoAMD { typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( VkDevice device, VkPipeline pipeline, @@ -12238,6 +15383,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( size_t* pInfoSize, void* pInfo); #endif +#endif // VK_AMD_shader_image_load_store_lod is a preprocessor guard. Do not pass it to API calls. @@ -12295,6 +15441,7 @@ typedef struct VkExternalImageFormatPropertiesNV { typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV( VkPhysicalDevice physicalDevice, VkFormat format, @@ -12305,6 +15452,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesN VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); #endif +#endif // VK_NV_external_memory is a preprocessor guard. Do not pass it to API calls. @@ -12386,45 +15534,15 @@ typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { #define VK_EXT_pipeline_robustness 1 #define VK_EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION 1 #define VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_pipeline_robustness" +typedef VkPipelineRobustnessBufferBehavior VkPipelineRobustnessBufferBehaviorEXT; -typedef enum VkPipelineRobustnessBufferBehaviorEXT { - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = 1, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = 2, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = 3, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineRobustnessBufferBehaviorEXT; +typedef VkPipelineRobustnessImageBehavior VkPipelineRobustnessImageBehaviorEXT; -typedef enum VkPipelineRobustnessImageBehaviorEXT { - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = 1, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = 2, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = 3, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineRobustnessImageBehaviorEXT; -typedef struct VkPhysicalDevicePipelineRobustnessFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelineRobustness; -} VkPhysicalDevicePipelineRobustnessFeaturesEXT; +typedef VkPhysicalDevicePipelineRobustnessFeatures VkPhysicalDevicePipelineRobustnessFeaturesEXT; -typedef struct VkPhysicalDevicePipelineRobustnessPropertiesEXT { - VkStructureType sType; - void* pNext; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessStorageBuffers; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessUniformBuffers; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessVertexInputs; - VkPipelineRobustnessImageBehaviorEXT defaultRobustnessImages; -} VkPhysicalDevicePipelineRobustnessPropertiesEXT; +typedef VkPhysicalDevicePipelineRobustnessProperties VkPhysicalDevicePipelineRobustnessPropertiesEXT; -typedef struct VkPipelineRobustnessCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineRobustnessBufferBehaviorEXT storageBuffers; - VkPipelineRobustnessBufferBehaviorEXT uniformBuffers; - VkPipelineRobustnessBufferBehaviorEXT vertexInputs; - VkPipelineRobustnessImageBehaviorEXT images; -} VkPipelineRobustnessCreateInfoEXT; +typedef VkPipelineRobustnessCreateInfo VkPipelineRobustnessCreateInfoEXT; @@ -12432,12 +15550,6 @@ typedef struct VkPipelineRobustnessCreateInfoEXT { #define VK_EXT_conditional_rendering 1 #define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2 #define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" - -typedef enum VkConditionalRenderingFlagBitsEXT { - VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, - VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkConditionalRenderingFlagBitsEXT; -typedef VkFlags VkConditionalRenderingFlagsEXT; typedef struct VkConditionalRenderingBeginInfoEXT { VkStructureType sType; const void* pNext; @@ -12463,13 +15575,17 @@ typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT( VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( VkCommandBuffer commandBuffer); #endif +#endif // VK_NV_clip_space_w_scaling is a preprocessor guard. Do not pass it to API calls. @@ -12492,12 +15608,14 @@ typedef struct VkPipelineViewportWScalingStateCreateInfoNV { typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); #endif +#endif // VK_EXT_direct_mode_display is a preprocessor guard. Do not pass it to API calls. @@ -12507,10 +15625,12 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( VkPhysicalDevice physicalDevice, VkDisplayKHR display); #endif +#endif // VK_EXT_display_surface_counter is a preprocessor guard. Do not pass it to API calls. @@ -12520,6 +15640,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( typedef enum VkSurfaceCounterFlagBitsEXT { VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001, + // VK_SURFACE_COUNTER_VBLANK_EXT is a legacy alias VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT, VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkSurfaceCounterFlagBitsEXT; @@ -12543,11 +15664,13 @@ typedef struct VkSurfaceCapabilities2EXT { typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); #endif +#endif // VK_EXT_display_control is a preprocessor guard. Do not pass it to API calls. @@ -12601,30 +15724,38 @@ typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkD typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT( VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT( VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT( VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT( VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); #endif +#endif // VK_GOOGLE_display_timing is a preprocessor guard. Do not pass it to API calls. @@ -12659,17 +15790,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice devic typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); #endif +#endif // VK_NV_sample_mask_override_coverage is a preprocessor guard. Do not pass it to API calls. @@ -12688,7 +15823,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( #define VK_NV_viewport_array2 1 #define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1 #define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2" +// VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION is a legacy alias #define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION +// VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME is a legacy alias #define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME @@ -12702,6 +15839,13 @@ typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX { VkBool32 perViewPositionAllComponents; } VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX; +typedef struct VkMultiviewPerViewAttributesInfoNVX { + VkStructureType sType; + const void* pNext; + VkBool32 perViewAttributes; + VkBool32 perViewAttributesPositionXOnly; +} VkMultiviewPerViewAttributesInfoNVX; + // VK_NV_viewport_swizzle is a preprocessor guard. Do not pass it to API calls. @@ -12769,20 +15913,26 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEnableEXT)(VkCommandBuffer typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleModeEXT)(VkCommandBuffer commandBuffer, VkDiscardRectangleModeEXT discardRectangleMode); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEnableEXT( VkCommandBuffer commandBuffer, VkBool32 discardRectangleEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleModeEXT( VkCommandBuffer commandBuffer, VkDiscardRectangleModeEXT discardRectangleMode); #endif +#endif // VK_EXT_conservative_rasterization is a preprocessor guard. Do not pass it to API calls. @@ -12843,13 +15993,13 @@ typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT { // VK_EXT_swapchain_colorspace is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_swapchain_colorspace 1 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 4 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 5 #define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" // VK_EXT_hdr_metadata is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_hdr_metadata 1 -#define VK_EXT_HDR_METADATA_SPEC_VERSION 2 +#define VK_EXT_HDR_METADATA_SPEC_VERSION 3 #define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" typedef struct VkXYColorEXT { float x; @@ -12872,12 +16022,14 @@ typedef struct VkHdrMetadataEXT { typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); #endif +#endif // VK_IMG_relaxed_line_rasterization is a preprocessor guard. Do not pass it to API calls. @@ -12961,10 +16113,10 @@ typedef struct VkDebugUtilsMessengerCallbackDataEXT { } VkDebugUtilsMessengerCallbackDataEXT; typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( - VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void* pUserData); + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData); typedef struct VkDebugUtilsMessengerCreateInfoEXT { VkStructureType sType; @@ -12999,53 +16151,75 @@ typedef void (VKAPI_PTR *PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instanc typedef void (VKAPI_PTR *PFN_vkSubmitDebugUtilsMessageEXT)(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectNameEXT( VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectTagEXT( VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkQueueBeginDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkQueueEndDebugUtilsLabelEXT( VkQueue queue); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkQueueInsertDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdEndDebugUtilsLabelEXT( VkCommandBuffer commandBuffer); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdInsertDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT( VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); #endif +#endif // VK_EXT_sampler_filter_minmax is a preprocessor guard. Do not pass it to API calls. @@ -13066,10 +16240,668 @@ typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFil #define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" +// VK_AMD_gpa_interface is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_gpa_interface 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkGpaSessionAMD) +#define VK_AMD_GPA_INTERFACE_SPEC_VERSION 1 +#define VK_AMD_GPA_INTERFACE_EXTENSION_NAME "VK_AMD_gpa_interface" + +typedef enum VkGpaPerfBlockAMD { + VK_GPA_PERF_BLOCK_CPF_AMD = 0, + VK_GPA_PERF_BLOCK_IA_AMD = 1, + VK_GPA_PERF_BLOCK_VGT_AMD = 2, + VK_GPA_PERF_BLOCK_PA_AMD = 3, + VK_GPA_PERF_BLOCK_SC_AMD = 4, + VK_GPA_PERF_BLOCK_SPI_AMD = 5, + VK_GPA_PERF_BLOCK_SQ_AMD = 6, + VK_GPA_PERF_BLOCK_SX_AMD = 7, + VK_GPA_PERF_BLOCK_TA_AMD = 8, + VK_GPA_PERF_BLOCK_TD_AMD = 9, + VK_GPA_PERF_BLOCK_TCP_AMD = 10, + VK_GPA_PERF_BLOCK_TCC_AMD = 11, + VK_GPA_PERF_BLOCK_TCA_AMD = 12, + VK_GPA_PERF_BLOCK_DB_AMD = 13, + VK_GPA_PERF_BLOCK_CB_AMD = 14, + VK_GPA_PERF_BLOCK_GDS_AMD = 15, + VK_GPA_PERF_BLOCK_SRBM_AMD = 16, + VK_GPA_PERF_BLOCK_GRBM_AMD = 17, + VK_GPA_PERF_BLOCK_GRBM_SE_AMD = 18, + VK_GPA_PERF_BLOCK_RLC_AMD = 19, + VK_GPA_PERF_BLOCK_DMA_AMD = 20, + VK_GPA_PERF_BLOCK_MC_AMD = 21, + VK_GPA_PERF_BLOCK_CPG_AMD = 22, + VK_GPA_PERF_BLOCK_CPC_AMD = 23, + VK_GPA_PERF_BLOCK_WD_AMD = 24, + VK_GPA_PERF_BLOCK_TCS_AMD = 25, + VK_GPA_PERF_BLOCK_ATC_AMD = 26, + VK_GPA_PERF_BLOCK_ATC_L2_AMD = 27, + VK_GPA_PERF_BLOCK_MC_VM_L2_AMD = 28, + VK_GPA_PERF_BLOCK_EA_AMD = 29, + VK_GPA_PERF_BLOCK_RPB_AMD = 30, + VK_GPA_PERF_BLOCK_RMI_AMD = 31, + VK_GPA_PERF_BLOCK_UMCCH_AMD = 32, + VK_GPA_PERF_BLOCK_GE_AMD = 33, + VK_GPA_PERF_BLOCK_GL1A_AMD = 34, + VK_GPA_PERF_BLOCK_GL1C_AMD = 35, + VK_GPA_PERF_BLOCK_GL1CG_AMD = 36, + VK_GPA_PERF_BLOCK_GL2A_AMD = 37, + VK_GPA_PERF_BLOCK_GL2C_AMD = 38, + VK_GPA_PERF_BLOCK_CHA_AMD = 39, + VK_GPA_PERF_BLOCK_CHC_AMD = 40, + VK_GPA_PERF_BLOCK_CHCG_AMD = 41, + VK_GPA_PERF_BLOCK_GUS_AMD = 42, + VK_GPA_PERF_BLOCK_GCR_AMD = 43, + VK_GPA_PERF_BLOCK_PH_AMD = 44, + VK_GPA_PERF_BLOCK_UTCL1_AMD = 45, + VK_GPA_PERF_BLOCK_GE_DIST_AMD = 46, + VK_GPA_PERF_BLOCK_GE_SE_AMD = 47, + VK_GPA_PERF_BLOCK_DF_MALL_AMD = 48, + VK_GPA_PERF_BLOCK_SQ_WGP_AMD = 49, + VK_GPA_PERF_BLOCK_PC_AMD = 50, + VK_GPA_PERF_BLOCK_GL1XA_AMD = 51, + VK_GPA_PERF_BLOCK_GL1XC_AMD = 52, + VK_GPA_PERF_BLOCK_WGS_AMD = 53, + VK_GPA_PERF_BLOCK_EACPWD_AMD = 54, + VK_GPA_PERF_BLOCK_EASE_AMD = 55, + VK_GPA_PERF_BLOCK_RLCUSER_AMD = 56, + VK_GPA_PERF_BLOCK_GE1_AMD = VK_GPA_PERF_BLOCK_GE_AMD, + VK_GPA_PERF_BLOCK_RLCLOCAL_AMD = VK_GPA_PERF_BLOCK_RLCUSER_AMD, + VK_GPA_PERF_BLOCK_MAX_ENUM_AMD = 0x7FFFFFFF +} VkGpaPerfBlockAMD; + +typedef enum VkGpaSampleTypeAMD { + VK_GPA_SAMPLE_TYPE_CUMULATIVE_AMD = 0, + VK_GPA_SAMPLE_TYPE_TRACE_AMD = 1, + VK_GPA_SAMPLE_TYPE_TIMING_AMD = 2, + VK_GPA_SAMPLE_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkGpaSampleTypeAMD; + +typedef enum VkGpaDeviceClockModeAMD { + VK_GPA_DEVICE_CLOCK_MODE_DEFAULT_AMD = 0, + VK_GPA_DEVICE_CLOCK_MODE_QUERY_AMD = 1, + VK_GPA_DEVICE_CLOCK_MODE_PROFILING_AMD = 2, + VK_GPA_DEVICE_CLOCK_MODE_MIN_MEMORY_AMD = 3, + VK_GPA_DEVICE_CLOCK_MODE_MIN_ENGINE_AMD = 4, + VK_GPA_DEVICE_CLOCK_MODE_PEAK_AMD = 5, + VK_GPA_DEVICE_CLOCK_MODE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkGpaDeviceClockModeAMD; + +typedef enum VkGpaSqShaderStageFlagBitsAMD { + VK_GPA_SQ_SHADER_STAGE_PS_BIT_AMD = 0x00000001, + VK_GPA_SQ_SHADER_STAGE_VS_BIT_AMD = 0x00000002, + VK_GPA_SQ_SHADER_STAGE_GS_BIT_AMD = 0x00000004, + VK_GPA_SQ_SHADER_STAGE_ES_BIT_AMD = 0x00000008, + VK_GPA_SQ_SHADER_STAGE_HS_BIT_AMD = 0x00000010, + VK_GPA_SQ_SHADER_STAGE_LS_BIT_AMD = 0x00000020, + VK_GPA_SQ_SHADER_STAGE_CS_BIT_AMD = 0x00000040, + VK_GPA_SQ_SHADER_STAGE_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF +} VkGpaSqShaderStageFlagBitsAMD; +typedef VkFlags VkGpaSqShaderStageFlagsAMD; +typedef VkFlags VkGpaPerfBlockPropertiesFlagsAMD; +typedef VkFlags VkPhysicalDeviceGpaPropertiesFlagsAMD; +typedef struct VkGpaPerfBlockPropertiesAMD { + VkGpaPerfBlockAMD blockType; + VkGpaPerfBlockPropertiesFlagsAMD flags; + uint32_t instanceCount; + uint32_t maxEventID; + uint32_t maxGlobalOnlyCounters; + uint32_t maxGlobalSharedCounters; + uint32_t maxStreamingCounters; +} VkGpaPerfBlockPropertiesAMD; + +typedef struct VkPhysicalDeviceGpaFeaturesAMD { + VkStructureType sType; + void* pNext; + VkBool32 perfCounters; + VkBool32 streamingPerfCounters; + VkBool32 sqThreadTracing; + VkBool32 clockModes; +} VkPhysicalDeviceGpaFeaturesAMD; + +typedef struct VkPhysicalDeviceGpaPropertiesAMD { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceGpaPropertiesFlagsAMD flags; + VkDeviceSize maxSqttSeBufferSize; + uint32_t shaderEngineCount; + uint32_t perfBlockCount; + VkGpaPerfBlockPropertiesAMD* pPerfBlocks; +} VkPhysicalDeviceGpaPropertiesAMD; + +typedef struct VkPhysicalDeviceGpaProperties2AMD { + VkStructureType sType; + void* pNext; + uint32_t revisionId; +} VkPhysicalDeviceGpaProperties2AMD; + +typedef struct VkGpaPerfCounterAMD { + VkGpaPerfBlockAMD blockType; + uint32_t blockInstance; + uint32_t eventID; +} VkGpaPerfCounterAMD; + +typedef struct VkGpaSampleBeginInfoAMD { + VkStructureType sType; + const void* pNext; + VkGpaSampleTypeAMD sampleType; + VkBool32 sampleInternalOperations; + VkBool32 cacheFlushOnCounterCollection; + VkBool32 sqShaderMaskEnable; + VkGpaSqShaderStageFlagsAMD sqShaderMask; + uint32_t perfCounterCount; + const VkGpaPerfCounterAMD* pPerfCounters; + uint32_t streamingPerfTraceSampleInterval; + VkDeviceSize perfCounterDeviceMemoryLimit; + VkBool32 sqThreadTraceEnable; + VkBool32 sqThreadTraceSuppressInstructionTokens; + VkDeviceSize sqThreadTraceDeviceMemoryLimit; + VkPipelineStageFlags timingPreSample; + VkPipelineStageFlags timingPostSample; +} VkGpaSampleBeginInfoAMD; + +typedef struct VkGpaDeviceClockModeInfoAMD { + VkStructureType sType; + const void* pNext; + VkGpaDeviceClockModeAMD clockMode; + float memoryClockRatioToPeak; + float engineClockRatioToPeak; +} VkGpaDeviceClockModeInfoAMD; + +typedef struct VkGpaDeviceGetClockInfoAMD { + VkStructureType sType; + void* pNext; + float memoryClockRatioToPeak; + float engineClockRatioToPeak; + uint32_t memoryClockFrequency; + uint32_t engineClockFrequency; +} VkGpaDeviceGetClockInfoAMD; + +typedef struct VkGpaSessionCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkGpaSessionAMD secondaryCopySource; +} VkGpaSessionCreateInfoAMD; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateGpaSessionAMD)(VkDevice device, const VkGpaSessionCreateInfoAMD* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkGpaSessionAMD* pGpaSession); +typedef void (VKAPI_PTR *PFN_vkDestroyGpaSessionAMD)(VkDevice device, VkGpaSessionAMD gpaSession, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetGpaDeviceClockModeAMD)(VkDevice device, VkGpaDeviceClockModeInfoAMD* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetGpaDeviceClockInfoAMD)(VkDevice device, VkGpaDeviceGetClockInfoAMD* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCmdBeginGpaSessionAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession); +typedef VkResult (VKAPI_PTR *PFN_vkCmdEndGpaSessionAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession); +typedef VkResult (VKAPI_PTR *PFN_vkCmdBeginGpaSampleAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession, const VkGpaSampleBeginInfoAMD* pGpaSampleBeginInfo, uint32_t* pSampleID); +typedef void (VKAPI_PTR *PFN_vkCmdEndGpaSampleAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession, uint32_t sampleID); +typedef VkResult (VKAPI_PTR *PFN_vkGetGpaSessionStatusAMD)(VkDevice device, VkGpaSessionAMD gpaSession); +typedef VkResult (VKAPI_PTR *PFN_vkGetGpaSessionResultsAMD)(VkDevice device, VkGpaSessionAMD gpaSession, uint32_t sampleID, size_t* pSizeInBytes, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkResetGpaSessionAMD)(VkDevice device, VkGpaSessionAMD gpaSession); +typedef void (VKAPI_PTR *PFN_vkCmdCopyGpaSessionResultsAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateGpaSessionAMD( + VkDevice device, + const VkGpaSessionCreateInfoAMD* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkGpaSessionAMD* pGpaSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyGpaSessionAMD( + VkDevice device, + VkGpaSessionAMD gpaSession, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkSetGpaDeviceClockModeAMD( + VkDevice device, + VkGpaDeviceClockModeInfoAMD* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetGpaDeviceClockInfoAMD( + VkDevice device, + VkGpaDeviceGetClockInfoAMD* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCmdBeginGpaSessionAMD( + VkCommandBuffer commandBuffer, + VkGpaSessionAMD gpaSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCmdEndGpaSessionAMD( + VkCommandBuffer commandBuffer, + VkGpaSessionAMD gpaSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCmdBeginGpaSampleAMD( + VkCommandBuffer commandBuffer, + VkGpaSessionAMD gpaSession, + const VkGpaSampleBeginInfoAMD* pGpaSampleBeginInfo, + uint32_t* pSampleID); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndGpaSampleAMD( + VkCommandBuffer commandBuffer, + VkGpaSessionAMD gpaSession, + uint32_t sampleID); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetGpaSessionStatusAMD( + VkDevice device, + VkGpaSessionAMD gpaSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetGpaSessionResultsAMD( + VkDevice device, + VkGpaSessionAMD gpaSession, + uint32_t sampleID, + size_t* pSizeInBytes, + void* pData); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkResetGpaSessionAMD( + VkDevice device, + VkGpaSessionAMD gpaSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyGpaSessionResultsAMD( + VkCommandBuffer commandBuffer, + VkGpaSessionAMD gpaSession); +#endif +#endif + + +// VK_EXT_descriptor_heap is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_descriptor_heap 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkTensorARM) +#define VK_EXT_DESCRIPTOR_HEAP_SPEC_VERSION 1 +#define VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME "VK_EXT_descriptor_heap" + +typedef enum VkDescriptorMappingSourceEXT { + VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT = 0, + VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_PUSH_INDEX_EXT = 1, + VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_EXT = 2, + VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_ARRAY_EXT = 3, + VK_DESCRIPTOR_MAPPING_SOURCE_RESOURCE_HEAP_DATA_EXT = 4, + VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_DATA_EXT = 5, + VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_ADDRESS_EXT = 6, + VK_DESCRIPTOR_MAPPING_SOURCE_INDIRECT_ADDRESS_EXT = 7, + VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_SHADER_RECORD_INDEX_EXT = 8, + VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_DATA_EXT = 9, + VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_ADDRESS_EXT = 10, + VK_DESCRIPTOR_MAPPING_SOURCE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDescriptorMappingSourceEXT; +typedef VkFlags64 VkTensorViewCreateFlagsARM; + +// Flag bits for VkTensorViewCreateFlagBitsARM +typedef VkFlags64 VkTensorViewCreateFlagBitsARM; +static const VkTensorViewCreateFlagBitsARM VK_TENSOR_VIEW_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_ARM = 0x00000001ULL; + + +typedef enum VkSpirvResourceTypeFlagBitsEXT { + VK_SPIRV_RESOURCE_TYPE_ALL_EXT = 0x7FFFFFFF, + VK_SPIRV_RESOURCE_TYPE_SAMPLER_BIT_EXT = 0x00000001, + VK_SPIRV_RESOURCE_TYPE_SAMPLED_IMAGE_BIT_EXT = 0x00000002, + VK_SPIRV_RESOURCE_TYPE_READ_ONLY_IMAGE_BIT_EXT = 0x00000004, + VK_SPIRV_RESOURCE_TYPE_READ_WRITE_IMAGE_BIT_EXT = 0x00000008, + VK_SPIRV_RESOURCE_TYPE_COMBINED_SAMPLED_IMAGE_BIT_EXT = 0x00000010, + VK_SPIRV_RESOURCE_TYPE_UNIFORM_BUFFER_BIT_EXT = 0x00000020, + VK_SPIRV_RESOURCE_TYPE_READ_ONLY_STORAGE_BUFFER_BIT_EXT = 0x00000040, + VK_SPIRV_RESOURCE_TYPE_READ_WRITE_STORAGE_BUFFER_BIT_EXT = 0x00000080, + VK_SPIRV_RESOURCE_TYPE_ACCELERATION_STRUCTURE_BIT_EXT = 0x00000100, + VK_SPIRV_RESOURCE_TYPE_TENSOR_BIT_ARM = 0x00000200, + VK_SPIRV_RESOURCE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSpirvResourceTypeFlagBitsEXT; +typedef VkFlags VkSpirvResourceTypeFlagsEXT; +typedef struct VkHostAddressRangeEXT { + void* address; + size_t size; +} VkHostAddressRangeEXT; + +typedef struct VkHostAddressRangeConstEXT { + const void* address; + size_t size; +} VkHostAddressRangeConstEXT; + +typedef VkDeviceAddressRangeKHR VkDeviceAddressRangeEXT; + +typedef struct VkTexelBufferDescriptorInfoEXT { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkDeviceAddressRangeEXT addressRange; +} VkTexelBufferDescriptorInfoEXT; + +typedef struct VkImageDescriptorInfoEXT { + VkStructureType sType; + const void* pNext; + const VkImageViewCreateInfo* pView; + VkImageLayout layout; +} VkImageDescriptorInfoEXT; + +typedef struct VkTensorViewCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorViewCreateFlagsARM flags; + VkTensorARM tensor; + VkFormat format; +} VkTensorViewCreateInfoARM; + +typedef union VkResourceDescriptorDataEXT { + const VkImageDescriptorInfoEXT* pImage; + const VkTexelBufferDescriptorInfoEXT* pTexelBuffer; + const VkDeviceAddressRangeEXT* pAddressRange; + const VkTensorViewCreateInfoARM* pTensorARM; +} VkResourceDescriptorDataEXT; + +typedef struct VkResourceDescriptorInfoEXT { + VkStructureType sType; + const void* pNext; + VkDescriptorType type; + VkResourceDescriptorDataEXT data; +} VkResourceDescriptorInfoEXT; + +typedef struct VkBindHeapInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceAddressRangeEXT heapRange; + VkDeviceSize reservedRangeOffset; + VkDeviceSize reservedRangeSize; +} VkBindHeapInfoEXT; + +typedef struct VkPushDataInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t offset; + VkHostAddressRangeConstEXT data; +} VkPushDataInfoEXT; + +typedef struct VkDescriptorMappingSourceConstantOffsetEXT { + uint32_t heapOffset; + uint32_t heapArrayStride; + const VkSamplerCreateInfo* pEmbeddedSampler; + uint32_t samplerHeapOffset; + uint32_t samplerHeapArrayStride; +} VkDescriptorMappingSourceConstantOffsetEXT; + +typedef struct VkDescriptorMappingSourcePushIndexEXT { + uint32_t heapOffset; + uint32_t pushOffset; + uint32_t heapIndexStride; + uint32_t heapArrayStride; + const VkSamplerCreateInfo* pEmbeddedSampler; + VkBool32 useCombinedImageSamplerIndex; + uint32_t samplerHeapOffset; + uint32_t samplerPushOffset; + uint32_t samplerHeapIndexStride; + uint32_t samplerHeapArrayStride; +} VkDescriptorMappingSourcePushIndexEXT; + +typedef struct VkDescriptorMappingSourceIndirectIndexEXT { + uint32_t heapOffset; + uint32_t pushOffset; + uint32_t addressOffset; + uint32_t heapIndexStride; + uint32_t heapArrayStride; + const VkSamplerCreateInfo* pEmbeddedSampler; + VkBool32 useCombinedImageSamplerIndex; + uint32_t samplerHeapOffset; + uint32_t samplerPushOffset; + uint32_t samplerAddressOffset; + uint32_t samplerHeapIndexStride; + uint32_t samplerHeapArrayStride; +} VkDescriptorMappingSourceIndirectIndexEXT; + +typedef struct VkDescriptorMappingSourceHeapDataEXT { + uint32_t heapOffset; + uint32_t pushOffset; +} VkDescriptorMappingSourceHeapDataEXT; + +typedef struct VkDescriptorMappingSourceIndirectAddressEXT { + uint32_t pushOffset; + uint32_t addressOffset; +} VkDescriptorMappingSourceIndirectAddressEXT; + +typedef struct VkDescriptorMappingSourceShaderRecordIndexEXT { + uint32_t heapOffset; + uint32_t shaderRecordOffset; + uint32_t heapIndexStride; + uint32_t heapArrayStride; + const VkSamplerCreateInfo* pEmbeddedSampler; + VkBool32 useCombinedImageSamplerIndex; + uint32_t samplerHeapOffset; + uint32_t samplerShaderRecordOffset; + uint32_t samplerHeapIndexStride; + uint32_t samplerHeapArrayStride; +} VkDescriptorMappingSourceShaderRecordIndexEXT; + +typedef struct VkDescriptorMappingSourceIndirectIndexArrayEXT { + uint32_t heapOffset; + uint32_t pushOffset; + uint32_t addressOffset; + uint32_t heapIndexStride; + const VkSamplerCreateInfo* pEmbeddedSampler; + VkBool32 useCombinedImageSamplerIndex; + uint32_t samplerHeapOffset; + uint32_t samplerPushOffset; + uint32_t samplerAddressOffset; + uint32_t samplerHeapIndexStride; +} VkDescriptorMappingSourceIndirectIndexArrayEXT; + +typedef union VkDescriptorMappingSourceDataEXT { + VkDescriptorMappingSourceConstantOffsetEXT constantOffset; + VkDescriptorMappingSourcePushIndexEXT pushIndex; + VkDescriptorMappingSourceIndirectIndexEXT indirectIndex; + VkDescriptorMappingSourceIndirectIndexArrayEXT indirectIndexArray; + VkDescriptorMappingSourceHeapDataEXT heapData; + uint32_t pushDataOffset; + uint32_t pushAddressOffset; + VkDescriptorMappingSourceIndirectAddressEXT indirectAddress; + VkDescriptorMappingSourceShaderRecordIndexEXT shaderRecordIndex; + uint32_t shaderRecordDataOffset; + uint32_t shaderRecordAddressOffset; +} VkDescriptorMappingSourceDataEXT; + +typedef struct VkDescriptorSetAndBindingMappingEXT { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSet; + uint32_t firstBinding; + uint32_t bindingCount; + VkSpirvResourceTypeFlagsEXT resourceMask; + VkDescriptorMappingSourceEXT source; + VkDescriptorMappingSourceDataEXT sourceData; +} VkDescriptorSetAndBindingMappingEXT; + +typedef struct VkShaderDescriptorSetAndBindingMappingInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t mappingCount; + const VkDescriptorSetAndBindingMappingEXT* pMappings; +} VkShaderDescriptorSetAndBindingMappingInfoEXT; + +typedef struct VkOpaqueCaptureDataCreateInfoEXT { + VkStructureType sType; + const void* pNext; + const VkHostAddressRangeConstEXT* pData; +} VkOpaqueCaptureDataCreateInfoEXT; + +typedef struct VkPhysicalDeviceDescriptorHeapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 descriptorHeap; + VkBool32 descriptorHeapCaptureReplay; +} VkPhysicalDeviceDescriptorHeapFeaturesEXT; + +typedef struct VkPhysicalDeviceDescriptorHeapPropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize samplerHeapAlignment; + VkDeviceSize resourceHeapAlignment; + VkDeviceSize maxSamplerHeapSize; + VkDeviceSize maxResourceHeapSize; + VkDeviceSize minSamplerHeapReservedRange; + VkDeviceSize minSamplerHeapReservedRangeWithEmbedded; + VkDeviceSize minResourceHeapReservedRange; + VkDeviceSize samplerDescriptorSize; + VkDeviceSize imageDescriptorSize; + VkDeviceSize bufferDescriptorSize; + VkDeviceSize samplerDescriptorAlignment; + VkDeviceSize imageDescriptorAlignment; + VkDeviceSize bufferDescriptorAlignment; + VkDeviceSize maxPushDataSize; + size_t imageCaptureReplayOpaqueDataSize; + uint32_t maxDescriptorHeapEmbeddedSamplers; + uint32_t samplerYcbcrConversionCount; + VkBool32 sparseDescriptorHeaps; + VkBool32 protectedDescriptorHeaps; +} VkPhysicalDeviceDescriptorHeapPropertiesEXT; + +typedef struct VkCommandBufferInheritanceDescriptorHeapInfoEXT { + VkStructureType sType; + const void* pNext; + const VkBindHeapInfoEXT* pSamplerHeapBindInfo; + const VkBindHeapInfoEXT* pResourceHeapBindInfo; +} VkCommandBufferInheritanceDescriptorHeapInfoEXT; + +typedef struct VkSamplerCustomBorderColorIndexCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t index; +} VkSamplerCustomBorderColorIndexCreateInfoEXT; + +typedef struct VkSamplerCustomBorderColorCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkClearColorValue customBorderColor; + VkFormat format; +} VkSamplerCustomBorderColorCreateInfoEXT; + +typedef struct VkIndirectCommandsLayoutPushDataTokenNV { + VkStructureType sType; + const void* pNext; + uint32_t pushDataOffset; + uint32_t pushDataSize; +} VkIndirectCommandsLayoutPushDataTokenNV; + +typedef struct VkSubsampledImageFormatPropertiesEXT { + VkStructureType sType; + const void* pNext; + uint32_t subsampledImageDescriptorCount; +} VkSubsampledImageFormatPropertiesEXT; + +typedef struct VkPhysicalDeviceDescriptorHeapTensorPropertiesARM { + VkStructureType sType; + void* pNext; + VkDeviceSize tensorDescriptorSize; + VkDeviceSize tensorDescriptorAlignment; + size_t tensorCaptureReplayOpaqueDataSize; +} VkPhysicalDeviceDescriptorHeapTensorPropertiesARM; + +typedef VkResult (VKAPI_PTR *PFN_vkWriteSamplerDescriptorsEXT)(VkDevice device, uint32_t samplerCount, const VkSamplerCreateInfo* pSamplers, const VkHostAddressRangeEXT* pDescriptors); +typedef VkResult (VKAPI_PTR *PFN_vkWriteResourceDescriptorsEXT)(VkDevice device, uint32_t resourceCount, const VkResourceDescriptorInfoEXT* pResources, const VkHostAddressRangeEXT* pDescriptors); +typedef void (VKAPI_PTR *PFN_vkCmdBindSamplerHeapEXT)(VkCommandBuffer commandBuffer, const VkBindHeapInfoEXT* pBindInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindResourceHeapEXT)(VkCommandBuffer commandBuffer, const VkBindHeapInfoEXT* pBindInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDataEXT)(VkCommandBuffer commandBuffer, const VkPushDataInfoEXT* pPushDataInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageOpaqueCaptureDataEXT)(VkDevice device, uint32_t imageCount, const VkImage* pImages, VkHostAddressRangeEXT* pDatas); +typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetPhysicalDeviceDescriptorSizeEXT)(VkPhysicalDevice physicalDevice, VkDescriptorType descriptorType); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterCustomBorderColorEXT)(VkDevice device, const VkSamplerCustomBorderColorCreateInfoEXT* pBorderColor, VkBool32 requestIndex, uint32_t* pIndex); +typedef void (VKAPI_PTR *PFN_vkUnregisterCustomBorderColorEXT)(VkDevice device, uint32_t index); +typedef VkResult (VKAPI_PTR *PFN_vkGetTensorOpaqueCaptureDataARM)(VkDevice device, uint32_t tensorCount, const VkTensorARM* pTensors, VkHostAddressRangeEXT* pDatas); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkWriteSamplerDescriptorsEXT( + VkDevice device, + uint32_t samplerCount, + const VkSamplerCreateInfo* pSamplers, + const VkHostAddressRangeEXT* pDescriptors); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkWriteResourceDescriptorsEXT( + VkDevice device, + uint32_t resourceCount, + const VkResourceDescriptorInfoEXT* pResources, + const VkHostAddressRangeEXT* pDescriptors); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindSamplerHeapEXT( + VkCommandBuffer commandBuffer, + const VkBindHeapInfoEXT* pBindInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindResourceHeapEXT( + VkCommandBuffer commandBuffer, + const VkBindHeapInfoEXT* pBindInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdPushDataEXT( + VkCommandBuffer commandBuffer, + const VkPushDataInfoEXT* pPushDataInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageOpaqueCaptureDataEXT( + VkDevice device, + uint32_t imageCount, + const VkImage* pImages, + VkHostAddressRangeEXT* pDatas); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetPhysicalDeviceDescriptorSizeEXT( + VkPhysicalDevice physicalDevice, + VkDescriptorType descriptorType); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterCustomBorderColorEXT( + VkDevice device, + const VkSamplerCustomBorderColorCreateInfoEXT* pBorderColor, + VkBool32 requestIndex, + uint32_t* pIndex); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkUnregisterCustomBorderColorEXT( + VkDevice device, + uint32_t index); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetTensorOpaqueCaptureDataARM( + VkDevice device, + uint32_t tensorCount, + const VkTensorARM* pTensors, + VkHostAddressRangeEXT* pDatas); +#endif +#endif + + // VK_AMD_mixed_attachment_samples is a preprocessor guard. Do not pass it to API calls. #define VK_AMD_mixed_attachment_samples 1 #define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 #define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" +typedef struct VkAttachmentSampleCountInfoAMD { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const VkSampleCountFlagBits* pColorAttachmentSamples; + VkSampleCountFlagBits depthStencilAttachmentSamples; +} VkAttachmentSampleCountInfoAMD; + // VK_AMD_shader_fragment_mask is a preprocessor guard. Do not pass it to API calls. @@ -13162,15 +16994,19 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer command typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT( VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT( VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); #endif +#endif // VK_EXT_blend_operation_advanced is a preprocessor guard. Do not pass it to API calls. @@ -13249,6 +17085,8 @@ typedef struct VkPipelineCoverageModulationStateCreateInfoNV { const float* pCoverageModulationTable; } VkPipelineCoverageModulationStateCreateInfoNV; +typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; + // VK_NV_fill_rectangle is a preprocessor guard. Do not pass it to API calls. @@ -13345,11 +17183,13 @@ typedef struct VkDrmFormatModifierPropertiesList2EXT { typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetImageDrmFormatModifierPropertiesEXT( VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); #endif +#endif // VK_EXT_validation_cache is a preprocessor guard. Do not pass it to API calls. @@ -13383,29 +17223,37 @@ typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, Vk typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT( VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT( VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT( VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); #endif +#endif // VK_EXT_descriptor_indexing is a preprocessor guard. Do not pass it to API calls. @@ -13516,23 +17364,29 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuff typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV( VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV( VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); #endif +#endif // VK_NV_ray_tracing is a preprocessor guard. Do not pass it to API calls. @@ -13559,21 +17413,18 @@ typedef enum VkGeometryTypeKHR { VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0, VK_GEOMETRY_TYPE_AABBS_KHR = 1, VK_GEOMETRY_TYPE_INSTANCES_KHR = 2, + VK_GEOMETRY_TYPE_SPHERES_NV = 1000429004, + VK_GEOMETRY_TYPE_LINEAR_SWEPT_SPHERES_NV = 1000429005, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_GEOMETRY_TYPE_DENSE_GEOMETRY_FORMAT_TRIANGLES_AMDX = 1000478000, +#endif + VK_GEOMETRY_TYPE_MICROMAP_KHR = 1000623000, VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR, VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF } VkGeometryTypeKHR; typedef VkGeometryTypeKHR VkGeometryTypeNV; - -typedef enum VkAccelerationStructureTypeKHR { - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, - VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2, - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, - VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureTypeKHR; typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV; @@ -13614,13 +17465,19 @@ typedef enum VkGeometryInstanceFlagBitsKHR { VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002, VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, - VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT = 0x00000010, - VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000020, + VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_BIT_KHR = 0x00000010, + VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_BIT_KHR = 0x00000020, VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_BIT_EXT = VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_BIT_KHR, + // VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT is a legacy alias + VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT = VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_BIT_EXT, + VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_BIT_EXT = VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_BIT_KHR, + // VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT is a legacy alias + VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT = VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_BIT_EXT, VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkGeometryInstanceFlagBitsKHR; typedef VkFlags VkGeometryInstanceFlagsKHR; @@ -13636,25 +17493,41 @@ typedef enum VkBuildAccelerationStructureFlagBitsKHR { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008, VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV = 0x00000020, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT = 0x00000040, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000080, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT = 0x00000100, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_BIT_EXT = 0x00000100, #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV = 0x00000200, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_BIT_NV = 0x00000200, #endif - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR = 0x00000800, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_BIT_KHR = 0x00000800, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_CLUSTER_OPACITY_MICROMAPS_BIT_NV = 0x00001000, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_BIT_KHR = 0x00000040, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_BIT_KHR = 0x00000080, + VK_BUILD_ACCELERATION_STRUCTURE_MICROMAP_LOSSY_BIT_KHR = 0x00000400, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_BIT_EXT = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_BIT_KHR, + // VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT is a legacy alias + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_BIT_EXT, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_BIT_EXT = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_BIT_KHR, + // VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT is a legacy alias + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_BIT_EXT, + // VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT is a legacy alias + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_BIT_EXT, +#ifdef VK_ENABLE_BETA_EXTENSIONS + // VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV is a legacy alias + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_BIT_NV, +#endif + // VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR is a legacy alias + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkBuildAccelerationStructureFlagBitsKHR; typedef VkFlags VkBuildAccelerationStructureFlagsKHR; -typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; - typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV; +typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; + typedef struct VkRayTracingShaderGroupCreateInfoNV { VkStructureType sType; const void* pNext; @@ -13718,13 +17591,13 @@ typedef struct VkGeometryNV { } VkGeometryNV; typedef struct VkAccelerationStructureInfoNV { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureTypeNV type; - VkBuildAccelerationStructureFlagsNV flags; - uint32_t instanceCount; - uint32_t geometryCount; - const VkGeometryNV* pGeometries; + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeNV type; + VkBuildAccelerationStructureFlagsKHR flags; + uint32_t instanceCount; + uint32_t geometryCount; + const VkGeometryNV* pGeometries; } VkAccelerationStructureInfoNV; typedef struct VkAccelerationStructureCreateInfoNV { @@ -13801,7 +17674,7 @@ typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV; typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode); @@ -13814,27 +17687,36 @@ typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCom typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV( VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV( VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, - VkMemoryRequirements2KHR* pMemoryRequirements); + VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV( VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, @@ -13845,13 +17727,17 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, @@ -13868,7 +17754,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( uint32_t width, uint32_t height, uint32_t depth); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( VkDevice device, VkPipelineCache pipelineCache, @@ -13876,7 +17764,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( VkDevice device, VkPipeline pipeline, @@ -13884,7 +17774,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( uint32_t groupCount, size_t dataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( VkDevice device, VkPipeline pipeline, @@ -13892,13 +17784,17 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( uint32_t groupCount, size_t dataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV( VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, @@ -13906,12 +17802,15 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV( VkDevice device, VkPipeline pipeline, uint32_t shader); #endif +#endif // VK_NV_representative_fragment_test is a preprocessor guard. Do not pass it to API calls. @@ -13957,13 +17856,37 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { #define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve" +// VK_QCOM_cooperative_matrix_conversion is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_cooperative_matrix_conversion 1 +#define VK_QCOM_COOPERATIVE_MATRIX_CONVERSION_SPEC_VERSION 1 +#define VK_QCOM_COOPERATIVE_MATRIX_CONVERSION_EXTENSION_NAME "VK_QCOM_cooperative_matrix_conversion" +typedef struct VkPhysicalDeviceCooperativeMatrixConversionFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeMatrixConversion; +} VkPhysicalDeviceCooperativeMatrixConversionFeaturesQCOM; + + + +// VK_QCOM_elapsed_timer_query is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_elapsed_timer_query 1 +#define VK_QCOM_ELAPSED_TIMER_QUERY_SPEC_VERSION 1 +#define VK_QCOM_ELAPSED_TIMER_QUERY_EXTENSION_NAME "VK_QCOM_elapsed_timer_query" +typedef struct VkPhysicalDeviceElapsedTimerQueryFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 elapsedTimerQuery; +} VkPhysicalDeviceElapsedTimerQueryFeaturesQCOM; + + + // VK_EXT_global_priority is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" -typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; +typedef VkQueueGlobalPriority VkQueueGlobalPriorityEXT; -typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; +typedef VkDeviceQueueGlobalPriorityCreateInfo VkDeviceQueueGlobalPriorityCreateInfoEXT; @@ -13993,12 +17916,14 @@ typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT { typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); #endif +#endif // VK_AMD_buffer_marker is a preprocessor guard. Do not pass it to API calls. @@ -14006,8 +17931,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( #define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1 #define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker" typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, @@ -14016,6 +17943,16 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( uint32_t marker); #endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + uint32_t marker); +#endif +#endif + // VK_AMD_pipeline_compiler_control is a preprocessor guard. Do not pass it to API calls. #define VK_AMD_pipeline_compiler_control 1 @@ -14046,11 +17983,14 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT) typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsEXT)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainKHR* pTimeDomains); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( VkDevice device, uint32_t timestampCount, @@ -14058,6 +17998,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( uint64_t* pTimestamps, uint64_t* pMaxDeviation); #endif +#endif // VK_AMD_shader_core_properties is a preprocessor guard. Do not pass it to API calls. @@ -14114,11 +18055,11 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT { uint32_t maxVertexAttribDivisor; } VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT; -typedef VkVertexInputBindingDivisorDescriptionKHR VkVertexInputBindingDivisorDescriptionEXT; +typedef VkVertexInputBindingDivisorDescription VkVertexInputBindingDivisorDescriptionEXT; -typedef VkPipelineVertexInputDivisorStateCreateInfoKHR VkPipelineVertexInputDivisorStateCreateInfoEXT; +typedef VkPipelineVertexInputDivisorStateCreateInfo VkPipelineVertexInputDivisorStateCreateInfoEXT; -typedef VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; +typedef VkPhysicalDeviceVertexAttributeDivisorFeatures VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; @@ -14146,12 +18087,7 @@ typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; #define VK_NV_compute_shader_derivatives 1 #define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 #define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" -typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 computeDerivativeGroupQuads; - VkBool32 computeDerivativeGroupLinear; -} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; +typedef VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; @@ -14194,18 +18130,23 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer comma typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV( VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -14215,6 +18156,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( uint32_t maxDrawCount, uint32_t stride); #endif +#endif // VK_NV_fragment_shader_barycentric is a preprocessor guard. Do not pass it to API calls. @@ -14258,18 +18200,22 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorEnableNV)(VkCommandBuffer c typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorEnableNV( VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkBool32* pExclusiveScissorEnables); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV( VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors); #endif +#endif // VK_NV_device_diagnostic_checkpoints is a preprocessor guard. Do not pass it to API calls. @@ -14289,20 +18235,200 @@ typedef struct VkCheckpointDataNV { void* pCheckpointMarker; } VkCheckpointDataNV; +typedef struct VkQueueFamilyCheckpointProperties2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 checkpointExecutionStageMask; +} VkQueueFamilyCheckpointProperties2NV; + +typedef struct VkCheckpointData2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 stage; + void* pCheckpointMarker; +} VkCheckpointData2NV; + typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker); typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV( VkCommandBuffer commandBuffer, const void* pCheckpointMarker); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV( VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData); #endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( + VkQueue queue, + uint32_t* pCheckpointDataCount, + VkCheckpointData2NV* pCheckpointData); +#endif +#endif + + +// VK_EXT_present_timing is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_present_timing 1 +#define VK_EXT_PRESENT_TIMING_SPEC_VERSION 3 +#define VK_EXT_PRESENT_TIMING_EXTENSION_NAME "VK_EXT_present_timing" + +typedef enum VkPresentStageFlagBitsEXT { + VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT = 0x00000001, + VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT = 0x00000002, + VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT = 0x00000004, + VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT = 0x00000008, + VK_PRESENT_STAGE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPresentStageFlagBitsEXT; +typedef VkFlags VkPresentStageFlagsEXT; + +typedef enum VkPastPresentationTimingFlagBitsEXT { + VK_PAST_PRESENTATION_TIMING_ALLOW_PARTIAL_RESULTS_BIT_EXT = 0x00000001, + VK_PAST_PRESENTATION_TIMING_ALLOW_OUT_OF_ORDER_RESULTS_BIT_EXT = 0x00000002, + VK_PAST_PRESENTATION_TIMING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPastPresentationTimingFlagBitsEXT; +typedef VkFlags VkPastPresentationTimingFlagsEXT; + +typedef enum VkPresentTimingInfoFlagBitsEXT { + VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT = 0x00000001, + VK_PRESENT_TIMING_INFO_PRESENT_AT_NEAREST_REFRESH_CYCLE_BIT_EXT = 0x00000002, + VK_PRESENT_TIMING_INFO_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPresentTimingInfoFlagBitsEXT; +typedef VkFlags VkPresentTimingInfoFlagsEXT; +typedef struct VkPhysicalDevicePresentTimingFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 presentTiming; + VkBool32 presentAtAbsoluteTime; + VkBool32 presentAtRelativeTime; +} VkPhysicalDevicePresentTimingFeaturesEXT; + +typedef struct VkPresentTimingSurfaceCapabilitiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 presentTimingSupported; + VkBool32 presentAtAbsoluteTimeSupported; + VkBool32 presentAtRelativeTimeSupported; + VkPresentStageFlagsEXT presentStageQueries; +} VkPresentTimingSurfaceCapabilitiesEXT; + +typedef struct VkSwapchainCalibratedTimestampInfoEXT { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + VkPresentStageFlagsEXT presentStage; + uint64_t timeDomainId; +} VkSwapchainCalibratedTimestampInfoEXT; + +typedef struct VkSwapchainTimingPropertiesEXT { + VkStructureType sType; + void* pNext; + uint64_t refreshDuration; + uint64_t refreshInterval; +} VkSwapchainTimingPropertiesEXT; + +typedef struct VkSwapchainTimeDomainPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t timeDomainCount; + VkTimeDomainKHR* pTimeDomains; + uint64_t* pTimeDomainIds; +} VkSwapchainTimeDomainPropertiesEXT; + +typedef struct VkPastPresentationTimingInfoEXT { + VkStructureType sType; + const void* pNext; + VkPastPresentationTimingFlagsEXT flags; + VkSwapchainKHR swapchain; +} VkPastPresentationTimingInfoEXT; + +typedef struct VkPresentStageTimeEXT { + VkPresentStageFlagsEXT stage; + uint64_t time; +} VkPresentStageTimeEXT; + +typedef struct VkPastPresentationTimingEXT { + VkStructureType sType; + void* pNext; + uint64_t presentId; + uint64_t targetTime; + uint32_t presentStageCount; + VkPresentStageTimeEXT* pPresentStages; + VkTimeDomainKHR timeDomain; + uint64_t timeDomainId; + VkBool32 reportComplete; +} VkPastPresentationTimingEXT; + +typedef struct VkPastPresentationTimingPropertiesEXT { + VkStructureType sType; + void* pNext; + uint64_t timingPropertiesCounter; + uint64_t timeDomainsCounter; + uint32_t presentationTimingCount; + VkPastPresentationTimingEXT* pPresentationTimings; +} VkPastPresentationTimingPropertiesEXT; + +typedef struct VkPresentTimingInfoEXT { + VkStructureType sType; + const void* pNext; + VkPresentTimingInfoFlagsEXT flags; + uint64_t targetTime; + uint64_t timeDomainId; + VkPresentStageFlagsEXT presentStageQueries; + VkPresentStageFlagsEXT targetTimeDomainPresentStage; +} VkPresentTimingInfoEXT; + +typedef struct VkPresentTimingsInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentTimingInfoEXT* pTimingInfos; +} VkPresentTimingsInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkSetSwapchainPresentTimingQueueSizeEXT)(VkDevice device, VkSwapchainKHR swapchain, uint32_t size); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainTimingPropertiesEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSwapchainTimingPropertiesEXT* pSwapchainTimingProperties, uint64_t* pSwapchainTimingPropertiesCounter); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainTimeDomainPropertiesEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSwapchainTimeDomainPropertiesEXT* pSwapchainTimeDomainProperties, uint64_t* pTimeDomainsCounter); +typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingEXT)(VkDevice device, const VkPastPresentationTimingInfoEXT* pPastPresentationTimingInfo, VkPastPresentationTimingPropertiesEXT* pPastPresentationTimingProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkSetSwapchainPresentTimingQueueSizeEXT( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t size); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainTimingPropertiesEXT( + VkDevice device, + VkSwapchainKHR swapchain, + VkSwapchainTimingPropertiesEXT* pSwapchainTimingProperties, + uint64_t* pSwapchainTimingPropertiesCounter); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainTimeDomainPropertiesEXT( + VkDevice device, + VkSwapchainKHR swapchain, + VkSwapchainTimeDomainPropertiesEXT* pSwapchainTimeDomainProperties, + uint64_t* pTimeDomainsCounter); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingEXT( + VkDevice device, + const VkPastPresentationTimingInfoEXT* pPastPresentationTimingInfo, + VkPastPresentationTimingPropertiesEXT* pPastPresentationTimingProperties); +#endif +#endif + // VK_INTEL_shader_integer_functions2 is a preprocessor guard. Do not pass it to API calls. #define VK_INTEL_shader_integer_functions2 1 @@ -14416,43 +18542,61 @@ typedef VkResult (VKAPI_PTR *PFN_vkQueueSetPerformanceConfigurationINTEL)(VkQueu typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceParameterINTEL)(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkInitializePerformanceApiINTEL( VkDevice device, const VkInitializePerformanceApiInfoINTEL* pInitializeInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkUninitializePerformanceApiINTEL( VkDevice device); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceMarkerINTEL( VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL* pMarkerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceStreamMarkerINTEL( VkCommandBuffer commandBuffer, const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceOverrideINTEL( VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL* pOverrideInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquirePerformanceConfigurationINTEL( VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, VkPerformanceConfigurationINTEL* pConfiguration); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkReleasePerformanceConfigurationINTEL( VkDevice device, VkPerformanceConfigurationINTEL configuration); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkQueueSetPerformanceConfigurationINTEL( VkQueue queue, VkPerformanceConfigurationINTEL configuration); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceParameterINTEL( VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue); #endif +#endif // VK_EXT_pci_bus_info is a preprocessor guard. Do not pass it to API calls. @@ -14489,16 +18633,18 @@ typedef struct VkSwapchainDisplayNativeHdrCreateInfoAMD { typedef void (VKAPI_PTR *PFN_vkSetLocalDimmingAMD)(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD( VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable); #endif +#endif // VK_EXT_fragment_density_map is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_fragment_density_map 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 3 #define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { VkStructureType sType; @@ -14522,6 +18668,13 @@ typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { VkAttachmentReference fragmentDensityMapAttachment; } VkRenderPassFragmentDensityMapCreateInfoEXT; +typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; +} VkRenderingFragmentDensityMapAttachmentInfoEXT; + // VK_EXT_scalar_block_layout is a preprocessor guard. Do not pass it to API calls. @@ -14536,7 +18689,9 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_GOOGLE_hlsl_functionality1 1 #define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1 #define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +// VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION is a legacy alias #define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +// VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME is a legacy alias #define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME @@ -14669,10 +18824,12 @@ typedef struct VkBufferDeviceAddressCreateInfoEXT { typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( VkDevice device, const VkBufferDeviceAddressInfo* pInfo); #endif +#endif // VK_EXT_tooling_info is a preprocessor guard. Do not pass it to API calls. @@ -14688,11 +18845,13 @@ typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); #endif +#endif // VK_EXT_separate_stencil_usage is a preprocessor guard. Do not pass it to API calls. @@ -14776,11 +18935,13 @@ typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesNV { typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties); #endif +#endif // VK_NV_coverage_reduction_mode is a preprocessor guard. Do not pass it to API calls. @@ -14819,11 +18980,13 @@ typedef struct VkFramebufferMixedSamplesCombinationNV { typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)(VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV( VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations); #endif +#endif // VK_EXT_fragment_shader_interlock is a preprocessor guard. Do not pass it to API calls. @@ -14898,34 +19061,38 @@ typedef struct VkHeadlessSurfaceCreateInfoEXT { typedef VkResult (VKAPI_PTR *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT( VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_EXT_line_rasterization is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_line_rasterization 1 #define VK_EXT_LINE_RASTERIZATION_SPEC_VERSION 1 #define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization" -typedef VkLineRasterizationModeKHR VkLineRasterizationModeEXT; +typedef VkLineRasterizationMode VkLineRasterizationModeEXT; -typedef VkPhysicalDeviceLineRasterizationFeaturesKHR VkPhysicalDeviceLineRasterizationFeaturesEXT; +typedef VkPhysicalDeviceLineRasterizationFeatures VkPhysicalDeviceLineRasterizationFeaturesEXT; -typedef VkPhysicalDeviceLineRasterizationPropertiesKHR VkPhysicalDeviceLineRasterizationPropertiesEXT; +typedef VkPhysicalDeviceLineRasterizationProperties VkPhysicalDeviceLineRasterizationPropertiesEXT; -typedef VkPipelineRasterizationLineStateCreateInfoKHR VkPipelineRasterizationLineStateCreateInfoEXT; +typedef VkPipelineRasterizationLineStateCreateInfo VkPipelineRasterizationLineStateCreateInfoEXT; typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEXT)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT( VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); #endif +#endif // VK_EXT_shader_atomic_float is a preprocessor guard. Do not pass it to API calls. @@ -14960,19 +19127,21 @@ typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFea typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkResetQueryPoolEXT( VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); #endif +#endif // VK_EXT_index_type_uint8 is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_index_type_uint8 1 #define VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION 1 #define VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_EXT_index_type_uint8" -typedef VkPhysicalDeviceIndexTypeUint8FeaturesKHR VkPhysicalDeviceIndexTypeUint8FeaturesEXT; +typedef VkPhysicalDeviceIndexTypeUint8Features VkPhysicalDeviceIndexTypeUint8FeaturesEXT; @@ -15000,28 +19169,39 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnableEXT)(VkCommandBuffer comma typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOpEXT)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCullModeEXT( VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFaceEXT( VkCommandBuffer commandBuffer, VkFrontFace frontFace); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopologyEXT( VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCountEXT( VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCountEXT( VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT( VkCommandBuffer commandBuffer, uint32_t firstBinding, @@ -15030,27 +19210,39 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT( const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOpEXT( VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT( VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, @@ -15059,144 +19251,80 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT( VkStencilOp depthFailOp, VkCompareOp compareOp); #endif +#endif // VK_EXT_host_image_copy is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_host_image_copy 1 #define VK_EXT_HOST_IMAGE_COPY_SPEC_VERSION 1 #define VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME "VK_EXT_host_image_copy" +typedef VkHostImageCopyFlagBits VkHostImageCopyFlagBitsEXT; -typedef enum VkHostImageCopyFlagBitsEXT { - VK_HOST_IMAGE_COPY_MEMCPY_EXT = 0x00000001, - VK_HOST_IMAGE_COPY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkHostImageCopyFlagBitsEXT; -typedef VkFlags VkHostImageCopyFlagsEXT; -typedef struct VkPhysicalDeviceHostImageCopyFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 hostImageCopy; -} VkPhysicalDeviceHostImageCopyFeaturesEXT; +typedef VkHostImageCopyFlags VkHostImageCopyFlagsEXT; -typedef struct VkPhysicalDeviceHostImageCopyPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t copySrcLayoutCount; - VkImageLayout* pCopySrcLayouts; - uint32_t copyDstLayoutCount; - VkImageLayout* pCopyDstLayouts; - uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE]; - VkBool32 identicalMemoryTypeRequirements; -} VkPhysicalDeviceHostImageCopyPropertiesEXT; +typedef VkPhysicalDeviceHostImageCopyFeatures VkPhysicalDeviceHostImageCopyFeaturesEXT; -typedef struct VkMemoryToImageCopyEXT { - VkStructureType sType; - const void* pNext; - const void* pHostPointer; - uint32_t memoryRowLength; - uint32_t memoryImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkMemoryToImageCopyEXT; +typedef VkPhysicalDeviceHostImageCopyProperties VkPhysicalDeviceHostImageCopyPropertiesEXT; -typedef struct VkImageToMemoryCopyEXT { - VkStructureType sType; - const void* pNext; - void* pHostPointer; - uint32_t memoryRowLength; - uint32_t memoryImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkImageToMemoryCopyEXT; +typedef VkMemoryToImageCopy VkMemoryToImageCopyEXT; -typedef struct VkCopyMemoryToImageInfoEXT { - VkStructureType sType; - const void* pNext; - VkHostImageCopyFlagsEXT flags; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkMemoryToImageCopyEXT* pRegions; -} VkCopyMemoryToImageInfoEXT; +typedef VkImageToMemoryCopy VkImageToMemoryCopyEXT; -typedef struct VkCopyImageToMemoryInfoEXT { - VkStructureType sType; - const void* pNext; - VkHostImageCopyFlagsEXT flags; - VkImage srcImage; - VkImageLayout srcImageLayout; - uint32_t regionCount; - const VkImageToMemoryCopyEXT* pRegions; -} VkCopyImageToMemoryInfoEXT; +typedef VkCopyMemoryToImageInfo VkCopyMemoryToImageInfoEXT; -typedef struct VkCopyImageToImageInfoEXT { - VkStructureType sType; - const void* pNext; - VkHostImageCopyFlagsEXT flags; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2* pRegions; -} VkCopyImageToImageInfoEXT; +typedef VkCopyImageToMemoryInfo VkCopyImageToMemoryInfoEXT; -typedef struct VkHostImageLayoutTransitionInfoEXT { - VkStructureType sType; - const void* pNext; - VkImage image; - VkImageLayout oldLayout; - VkImageLayout newLayout; - VkImageSubresourceRange subresourceRange; -} VkHostImageLayoutTransitionInfoEXT; +typedef VkCopyImageToImageInfo VkCopyImageToImageInfoEXT; -typedef struct VkSubresourceHostMemcpySizeEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize size; -} VkSubresourceHostMemcpySizeEXT; +typedef VkHostImageLayoutTransitionInfo VkHostImageLayoutTransitionInfoEXT; -typedef struct VkHostImageCopyDevicePerformanceQueryEXT { - VkStructureType sType; - void* pNext; - VkBool32 optimalDeviceAccess; - VkBool32 identicalMemoryLayout; -} VkHostImageCopyDevicePerformanceQueryEXT; +typedef VkSubresourceHostMemcpySize VkSubresourceHostMemcpySizeEXT; -typedef VkSubresourceLayout2KHR VkSubresourceLayout2EXT; +typedef VkHostImageCopyDevicePerformanceQuery VkHostImageCopyDevicePerformanceQueryEXT; -typedef VkImageSubresource2KHR VkImageSubresource2EXT; +typedef VkSubresourceLayout2 VkSubresourceLayout2EXT; -typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToImageEXT)(VkDevice device, const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToMemoryEXT)(VkDevice device, const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToImageEXT)(VkDevice device, const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo); -typedef VkResult (VKAPI_PTR *PFN_vkTransitionImageLayoutEXT)(VkDevice device, uint32_t transitionCount, const VkHostImageLayoutTransitionInfoEXT* pTransitions); -typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource, VkSubresourceLayout2KHR* pLayout); +typedef VkImageSubresource2 VkImageSubresource2EXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToImageEXT)(VkDevice device, const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToMemoryEXT)(VkDevice device, const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToImageEXT)(VkDevice device, const VkCopyImageToImageInfo* pCopyImageToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkTransitionImageLayoutEXT)(VkDevice device, uint32_t transitionCount, const VkHostImageLayoutTransitionInfo* pTransitions); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource, VkSubresourceLayout2* pLayout); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToImageEXT( VkDevice device, - const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo); + const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToMemoryEXT( VkDevice device, - const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo); + const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToImageEXT( VkDevice device, - const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo); + const VkCopyImageToImageInfo* pCopyImageToImageInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkTransitionImageLayoutEXT( VkDevice device, uint32_t transitionCount, - const VkHostImageLayoutTransitionInfoEXT* pTransitions); + const VkHostImageLayoutTransitionInfo* pTransitions); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT( VkDevice device, VkImage image, - const VkImageSubresource2KHR* pSubresource, - VkSubresourceLayout2KHR* pLayout); + const VkImageSubresource2* pSubresource, + VkSubresourceLayout2* pLayout); +#endif #endif @@ -15253,44 +19381,19 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { #define VK_EXT_surface_maintenance1 1 #define VK_EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION 1 #define VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME "VK_EXT_surface_maintenance1" +typedef VkPresentScalingFlagBitsKHR VkPresentScalingFlagBitsEXT; -typedef enum VkPresentScalingFlagBitsEXT { - VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT = 0x00000001, - VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT = 0x00000002, - VK_PRESENT_SCALING_STRETCH_BIT_EXT = 0x00000004, - VK_PRESENT_SCALING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPresentScalingFlagBitsEXT; -typedef VkFlags VkPresentScalingFlagsEXT; +typedef VkPresentScalingFlagsKHR VkPresentScalingFlagsEXT; -typedef enum VkPresentGravityFlagBitsEXT { - VK_PRESENT_GRAVITY_MIN_BIT_EXT = 0x00000001, - VK_PRESENT_GRAVITY_MAX_BIT_EXT = 0x00000002, - VK_PRESENT_GRAVITY_CENTERED_BIT_EXT = 0x00000004, - VK_PRESENT_GRAVITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPresentGravityFlagBitsEXT; -typedef VkFlags VkPresentGravityFlagsEXT; -typedef struct VkSurfacePresentModeEXT { - VkStructureType sType; - void* pNext; - VkPresentModeKHR presentMode; -} VkSurfacePresentModeEXT; +typedef VkPresentGravityFlagBitsKHR VkPresentGravityFlagBitsEXT; -typedef struct VkSurfacePresentScalingCapabilitiesEXT { - VkStructureType sType; - void* pNext; - VkPresentScalingFlagsEXT supportedPresentScaling; - VkPresentGravityFlagsEXT supportedPresentGravityX; - VkPresentGravityFlagsEXT supportedPresentGravityY; - VkExtent2D minScaledImageExtent; - VkExtent2D maxScaledImageExtent; -} VkSurfacePresentScalingCapabilitiesEXT; +typedef VkPresentGravityFlagsKHR VkPresentGravityFlagsEXT; -typedef struct VkSurfacePresentModeCompatibilityEXT { - VkStructureType sType; - void* pNext; - uint32_t presentModeCount; - VkPresentModeKHR* pPresentModes; -} VkSurfacePresentModeCompatibilityEXT; +typedef VkSurfacePresentModeKHR VkSurfacePresentModeEXT; + +typedef VkSurfacePresentScalingCapabilitiesKHR VkSurfacePresentScalingCapabilitiesEXT; + +typedef VkSurfacePresentModeCompatibilityKHR VkSurfacePresentModeCompatibilityEXT; @@ -15298,55 +19401,26 @@ typedef struct VkSurfacePresentModeCompatibilityEXT { #define VK_EXT_swapchain_maintenance1 1 #define VK_EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION 1 #define VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME "VK_EXT_swapchain_maintenance1" -typedef struct VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 swapchainMaintenance1; -} VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT; +typedef VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT; -typedef struct VkSwapchainPresentFenceInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkFence* pFences; -} VkSwapchainPresentFenceInfoEXT; +typedef VkSwapchainPresentFenceInfoKHR VkSwapchainPresentFenceInfoEXT; -typedef struct VkSwapchainPresentModesCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t presentModeCount; - const VkPresentModeKHR* pPresentModes; -} VkSwapchainPresentModesCreateInfoEXT; +typedef VkSwapchainPresentModesCreateInfoKHR VkSwapchainPresentModesCreateInfoEXT; -typedef struct VkSwapchainPresentModeInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkPresentModeKHR* pPresentModes; -} VkSwapchainPresentModeInfoEXT; +typedef VkSwapchainPresentModeInfoKHR VkSwapchainPresentModeInfoEXT; -typedef struct VkSwapchainPresentScalingCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPresentScalingFlagsEXT scalingBehavior; - VkPresentGravityFlagsEXT presentGravityX; - VkPresentGravityFlagsEXT presentGravityY; -} VkSwapchainPresentScalingCreateInfoEXT; +typedef VkSwapchainPresentScalingCreateInfoKHR VkSwapchainPresentScalingCreateInfoEXT; -typedef struct VkReleaseSwapchainImagesInfoEXT { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; - uint32_t imageIndexCount; - const uint32_t* pImageIndices; -} VkReleaseSwapchainImagesInfoEXT; +typedef VkReleaseSwapchainImagesInfoKHR VkReleaseSwapchainImagesInfoEXT; -typedef VkResult (VKAPI_PTR *PFN_vkReleaseSwapchainImagesEXT)(VkDevice device, const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo); +typedef VkResult (VKAPI_PTR *PFN_vkReleaseSwapchainImagesEXT)(VkDevice device, const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkReleaseSwapchainImagesEXT( VkDevice device, - const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo); + const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo); +#endif #endif @@ -15373,6 +19447,7 @@ typedef enum VkIndirectCommandsTokenTypeNV { VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_NV = 1000135000, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV = 1000328000, VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NV = 1000428003, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NV = 1000428004, @@ -15519,37 +19594,49 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice devi typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV( VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV( VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV( VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV( VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV( VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); #endif +#endif // VK_NV_inherited_viewport_scissor is a preprocessor guard. Do not pass it to API calls. @@ -15588,17 +19675,17 @@ typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBuff // VK_QCOM_render_pass_transform is a preprocessor guard. Do not pass it to API calls. #define VK_QCOM_render_pass_transform 1 -#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 4 +#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 5 #define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" typedef struct VkRenderPassTransformBeginInfoQCOM { VkStructureType sType; - void* pNext; + const void* pNext; VkSurfaceTransformFlagBitsKHR transform; } VkRenderPassTransformBeginInfoQCOM; typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM { VkStructureType sType; - void* pNext; + const void* pNext; VkSurfaceTransformFlagBitsKHR transform; VkRect2D renderArea; } VkCommandBufferInheritanceRenderPassTransformInfoQCOM; @@ -15643,10 +19730,12 @@ typedef struct VkDepthBiasRepresentationInfoEXT { typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias2EXT)(VkCommandBuffer commandBuffer, const VkDepthBiasInfoEXT* pDepthBiasInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias2EXT( VkCommandBuffer commandBuffer, const VkDepthBiasInfoEXT* pDepthBiasInfo); #endif +#endif // VK_EXT_device_memory_report is a preprocessor guard. Do not pass it to API calls. @@ -15703,37 +19792,30 @@ typedef VkResult (VKAPI_PTR *PFN_vkAcquireDrmDisplayEXT)(VkPhysicalDevice physic typedef VkResult (VKAPI_PTR *PFN_vkGetDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireDrmDisplayEXT( VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDrmDisplayEXT( VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display); #endif +#endif // VK_EXT_robustness2 is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_robustness2 1 #define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1 #define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2" -typedef struct VkPhysicalDeviceRobustness2FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 robustBufferAccess2; - VkBool32 robustImageAccess2; - VkBool32 nullDescriptor; -} VkPhysicalDeviceRobustness2FeaturesEXT; +typedef VkPhysicalDeviceRobustness2FeaturesKHR VkPhysicalDeviceRobustness2FeaturesEXT; -typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize robustStorageBufferAccessSizeAlignment; - VkDeviceSize robustUniformBufferAccessSizeAlignment; -} VkPhysicalDeviceRobustness2PropertiesEXT; +typedef VkPhysicalDeviceRobustness2PropertiesKHR VkPhysicalDeviceRobustness2PropertiesEXT; @@ -15741,13 +19823,6 @@ typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { #define VK_EXT_custom_border_color 1 #define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12 #define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color" -typedef struct VkSamplerCustomBorderColorCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkClearColorValue customBorderColor; - VkFormat format; -} VkSamplerCustomBorderColorCreateInfoEXT; - typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT { VkStructureType sType; void* pNext; @@ -15763,6 +19838,18 @@ typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { +// VK_EXT_texture_compression_astc_3d is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_texture_compression_astc_3d 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_3D_SPEC_VERSION 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_3D_EXTENSION_NAME "VK_EXT_texture_compression_astc_3d" +typedef struct VkPhysicalDeviceTextureCompressionASTC3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_3D; +} VkPhysicalDeviceTextureCompressionASTC3DFeaturesEXT; + + + // VK_GOOGLE_user_type is a preprocessor guard. Do not pass it to API calls. #define VK_GOOGLE_user_type 1 #define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1 @@ -15813,24 +19900,31 @@ typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectT typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( VkDevice device, VkObjectType objectType, @@ -15838,6 +19932,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( VkPrivateDataSlot privateDataSlot, uint64_t* pData); #endif +#endif // VK_EXT_pipeline_creation_cache_control is a preprocessor guard. Do not pass it to API calls. @@ -15881,95 +19976,181 @@ typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { #define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" -// VK_NV_cuda_kernel_launch is a preprocessor guard. Do not pass it to API calls. -#define VK_NV_cuda_kernel_launch 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaModuleNV) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaFunctionNV) -#define VK_NV_CUDA_KERNEL_LAUNCH_SPEC_VERSION 2 -#define VK_NV_CUDA_KERNEL_LAUNCH_EXTENSION_NAME "VK_NV_cuda_kernel_launch" -typedef struct VkCudaModuleCreateInfoNV { - VkStructureType sType; - const void* pNext; - size_t dataSize; - const void* pData; -} VkCudaModuleCreateInfoNV; +// VK_QCOM_queue_perf_hint is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_queue_perf_hint 1 +#define VK_QCOM_QUEUE_PERF_HINT_SPEC_VERSION 1 +#define VK_QCOM_QUEUE_PERF_HINT_EXTENSION_NAME "VK_QCOM_queue_perf_hint" -typedef struct VkCudaFunctionCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkCudaModuleNV module; - const char* pName; -} VkCudaFunctionCreateInfoNV; +typedef enum VkPerfHintTypeQCOM { + VK_PERF_HINT_TYPE_DEFAULT_QCOM = 0, + VK_PERF_HINT_TYPE_FREQUENCY_MIN_QCOM = 1, + VK_PERF_HINT_TYPE_FREQUENCY_MAX_QCOM = 2, + VK_PERF_HINT_TYPE_FREQUENCY_SCALED_QCOM = 3, + VK_PERF_HINT_TYPE_MAX_ENUM_QCOM = 0x7FFFFFFF +} VkPerfHintTypeQCOM; +typedef struct VkPerfHintInfoQCOM { + VkStructureType sType; + void* pNext; + VkPerfHintTypeQCOM type; + uint32_t scale; +} VkPerfHintInfoQCOM; -typedef struct VkCudaLaunchInfoNV { - VkStructureType sType; - const void* pNext; - VkCudaFunctionNV function; - uint32_t gridDimX; - uint32_t gridDimY; - uint32_t gridDimZ; - uint32_t blockDimX; - uint32_t blockDimY; - uint32_t blockDimZ; - uint32_t sharedMemBytes; - size_t paramCount; - const void* const * pParams; - size_t extraCount; - const void* const * pExtras; -} VkCudaLaunchInfoNV; - -typedef struct VkPhysicalDeviceCudaKernelLaunchFeaturesNV { +typedef struct VkPhysicalDeviceQueuePerfHintFeaturesQCOM { VkStructureType sType; void* pNext; - VkBool32 cudaKernelLaunchFeatures; -} VkPhysicalDeviceCudaKernelLaunchFeaturesNV; + VkBool32 queuePerfHint; +} VkPhysicalDeviceQueuePerfHintFeaturesQCOM; -typedef struct VkPhysicalDeviceCudaKernelLaunchPropertiesNV { +typedef struct VkPhysicalDeviceQueuePerfHintPropertiesQCOM { VkStructureType sType; void* pNext; - uint32_t computeCapabilityMinor; - uint32_t computeCapabilityMajor; -} VkPhysicalDeviceCudaKernelLaunchPropertiesNV; + VkQueueFlags supportedQueues; +} VkPhysicalDeviceQueuePerfHintPropertiesQCOM; -typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaModuleNV)(VkDevice device, const VkCudaModuleCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaModuleNV* pModule); -typedef VkResult (VKAPI_PTR *PFN_vkGetCudaModuleCacheNV)(VkDevice device, VkCudaModuleNV module, size_t* pCacheSize, void* pCacheData); -typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaFunctionNV)(VkDevice device, const VkCudaFunctionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaFunctionNV* pFunction); -typedef void (VKAPI_PTR *PFN_vkDestroyCudaModuleNV)(VkDevice device, VkCudaModuleNV module, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkDestroyCudaFunctionNV)(VkDevice device, VkCudaFunctionNV function, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkCmdCudaLaunchKernelNV)(VkCommandBuffer commandBuffer, const VkCudaLaunchInfoNV* pLaunchInfo); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSetPerfHintQCOM)(VkQueue queue, const VkPerfHintInfoQCOM* pPerfHintInfo); #ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaModuleNV( - VkDevice device, - const VkCudaModuleCreateInfoNV* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCudaModuleNV* pModule); +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSetPerfHintQCOM( + VkQueue queue, + const VkPerfHintInfoQCOM* pPerfHintInfo); +#endif +#endif -VKAPI_ATTR VkResult VKAPI_CALL vkGetCudaModuleCacheNV( - VkDevice device, - VkCudaModuleNV module, - size_t* pCacheSize, - void* pCacheData); -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaFunctionNV( - VkDevice device, - const VkCudaFunctionCreateInfoNV* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCudaFunctionNV* pFunction); +// VK_QCOM_image_processing3 is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_image_processing3 1 +#define VK_QCOM_IMAGE_PROCESSING_3_SPEC_VERSION 1 +#define VK_QCOM_IMAGE_PROCESSING_3_EXTENSION_NAME "VK_QCOM_image_processing3" +typedef struct VkPhysicalDeviceImageProcessing3FeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 imageGatherLinear; + VkBool32 imageGatherExtendedModes; + VkBool32 blockMatchExtendedClampToEdge; +} VkPhysicalDeviceImageProcessing3FeaturesQCOM; -VKAPI_ATTR void VKAPI_CALL vkDestroyCudaModuleNV( - VkDevice device, - VkCudaModuleNV module, - const VkAllocationCallbacks* pAllocator); -VKAPI_ATTR void VKAPI_CALL vkDestroyCudaFunctionNV( - VkDevice device, - VkCudaFunctionNV function, - const VkAllocationCallbacks* pAllocator); -VKAPI_ATTR void VKAPI_CALL vkCmdCudaLaunchKernelNV( +// VK_QCOM_shader_multiple_wait_queues is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_shader_multiple_wait_queues 1 +#define VK_QCOM_SHADER_MULTIPLE_WAIT_QUEUES_SPEC_VERSION 1 +#define VK_QCOM_SHADER_MULTIPLE_WAIT_QUEUES_EXTENSION_NAME "VK_QCOM_shader_multiple_wait_queues" +typedef struct VkPhysicalDeviceShaderMultipleWaitQueuesFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 shaderMultipleWaitQueues; +} VkPhysicalDeviceShaderMultipleWaitQueuesFeaturesQCOM; + +typedef struct VkPhysicalDeviceShaderMultipleWaitQueuesPropertiesQCOM { + VkStructureType sType; + void* pNext; + uint32_t maxShaderWaitQueues; +} VkPhysicalDeviceShaderMultipleWaitQueuesPropertiesQCOM; + + + +// VK_EXT_shader_split_barrier is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_split_barrier 1 +#define VK_EXT_SHADER_SPLIT_BARRIER_SPEC_VERSION 1 +#define VK_EXT_SHADER_SPLIT_BARRIER_EXTENSION_NAME "VK_EXT_shader_split_barrier" +typedef struct VkPhysicalDeviceShaderSplitBarrierFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderSplitBarrier; +} VkPhysicalDeviceShaderSplitBarrierFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderSplitBarrierPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t splitBarrierReservedSharedMemory; +} VkPhysicalDeviceShaderSplitBarrierPropertiesEXT; + + + +// VK_QCOM_tile_shading is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_tile_shading 1 +#define VK_QCOM_TILE_SHADING_SPEC_VERSION 2 +#define VK_QCOM_TILE_SHADING_EXTENSION_NAME "VK_QCOM_tile_shading" + +typedef enum VkTileShadingRenderPassFlagBitsQCOM { + VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM = 0x00000001, + VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM = 0x00000002, + VK_TILE_SHADING_RENDER_PASS_FLAG_BITS_MAX_ENUM_QCOM = 0x7FFFFFFF +} VkTileShadingRenderPassFlagBitsQCOM; +typedef VkFlags VkTileShadingRenderPassFlagsQCOM; +typedef struct VkPhysicalDeviceTileShadingFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 tileShading; + VkBool32 tileShadingFragmentStage; + VkBool32 tileShadingColorAttachments; + VkBool32 tileShadingDepthAttachments; + VkBool32 tileShadingStencilAttachments; + VkBool32 tileShadingInputAttachments; + VkBool32 tileShadingSampledAttachments; + VkBool32 tileShadingPerTileDraw; + VkBool32 tileShadingPerTileDispatch; + VkBool32 tileShadingDispatchTile; + VkBool32 tileShadingApron; + VkBool32 tileShadingAnisotropicApron; + VkBool32 tileShadingAtomicOps; + VkBool32 tileShadingImageProcessing; +} VkPhysicalDeviceTileShadingFeaturesQCOM; + +typedef struct VkPhysicalDeviceTileShadingPropertiesQCOM { + VkStructureType sType; + void* pNext; + uint32_t maxApronSize; + VkBool32 preferNonCoherent; + VkExtent2D tileGranularity; + VkExtent2D maxTileShadingRate; +} VkPhysicalDeviceTileShadingPropertiesQCOM; + +typedef struct VkRenderPassTileShadingCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + VkTileShadingRenderPassFlagsQCOM flags; + VkExtent2D tileApronSize; +} VkRenderPassTileShadingCreateInfoQCOM; + +typedef struct VkPerTileBeginInfoQCOM { + VkStructureType sType; + const void* pNext; +} VkPerTileBeginInfoQCOM; + +typedef struct VkPerTileEndInfoQCOM { + VkStructureType sType; + const void* pNext; +} VkPerTileEndInfoQCOM; + +typedef struct VkDispatchTileInfoQCOM { + VkStructureType sType; + const void* pNext; +} VkDispatchTileInfoQCOM; + +typedef void (VKAPI_PTR *PFN_vkCmdDispatchTileQCOM)(VkCommandBuffer commandBuffer, const VkDispatchTileInfoQCOM* pDispatchTileInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginPerTileExecutionQCOM)(VkCommandBuffer commandBuffer, const VkPerTileBeginInfoQCOM* pPerTileBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndPerTileExecutionQCOM)(VkCommandBuffer commandBuffer, const VkPerTileEndInfoQCOM* pPerTileEndInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchTileQCOM( VkCommandBuffer commandBuffer, - const VkCudaLaunchInfoNV* pLaunchInfo); + const VkDispatchTileInfoQCOM* pDispatchTileInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginPerTileExecutionQCOM( + VkCommandBuffer commandBuffer, + const VkPerTileBeginInfoQCOM* pPerTileBeginInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndPerTileExecutionQCOM( + VkCommandBuffer commandBuffer, + const VkPerTileEndInfoQCOM* pPerTileEndInfo); +#endif #endif @@ -15987,7 +20168,6 @@ typedef struct VkQueryLowLatencySupportNV { // VK_EXT_descriptor_buffer is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_descriptor_buffer 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) #define VK_EXT_DESCRIPTOR_BUFFER_SPEC_VERSION 1 #define VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME "VK_EXT_descriptor_buffer" typedef struct VkPhysicalDeviceDescriptorBufferPropertiesEXT { @@ -16028,12 +20208,6 @@ typedef struct VkPhysicalDeviceDescriptorBufferPropertiesEXT { VkDeviceSize descriptorBufferAddressSpaceSize; } VkPhysicalDeviceDescriptorBufferPropertiesEXT; -typedef struct VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT { - VkStructureType sType; - void* pNext; - size_t combinedImageSamplerDensityMapDescriptorSize; -} VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT; - typedef struct VkPhysicalDeviceDescriptorBufferFeaturesEXT { VkStructureType sType; void* pNext; @@ -16053,14 +20227,14 @@ typedef struct VkDescriptorAddressInfoEXT { typedef struct VkDescriptorBufferBindingInfoEXT { VkStructureType sType; - void* pNext; + const void* pNext; VkDeviceAddress address; VkBufferUsageFlags usage; } VkDescriptorBufferBindingInfoEXT; typedef struct VkDescriptorBufferBindingPushDescriptorBufferHandleEXT { VkStructureType sType; - void* pNext; + const void* pNext; VkBuffer buffer; } VkDescriptorBufferBindingPushDescriptorBufferHandleEXT; @@ -16121,6 +20295,12 @@ typedef struct VkAccelerationStructureCaptureDescriptorDataInfoEXT { VkAccelerationStructureNV accelerationStructureNV; } VkAccelerationStructureCaptureDescriptorDataInfoEXT; +typedef struct VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT { + VkStructureType sType; + void* pNext; + size_t combinedImageSamplerDensityMapDescriptorSize; +} VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT; + typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSizeEXT)(VkDevice device, VkDescriptorSetLayout layout, VkDeviceSize* pLayoutSizeInBytes); typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutBindingOffsetEXT)(VkDevice device, VkDescriptorSetLayout layout, uint32_t binding, VkDeviceSize* pOffset); typedef void (VKAPI_PTR *PFN_vkGetDescriptorEXT)(VkDevice device, const VkDescriptorGetInfoEXT* pDescriptorInfo, size_t dataSize, void* pDescriptor); @@ -16134,28 +20314,37 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetSamplerOpaqueCaptureDescriptorDataEXT)(VkD typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo, void* pData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSizeEXT( VkDevice device, VkDescriptorSetLayout layout, VkDeviceSize* pLayoutSizeInBytes); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutBindingOffsetEXT( VkDevice device, VkDescriptorSetLayout layout, uint32_t binding, VkDeviceSize* pOffset); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorEXT( VkDevice device, const VkDescriptorGetInfoEXT* pDescriptorInfo, size_t dataSize, void* pDescriptor); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBuffersEXT( VkCommandBuffer commandBuffer, uint32_t bufferCount, const VkDescriptorBufferBindingInfoEXT* pBindingInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDescriptorBufferOffsetsEXT( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, @@ -16164,38 +20353,51 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetDescriptorBufferOffsetsEXT( uint32_t setCount, const uint32_t* pBufferIndices, const VkDeviceSize* pOffsets); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBufferEmbeddedSamplersEXT( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferOpaqueCaptureDescriptorDataEXT( VkDevice device, const VkBufferCaptureDescriptorDataInfoEXT* pInfo, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetImageOpaqueCaptureDescriptorDataEXT( VkDevice device, const VkImageCaptureDescriptorDataInfoEXT* pInfo, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewOpaqueCaptureDescriptorDataEXT( VkDevice device, const VkImageViewCaptureDescriptorDataInfoEXT* pInfo, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSamplerOpaqueCaptureDescriptorDataEXT( VkDevice device, const VkSamplerCaptureDescriptorDataInfoEXT* pInfo, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT( VkDevice device, const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo, void* pData); #endif +#endif // VK_EXT_graphics_pipeline_library is a preprocessor guard. Do not pass it to API calls. @@ -16295,11 +20497,13 @@ typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV { typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateEnumNV)(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateEnumNV( VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); #endif +#endif // VK_NV_ray_tracing_motion_blur is a preprocessor guard. Do not pass it to API calls. @@ -16541,22 +20745,10 @@ typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { #define VK_EXT_device_fault 1 #define VK_EXT_DEVICE_FAULT_SPEC_VERSION 2 #define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault" +typedef VkDeviceFaultAddressTypeKHR VkDeviceFaultAddressTypeEXT; -typedef enum VkDeviceFaultAddressTypeEXT { - VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = 0, - VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = 1, - VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = 2, - VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = 3, - VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = 4, - VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = 5, - VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6, - VK_DEVICE_FAULT_ADDRESS_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDeviceFaultAddressTypeEXT; +typedef VkDeviceFaultVendorBinaryHeaderVersionKHR VkDeviceFaultVendorBinaryHeaderVersionEXT; -typedef enum VkDeviceFaultVendorBinaryHeaderVersionEXT { - VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT = 1, - VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDeviceFaultVendorBinaryHeaderVersionEXT; typedef struct VkPhysicalDeviceFaultFeaturesEXT { VkStructureType sType; void* pNext; @@ -16572,49 +20764,31 @@ typedef struct VkDeviceFaultCountsEXT { VkDeviceSize vendorBinarySize; } VkDeviceFaultCountsEXT; -typedef struct VkDeviceFaultAddressInfoEXT { - VkDeviceFaultAddressTypeEXT addressType; - VkDeviceAddress reportedAddress; - VkDeviceSize addressPrecision; -} VkDeviceFaultAddressInfoEXT; - -typedef struct VkDeviceFaultVendorInfoEXT { - char description[VK_MAX_DESCRIPTION_SIZE]; - uint64_t vendorFaultCode; - uint64_t vendorFaultData; -} VkDeviceFaultVendorInfoEXT; - typedef struct VkDeviceFaultInfoEXT { VkStructureType sType; void* pNext; char description[VK_MAX_DESCRIPTION_SIZE]; - VkDeviceFaultAddressInfoEXT* pAddressInfos; - VkDeviceFaultVendorInfoEXT* pVendorInfos; + VkDeviceFaultAddressInfoKHR* pAddressInfos; + VkDeviceFaultVendorInfoKHR* pVendorInfos; void* pVendorBinaryData; } VkDeviceFaultInfoEXT; -typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneEXT { - uint32_t headerSize; - VkDeviceFaultVendorBinaryHeaderVersionEXT headerVersion; - uint32_t vendorID; - uint32_t deviceID; - uint32_t driverVersion; - uint8_t pipelineCacheUUID[VK_UUID_SIZE]; - uint32_t applicationNameOffset; - uint32_t applicationVersion; - uint32_t engineNameOffset; - uint32_t engineVersion; - uint32_t apiVersion; -} VkDeviceFaultVendorBinaryHeaderVersionOneEXT; +typedef VkDeviceFaultAddressInfoKHR VkDeviceFaultAddressInfoEXT; + +typedef VkDeviceFaultVendorInfoKHR VkDeviceFaultVendorInfoEXT; + +typedef VkDeviceFaultVendorBinaryHeaderVersionOneKHR VkDeviceFaultVendorBinaryHeaderVersionOneEXT; typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultInfoEXT)(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultInfoEXT( VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo); #endif +#endif // VK_ARM_rasterization_order_attachment_access is a preprocessor guard. Do not pass it to API calls. @@ -16706,6 +20880,7 @@ typedef struct VkVertexInputAttributeDescription2EXT { typedef void (VKAPI_PTR *PFN_vkCmdSetVertexInputEXT)(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT( VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, @@ -16713,6 +20888,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT( uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); #endif +#endif // VK_EXT_physical_device_drm is a preprocessor guard. Do not pass it to API calls. @@ -16796,6 +20972,14 @@ typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT { +// VK_EXT_present_mode_fifo_latest_ready is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_present_mode_fifo_latest_ready 1 +#define VK_EXT_PRESENT_MODE_FIFO_LATEST_READY_SPEC_VERSION 1 +#define VK_EXT_PRESENT_MODE_FIFO_LATEST_READY_EXTENSION_NAME "VK_EXT_present_mode_fifo_latest_ready" +typedef VkPhysicalDevicePresentModeFifoLatestReadyFeaturesKHR VkPhysicalDevicePresentModeFifoLatestReadyFeaturesEXT; + + + // VK_HUAWEI_subpass_shading is a preprocessor guard. Do not pass it to API calls. #define VK_HUAWEI_subpass_shading 1 #define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 3 @@ -16823,14 +21007,18 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI( VkCommandBuffer commandBuffer); #endif +#endif // VK_HUAWEI_invocation_mask is a preprocessor guard. Do not pass it to API calls. @@ -16846,11 +21034,13 @@ typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI { typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI( VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); #endif +#endif // VK_NV_external_memory_rdma is a preprocessor guard. Do not pass it to API calls. @@ -16874,11 +21064,13 @@ typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV { typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV( VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress); #endif +#endif // VK_EXT_pipeline_properties is a preprocessor guard. Do not pass it to API calls. @@ -16899,14 +21091,16 @@ typedef struct VkPhysicalDevicePipelinePropertiesFeaturesEXT { VkBool32 pipelinePropertiesIdentifier; } VkPhysicalDevicePipelinePropertiesFeaturesEXT; -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT( VkDevice device, - const VkPipelineInfoEXT* pPipelineInfo, + const VkPipelineInfoKHR* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); #endif +#endif // VK_EXT_frame_boundary is a preprocessor guard. Do not pass it to API calls. @@ -16985,26 +21179,36 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEXT)(VkCommandBuffer commandBuffer, typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetPatchControlPointsEXT( VkCommandBuffer commandBuffer, uint32_t patchControlPoints); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnableEXT( VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEXT( VkCommandBuffer commandBuffer, VkLogicOp logicOp); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnableEXT( VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); #endif +#endif // VK_EXT_color_write_enable is a preprocessor guard. Do not pass it to API calls. @@ -17024,14 +21228,16 @@ typedef struct VkPipelineColorWriteCreateInfoEXT { const VkBool32* pColorWriteEnables; } VkPipelineColorWriteCreateInfoEXT; -typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); +typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); #ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT( +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT( VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); #endif +#endif // VK_EXT_primitives_generated_query is a preprocessor guard. Do not pass it to API calls. @@ -17052,10 +21258,70 @@ typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { #define VK_EXT_global_priority_query 1 #define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 #define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" -#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR -typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE +typedef VkPhysicalDeviceGlobalPriorityQueryFeatures VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; -typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; +typedef VkQueueFamilyGlobalPriorityProperties VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +// VK_VALVE_video_encode_rgb_conversion is a preprocessor guard. Do not pass it to API calls. +#define VK_VALVE_video_encode_rgb_conversion 1 +#define VK_VALVE_VIDEO_ENCODE_RGB_CONVERSION_SPEC_VERSION 1 +#define VK_VALVE_VIDEO_ENCODE_RGB_CONVERSION_EXTENSION_NAME "VK_VALVE_video_encode_rgb_conversion" + +typedef enum VkVideoEncodeRgbModelConversionFlagBitsVALVE { + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_RGB_IDENTITY_BIT_VALVE = 0x00000001, + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_IDENTITY_BIT_VALVE = 0x00000002, + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_709_BIT_VALVE = 0x00000004, + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_601_BIT_VALVE = 0x00000008, + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_2020_BIT_VALVE = 0x00000010, + VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_FLAG_BITS_MAX_ENUM_VALVE = 0x7FFFFFFF +} VkVideoEncodeRgbModelConversionFlagBitsVALVE; +typedef VkFlags VkVideoEncodeRgbModelConversionFlagsVALVE; + +typedef enum VkVideoEncodeRgbRangeCompressionFlagBitsVALVE { + VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_FULL_RANGE_BIT_VALVE = 0x00000001, + VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_NARROW_RANGE_BIT_VALVE = 0x00000002, + VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_FLAG_BITS_MAX_ENUM_VALVE = 0x7FFFFFFF +} VkVideoEncodeRgbRangeCompressionFlagBitsVALVE; +typedef VkFlags VkVideoEncodeRgbRangeCompressionFlagsVALVE; + +typedef enum VkVideoEncodeRgbChromaOffsetFlagBitsVALVE { + VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_COSITED_EVEN_BIT_VALVE = 0x00000001, + VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_MIDPOINT_BIT_VALVE = 0x00000002, + VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_FLAG_BITS_MAX_ENUM_VALVE = 0x7FFFFFFF +} VkVideoEncodeRgbChromaOffsetFlagBitsVALVE; +typedef VkFlags VkVideoEncodeRgbChromaOffsetFlagsVALVE; +typedef struct VkPhysicalDeviceVideoEncodeRgbConversionFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 videoEncodeRgbConversion; +} VkPhysicalDeviceVideoEncodeRgbConversionFeaturesVALVE; + +typedef struct VkVideoEncodeRgbConversionCapabilitiesVALVE { + VkStructureType sType; + void* pNext; + VkVideoEncodeRgbModelConversionFlagsVALVE rgbModels; + VkVideoEncodeRgbRangeCompressionFlagsVALVE rgbRanges; + VkVideoEncodeRgbChromaOffsetFlagsVALVE xChromaOffsets; + VkVideoEncodeRgbChromaOffsetFlagsVALVE yChromaOffsets; +} VkVideoEncodeRgbConversionCapabilitiesVALVE; + +typedef struct VkVideoEncodeProfileRgbConversionInfoVALVE { + VkStructureType sType; + const void* pNext; + VkBool32 performEncodeRgbConversion; +} VkVideoEncodeProfileRgbConversionInfoVALVE; + +typedef struct VkVideoEncodeSessionRgbConversionCreateInfoVALVE { + VkStructureType sType; + const void* pNext; + VkVideoEncodeRgbModelConversionFlagBitsVALVE rgbModel; + VkVideoEncodeRgbRangeCompressionFlagBitsVALVE rgbRange; + VkVideoEncodeRgbChromaOffsetFlagBitsVALVE xChromaOffset; + VkVideoEncodeRgbChromaOffsetFlagBitsVALVE yChromaOffset; +} VkVideoEncodeSessionRgbConversionCreateInfoVALVE; @@ -17108,6 +21374,7 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiEXT)(VkCommandBuffer commandBuffer, u typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiIndexedEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT( VkCommandBuffer commandBuffer, uint32_t drawCount, @@ -17115,7 +21382,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT( uint32_t instanceCount, uint32_t firstInstance, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( VkCommandBuffer commandBuffer, uint32_t drawCount, @@ -17125,6 +21394,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( uint32_t stride, const int32_t* pVertexOffset); #endif +#endif // VK_EXT_image_2d_view_of_3d is a preprocessor guard. Do not pass it to API calls. @@ -17188,20 +21458,10 @@ typedef enum VkCopyMicromapModeEXT { VK_COPY_MICROMAP_MODE_COMPACT_EXT = 3, VK_COPY_MICROMAP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkCopyMicromapModeEXT; +typedef VkOpacityMicromapFormatKHR VkOpacityMicromapFormatEXT; -typedef enum VkOpacityMicromapFormatEXT { - VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT = 1, - VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT = 2, - VK_OPACITY_MICROMAP_FORMAT_MAX_ENUM_EXT = 0x7FFFFFFF -} VkOpacityMicromapFormatEXT; +typedef VkOpacityMicromapSpecialIndexKHR VkOpacityMicromapSpecialIndexEXT; -typedef enum VkOpacityMicromapSpecialIndexEXT { - VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT = -1, - VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT = -2, - VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT = -3, - VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT = -4, - VK_OPACITY_MICROMAP_SPECIAL_INDEX_MAX_ENUM_EXT = 0x7FFFFFFF -} VkOpacityMicromapSpecialIndexEXT; typedef enum VkAccelerationStructureCompatibilityKHR { VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0, @@ -17333,65 +21593,76 @@ typedef struct VkAccelerationStructureTrianglesOpacityMicromapEXT { VkMicromapEXT micromap; } VkAccelerationStructureTrianglesOpacityMicromapEXT; -typedef struct VkMicromapTriangleEXT { - uint32_t dataOffset; - uint16_t subdivisionLevel; - uint16_t format; -} VkMicromapTriangleEXT; +typedef VkMicromapTriangleKHR VkMicromapTriangleEXT; -typedef VkResult (VKAPI_PTR *PFN_vkCreateMicromapEXT)(VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap); -typedef void (VKAPI_PTR *PFN_vkDestroyMicromapEXT)(VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkCmdBuildMicromapsEXT)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); -typedef VkResult (VKAPI_PTR *PFN_vkBuildMicromapsEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); -typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapToMemoryEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapToMemoryInfoEXT* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToMicromapInfoEXT* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkWriteMicromapsPropertiesEXT)(VkDevice device, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapToMemoryEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteMicromapsPropertiesEXT)(VkCommandBuffer commandBuffer, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); -typedef void (VKAPI_PTR *PFN_vkGetDeviceMicromapCompatibilityEXT)(VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); -typedef void (VKAPI_PTR *PFN_vkGetMicromapBuildSizesEXT)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkMicromapBuildInfoEXT* pBuildInfo, VkMicromapBuildSizesInfoEXT* pSizeInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateMicromapEXT)(VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap); +typedef void (VKAPI_PTR *PFN_vkDestroyMicromapEXT)(VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBuildMicromapsEXT)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBuildMicromapsEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapToMemoryEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapToMemoryInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToMicromapInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkWriteMicromapsPropertiesEXT)(VkDevice device, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapToMemoryEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteMicromapsPropertiesEXT)(VkCommandBuffer commandBuffer, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMicromapCompatibilityEXT)(VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +typedef void (VKAPI_PTR *PFN_vkGetMicromapBuildSizesEXT)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkMicromapBuildInfoEXT* pBuildInfo, VkMicromapBuildSizesInfoEXT* pSizeInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateMicromapEXT( VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyMicromapEXT( VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBuildMicromapsEXT( VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBuildMicromapsEXT( VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapEXT( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapToMemoryEXT( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapToMemoryInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToMicromapEXT( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToMicromapInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT( VkDevice device, uint32_t micromapCount, @@ -17400,19 +21671,27 @@ VKAPI_ATTR VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT( size_t dataSize, void* pData, size_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapEXT( VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapToMemoryEXT( VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToMicromapEXT( VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWriteMicromapsPropertiesEXT( VkCommandBuffer commandBuffer, uint32_t micromapCount, @@ -17420,18 +21699,23 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteMicromapsPropertiesEXT( VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceMicromapCompatibilityEXT( VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetMicromapBuildSizesEXT( VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkMicromapBuildInfoEXT* pBuildInfo, VkMicromapBuildSizesInfoEXT* pSizeInfo); #endif +#endif // VK_EXT_load_store_op_none is a preprocessor guard. Do not pass it to API calls. @@ -17470,17 +21754,21 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterHUAWEI)(VkCommandBuffer commandBuff typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterIndirectHUAWEI)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterHUAWEI( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterIndirectHUAWEI( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); #endif +#endif // VK_EXT_border_color_swizzle is a preprocessor guard. Do not pass it to API calls. @@ -17516,11 +21804,13 @@ typedef struct VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT { typedef void (VKAPI_PTR *PFN_vkSetDeviceMemoryPriorityEXT)(VkDevice device, VkDeviceMemory memory, float priority); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( VkDevice device, VkDeviceMemory memory, float priority); #endif +#endif // VK_ARM_shader_core_properties is a preprocessor guard. Do not pass it to API calls. @@ -17539,13 +21829,14 @@ typedef struct VkPhysicalDeviceShaderCorePropertiesARM { // VK_ARM_scheduling_controls is a preprocessor guard. Do not pass it to API calls. #define VK_ARM_scheduling_controls 1 -#define VK_ARM_SCHEDULING_CONTROLS_SPEC_VERSION 1 +#define VK_ARM_SCHEDULING_CONTROLS_SPEC_VERSION 2 #define VK_ARM_SCHEDULING_CONTROLS_EXTENSION_NAME "VK_ARM_scheduling_controls" typedef VkFlags64 VkPhysicalDeviceSchedulingControlsFlagsARM; // Flag bits for VkPhysicalDeviceSchedulingControlsFlagBitsARM typedef VkFlags64 VkPhysicalDeviceSchedulingControlsFlagBitsARM; static const VkPhysicalDeviceSchedulingControlsFlagBitsARM VK_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_SHADER_CORE_COUNT_ARM = 0x00000001ULL; +static const VkPhysicalDeviceSchedulingControlsFlagBitsARM VK_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_DISPATCH_PARAMETERS_ARM = 0x00000002ULL; typedef struct VkDeviceQueueShaderCoreControlCreateInfoARM { VkStructureType sType; @@ -17565,6 +21856,31 @@ typedef struct VkPhysicalDeviceSchedulingControlsPropertiesARM { VkPhysicalDeviceSchedulingControlsFlagsARM schedulingControlsFlags; } VkPhysicalDeviceSchedulingControlsPropertiesARM; +typedef struct VkDispatchParametersARM { + VkStructureType sType; + void* pNext; + uint32_t workGroupBatchSize; + uint32_t maxQueuedWorkGroupBatches; + uint32_t maxWarpsPerShaderCore; +} VkDispatchParametersARM; + +typedef struct VkPhysicalDeviceSchedulingControlsDispatchParametersPropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t schedulingControlsMaxWarpsCount; + uint32_t schedulingControlsMaxQueuedBatchesCount; + uint32_t schedulingControlsMaxWorkGroupBatchSize; +} VkPhysicalDeviceSchedulingControlsDispatchParametersPropertiesARM; + +typedef void (VKAPI_PTR *PFN_vkCmdSetDispatchParametersARM)(VkCommandBuffer commandBuffer, const VkDispatchParametersARM* pDispatchParameters); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetDispatchParametersARM( + VkCommandBuffer commandBuffer, + const VkDispatchParametersARM* pDispatchParameters); +#endif +#endif // VK_EXT_image_sliced_view_of_3d is a preprocessor guard. Do not pass it to API calls. @@ -17615,27 +21931,27 @@ typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDev typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( VkDevice device, VkDescriptorSet descriptorSet, void** ppData); #endif +#endif // VK_EXT_depth_clamp_zero_one is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_depth_clamp_zero_one 1 #define VK_EXT_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION 1 #define VK_EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME "VK_EXT_depth_clamp_zero_one" -typedef struct VkPhysicalDeviceDepthClampZeroOneFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 depthClampZeroOne; -} VkPhysicalDeviceDepthClampZeroOneFeaturesEXT; +typedef VkPhysicalDeviceDepthClampZeroOneFeaturesKHR VkPhysicalDeviceDepthClampZeroOneFeaturesEXT; @@ -17692,26 +22008,32 @@ typedef struct VkRenderPassStripeSubmitInfoARM { // VK_QCOM_fragment_density_map_offset is a preprocessor guard. Do not pass it to API calls. #define VK_QCOM_fragment_density_map_offset 1 -#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 3 #define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" -typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT { VkStructureType sType; void* pNext; VkBool32 fragmentDensityMapOffset; -} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; +} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT; -typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { +typedef VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; + +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT { VkStructureType sType; void* pNext; VkExtent2D fragmentDensityOffsetGranularity; -} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; +} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT; -typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { +typedef VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; + +typedef struct VkRenderPassFragmentDensityMapOffsetEndInfoEXT { VkStructureType sType; const void* pNext; uint32_t fragmentDensityOffsetCount; const VkOffset2D* pFragmentDensityOffsets; -} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; +} VkRenderPassFragmentDensityMapOffsetEndInfoEXT; + +typedef VkRenderPassFragmentDensityMapOffsetEndInfoEXT VkSubpassFragmentDensityMapOffsetEndInfoQCOM; @@ -17719,20 +22041,9 @@ typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { #define VK_NV_copy_memory_indirect 1 #define VK_NV_COPY_MEMORY_INDIRECT_SPEC_VERSION 1 #define VK_NV_COPY_MEMORY_INDIRECT_EXTENSION_NAME "VK_NV_copy_memory_indirect" -typedef struct VkCopyMemoryIndirectCommandNV { - VkDeviceAddress srcAddress; - VkDeviceAddress dstAddress; - VkDeviceSize size; -} VkCopyMemoryIndirectCommandNV; +typedef VkCopyMemoryIndirectCommandKHR VkCopyMemoryIndirectCommandNV; -typedef struct VkCopyMemoryToImageIndirectCommandNV { - VkDeviceAddress srcAddress; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkCopyMemoryToImageIndirectCommandNV; +typedef VkCopyMemoryToImageIndirectCommandKHR VkCopyMemoryToImageIndirectCommandNV; typedef struct VkPhysicalDeviceCopyMemoryIndirectFeaturesNV { VkStructureType sType; @@ -17740,22 +22051,21 @@ typedef struct VkPhysicalDeviceCopyMemoryIndirectFeaturesNV { VkBool32 indirectCopy; } VkPhysicalDeviceCopyMemoryIndirectFeaturesNV; -typedef struct VkPhysicalDeviceCopyMemoryIndirectPropertiesNV { - VkStructureType sType; - void* pNext; - VkQueueFlags supportedQueues; -} VkPhysicalDeviceCopyMemoryIndirectPropertiesNV; +typedef VkPhysicalDeviceCopyMemoryIndirectPropertiesKHR VkPhysicalDeviceCopyMemoryIndirectPropertiesNV; typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryIndirectNV)(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, uint32_t copyCount, uint32_t stride); typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToImageIndirectNV)(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, uint32_t copyCount, uint32_t stride, VkImage dstImage, VkImageLayout dstImageLayout, const VkImageSubresourceLayers* pImageSubresources); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryIndirectNV( VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, uint32_t copyCount, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageIndirectNV( VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, @@ -17765,6 +22075,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageIndirectNV( VkImageLayout dstImageLayout, const VkImageSubresourceLayers* pImageSubresources); #endif +#endif // VK_NV_memory_decompression is a preprocessor guard. Do not pass it to API calls. @@ -17772,47 +22083,60 @@ VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageIndirectNV( #define VK_NV_MEMORY_DECOMPRESSION_SPEC_VERSION 1 #define VK_NV_MEMORY_DECOMPRESSION_EXTENSION_NAME "VK_NV_memory_decompression" -// Flag bits for VkMemoryDecompressionMethodFlagBitsNV -typedef VkFlags64 VkMemoryDecompressionMethodFlagBitsNV; -static const VkMemoryDecompressionMethodFlagBitsNV VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_NV = 0x00000001ULL; +// Flag bits for VkMemoryDecompressionMethodFlagBitsEXT +typedef VkFlags64 VkMemoryDecompressionMethodFlagBitsEXT; +static const VkMemoryDecompressionMethodFlagBitsEXT VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT = 0x00000001ULL; +static const VkMemoryDecompressionMethodFlagBitsEXT VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_NV = 0x00000001ULL; + +typedef VkMemoryDecompressionMethodFlagBitsEXT VkMemoryDecompressionMethodFlagBitsNV; + +typedef VkFlags64 VkMemoryDecompressionMethodFlagsEXT; +typedef VkMemoryDecompressionMethodFlagsEXT VkMemoryDecompressionMethodFlagsNV; -typedef VkFlags64 VkMemoryDecompressionMethodFlagsNV; typedef struct VkDecompressMemoryRegionNV { - VkDeviceAddress srcAddress; - VkDeviceAddress dstAddress; - VkDeviceSize compressedSize; - VkDeviceSize decompressedSize; - VkMemoryDecompressionMethodFlagsNV decompressionMethod; + VkDeviceAddress srcAddress; + VkDeviceAddress dstAddress; + VkDeviceSize compressedSize; + VkDeviceSize decompressedSize; + VkMemoryDecompressionMethodFlagsEXT decompressionMethod; } VkDecompressMemoryRegionNV; -typedef struct VkPhysicalDeviceMemoryDecompressionFeaturesNV { +typedef struct VkPhysicalDeviceMemoryDecompressionFeaturesEXT { VkStructureType sType; void* pNext; VkBool32 memoryDecompression; -} VkPhysicalDeviceMemoryDecompressionFeaturesNV; +} VkPhysicalDeviceMemoryDecompressionFeaturesEXT; -typedef struct VkPhysicalDeviceMemoryDecompressionPropertiesNV { - VkStructureType sType; - void* pNext; - VkMemoryDecompressionMethodFlagsNV decompressionMethods; - uint64_t maxDecompressionIndirectCount; -} VkPhysicalDeviceMemoryDecompressionPropertiesNV; +typedef VkPhysicalDeviceMemoryDecompressionFeaturesEXT VkPhysicalDeviceMemoryDecompressionFeaturesNV; + +typedef struct VkPhysicalDeviceMemoryDecompressionPropertiesEXT { + VkStructureType sType; + void* pNext; + VkMemoryDecompressionMethodFlagsEXT decompressionMethods; + uint64_t maxDecompressionIndirectCount; +} VkPhysicalDeviceMemoryDecompressionPropertiesEXT; + +typedef VkPhysicalDeviceMemoryDecompressionPropertiesEXT VkPhysicalDeviceMemoryDecompressionPropertiesNV; typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryNV)(VkCommandBuffer commandBuffer, uint32_t decompressRegionCount, const VkDecompressMemoryRegionNV* pDecompressMemoryRegions); typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryIndirectCountNV)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectCommandsAddress, VkDeviceAddress indirectCommandsCountAddress, uint32_t stride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryNV( VkCommandBuffer commandBuffer, uint32_t decompressRegionCount, const VkDecompressMemoryRegionNV* pDecompressMemoryRegions); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryIndirectCountNV( VkCommandBuffer commandBuffer, VkDeviceAddress indirectCommandsAddress, VkDeviceAddress indirectCommandsCountAddress, uint32_t stride); #endif +#endif // VK_NV_device_generated_commands_compute is a preprocessor guard. Do not pass it to API calls. @@ -17851,20 +22175,81 @@ typedef void (VKAPI_PTR *PFN_vkCmdUpdatePipelineIndirectBufferNV)(VkCommandBuffe typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetPipelineIndirectDeviceAddressNV)(VkDevice device, const VkPipelineIndirectDeviceAddressInfoNV* pInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetPipelineIndirectMemoryRequirementsNV( VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo, VkMemoryRequirements2* pMemoryRequirements); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdUpdatePipelineIndirectBufferNV( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetPipelineIndirectDeviceAddressNV( VkDevice device, const VkPipelineIndirectDeviceAddressInfoNV* pInfo); #endif +#endif + + +// VK_NV_ray_tracing_linear_swept_spheres is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_ray_tracing_linear_swept_spheres 1 +#define VK_NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_SPEC_VERSION 1 +#define VK_NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_EXTENSION_NAME "VK_NV_ray_tracing_linear_swept_spheres" + +typedef enum VkRayTracingLssIndexingModeNV { + VK_RAY_TRACING_LSS_INDEXING_MODE_LIST_NV = 0, + VK_RAY_TRACING_LSS_INDEXING_MODE_SUCCESSIVE_NV = 1, + VK_RAY_TRACING_LSS_INDEXING_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkRayTracingLssIndexingModeNV; + +typedef enum VkRayTracingLssPrimitiveEndCapsModeNV { + VK_RAY_TRACING_LSS_PRIMITIVE_END_CAPS_MODE_NONE_NV = 0, + VK_RAY_TRACING_LSS_PRIMITIVE_END_CAPS_MODE_CHAINED_NV = 1, + VK_RAY_TRACING_LSS_PRIMITIVE_END_CAPS_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkRayTracingLssPrimitiveEndCapsModeNV; +typedef struct VkPhysicalDeviceRayTracingLinearSweptSpheresFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 spheres; + VkBool32 linearSweptSpheres; +} VkPhysicalDeviceRayTracingLinearSweptSpheresFeaturesNV; + +typedef struct VkAccelerationStructureGeometryLinearSweptSpheresDataNV { + VkStructureType sType; + const void* pNext; + VkFormat vertexFormat; + VkDeviceOrHostAddressConstKHR vertexData; + VkDeviceSize vertexStride; + VkFormat radiusFormat; + VkDeviceOrHostAddressConstKHR radiusData; + VkDeviceSize radiusStride; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexData; + VkDeviceSize indexStride; + VkRayTracingLssIndexingModeNV indexingMode; + VkRayTracingLssPrimitiveEndCapsModeNV endCapsMode; +} VkAccelerationStructureGeometryLinearSweptSpheresDataNV; + +typedef struct VkAccelerationStructureGeometrySpheresDataNV { + VkStructureType sType; + const void* pNext; + VkFormat vertexFormat; + VkDeviceOrHostAddressConstKHR vertexData; + VkDeviceSize vertexStride; + VkFormat radiusFormat; + VkDeviceOrHostAddressConstKHR radiusData; + VkDeviceSize radiusStride; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexData; + VkDeviceSize indexStride; +} VkAccelerationStructureGeometrySpheresDataNV; + // VK_NV_linear_color_attachment is a preprocessor guard. Do not pass it to API calls. @@ -18056,142 +22441,204 @@ typedef void (VKAPI_PTR *PFN_vkCmdSetRepresentativeFragmentTestEnableNV)(VkComma typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageReductionModeNV)(VkCommandBuffer commandBuffer, VkCoverageReductionModeNV coverageReductionMode); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClampEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthClampEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetPolygonModeEXT( VkCommandBuffer commandBuffer, VkPolygonMode polygonMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationSamplesEXT( VkCommandBuffer commandBuffer, VkSampleCountFlagBits rasterizationSamples); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleMaskEXT( VkCommandBuffer commandBuffer, VkSampleCountFlagBits samples, const VkSampleMask* pSampleMask); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToCoverageEnableEXT( VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToOneEnableEXT( VkCommandBuffer commandBuffer, VkBool32 alphaToOneEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEnableEXT( VkCommandBuffer commandBuffer, VkBool32 logicOpEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEnableEXT( VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkBool32* pColorBlendEnables); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEquationEXT( VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendEquationEXT* pColorBlendEquations); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteMaskEXT( VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorComponentFlags* pColorWriteMasks); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetTessellationDomainOriginEXT( VkCommandBuffer commandBuffer, VkTessellationDomainOrigin domainOrigin); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationStreamEXT( VkCommandBuffer commandBuffer, uint32_t rasterizationStream); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetConservativeRasterizationModeEXT( VkCommandBuffer commandBuffer, VkConservativeRasterizationModeEXT conservativeRasterizationMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetExtraPrimitiveOverestimationSizeEXT( VkCommandBuffer commandBuffer, float extraPrimitiveOverestimationSize); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthClipEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEnableEXT( VkCommandBuffer commandBuffer, VkBool32 sampleLocationsEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendAdvancedEXT( VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendAdvancedEXT* pColorBlendAdvanced); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetProvokingVertexModeEXT( VkCommandBuffer commandBuffer, VkProvokingVertexModeEXT provokingVertexMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLineRasterizationModeEXT( VkCommandBuffer commandBuffer, VkLineRasterizationModeEXT lineRasterizationMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEnableEXT( VkCommandBuffer commandBuffer, VkBool32 stippledLineEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipNegativeOneToOneEXT( VkCommandBuffer commandBuffer, VkBool32 negativeOneToOne); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingEnableNV( VkCommandBuffer commandBuffer, VkBool32 viewportWScalingEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportSwizzleNV( VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportSwizzleNV* pViewportSwizzles); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorEnableNV( VkCommandBuffer commandBuffer, VkBool32 coverageToColorEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorLocationNV( VkCommandBuffer commandBuffer, uint32_t coverageToColorLocation); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationModeNV( VkCommandBuffer commandBuffer, VkCoverageModulationModeNV coverageModulationMode); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableEnableNV( VkCommandBuffer commandBuffer, VkBool32 coverageModulationTableEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableNV( VkCommandBuffer commandBuffer, uint32_t coverageModulationTableCount, const float* pCoverageModulationTable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetShadingRateImageEnableNV( VkCommandBuffer commandBuffer, VkBool32 shadingRateImageEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRepresentativeFragmentTestEnableNV( VkCommandBuffer commandBuffer, VkBool32 representativeFragmentTestEnable); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageReductionModeNV( VkCommandBuffer commandBuffer, VkCoverageReductionModeNV coverageReductionMode); #endif +#endif // VK_EXT_subpass_merge_feedback is a preprocessor guard. Do not pass it to API calls. @@ -18264,7 +22711,8 @@ typedef enum VkDirectDriverLoadingModeLUNARG { } VkDirectDriverLoadingModeLUNARG; typedef VkFlags VkDirectDriverLoadingFlagsLUNARG; typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddrLUNARG)( - VkInstance instance, const char* pName); + VkInstance instance, + const char* pName); typedef struct VkDirectDriverLoadingInfoLUNARG { VkStructureType sType; @@ -18283,6 +22731,315 @@ typedef struct VkDirectDriverLoadingListLUNARG { +// VK_ARM_tensors is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_tensors 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkTensorViewARM) +#define VK_ARM_TENSORS_SPEC_VERSION 2 +#define VK_ARM_TENSORS_EXTENSION_NAME "VK_ARM_tensors" + +typedef enum VkTensorTilingARM { + VK_TENSOR_TILING_OPTIMAL_ARM = 0, + VK_TENSOR_TILING_LINEAR_ARM = 1, + VK_TENSOR_TILING_MAX_ENUM_ARM = 0x7FFFFFFF +} VkTensorTilingARM; +typedef VkFlags64 VkTensorCreateFlagsARM; + +// Flag bits for VkTensorCreateFlagBitsARM +typedef VkFlags64 VkTensorCreateFlagBitsARM; +static const VkTensorCreateFlagBitsARM VK_TENSOR_CREATE_MUTABLE_FORMAT_BIT_ARM = 0x00000001ULL; +static const VkTensorCreateFlagBitsARM VK_TENSOR_CREATE_PROTECTED_BIT_ARM = 0x00000002ULL; +static const VkTensorCreateFlagBitsARM VK_TENSOR_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_ARM = 0x00000008ULL; +static const VkTensorCreateFlagBitsARM VK_TENSOR_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_ARM = 0x00000004ULL; + +typedef VkFlags64 VkTensorUsageFlagsARM; + +// Flag bits for VkTensorUsageFlagBitsARM +typedef VkFlags64 VkTensorUsageFlagBitsARM; +static const VkTensorUsageFlagBitsARM VK_TENSOR_USAGE_SHADER_BIT_ARM = 0x00000002ULL; +static const VkTensorUsageFlagBitsARM VK_TENSOR_USAGE_TRANSFER_SRC_BIT_ARM = 0x00000004ULL; +static const VkTensorUsageFlagBitsARM VK_TENSOR_USAGE_TRANSFER_DST_BIT_ARM = 0x00000008ULL; +static const VkTensorUsageFlagBitsARM VK_TENSOR_USAGE_IMAGE_ALIASING_BIT_ARM = 0x00000010ULL; +static const VkTensorUsageFlagBitsARM VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM = 0x00000020ULL; + +typedef struct VkTensorDescriptionARM { + VkStructureType sType; + const void* pNext; + VkTensorTilingARM tiling; + VkFormat format; + uint32_t dimensionCount; + const int64_t* pDimensions; + const int64_t* pStrides; + VkTensorUsageFlagsARM usage; +} VkTensorDescriptionARM; + +typedef struct VkTensorCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorCreateFlagsARM flags; + const VkTensorDescriptionARM* pDescription; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkTensorCreateInfoARM; + +typedef struct VkTensorMemoryRequirementsInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorARM tensor; +} VkTensorMemoryRequirementsInfoARM; + +typedef struct VkBindTensorMemoryInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorARM tensor; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindTensorMemoryInfoARM; + +typedef struct VkWriteDescriptorSetTensorARM { + VkStructureType sType; + const void* pNext; + uint32_t tensorViewCount; + const VkTensorViewARM* pTensorViews; +} VkWriteDescriptorSetTensorARM; + +typedef struct VkTensorFormatPropertiesARM { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 optimalTilingTensorFeatures; + VkFormatFeatureFlags2 linearTilingTensorFeatures; +} VkTensorFormatPropertiesARM; + +typedef struct VkPhysicalDeviceTensorPropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t maxTensorDimensionCount; + uint64_t maxTensorElements; + uint64_t maxPerDimensionTensorElements; + int64_t maxTensorStride; + uint64_t maxTensorSize; + uint32_t maxTensorShaderAccessArrayLength; + uint32_t maxTensorShaderAccessSize; + uint32_t maxDescriptorSetStorageTensors; + uint32_t maxPerStageDescriptorSetStorageTensors; + uint32_t maxDescriptorSetUpdateAfterBindStorageTensors; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageTensors; + VkBool32 shaderStorageTensorArrayNonUniformIndexingNative; + VkShaderStageFlags shaderTensorSupportedStages; +} VkPhysicalDeviceTensorPropertiesARM; + +typedef struct VkTensorMemoryBarrierARM { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkTensorARM tensor; +} VkTensorMemoryBarrierARM; + +typedef struct VkTensorDependencyInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t tensorMemoryBarrierCount; + const VkTensorMemoryBarrierARM* pTensorMemoryBarriers; +} VkTensorDependencyInfoARM; + +typedef struct VkPhysicalDeviceTensorFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 tensorNonPacked; + VkBool32 shaderTensorAccess; + VkBool32 shaderStorageTensorArrayDynamicIndexing; + VkBool32 shaderStorageTensorArrayNonUniformIndexing; + VkBool32 descriptorBindingStorageTensorUpdateAfterBind; + VkBool32 tensors; +} VkPhysicalDeviceTensorFeaturesARM; + +typedef struct VkDeviceTensorMemoryRequirementsARM { + VkStructureType sType; + const void* pNext; + const VkTensorCreateInfoARM* pCreateInfo; +} VkDeviceTensorMemoryRequirementsARM; + +typedef struct VkTensorCopyARM { + VkStructureType sType; + const void* pNext; + uint32_t dimensionCount; + const uint64_t* pSrcOffset; + const uint64_t* pDstOffset; + const uint64_t* pExtent; +} VkTensorCopyARM; + +typedef struct VkCopyTensorInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorARM srcTensor; + VkTensorARM dstTensor; + uint32_t regionCount; + const VkTensorCopyARM* pRegions; +} VkCopyTensorInfoARM; + +typedef struct VkMemoryDedicatedAllocateInfoTensorARM { + VkStructureType sType; + const void* pNext; + VkTensorARM tensor; +} VkMemoryDedicatedAllocateInfoTensorARM; + +typedef struct VkPhysicalDeviceExternalTensorInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorCreateFlagsARM flags; + const VkTensorDescriptionARM* pDescription; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalTensorInfoARM; + +typedef struct VkExternalTensorPropertiesARM { + VkStructureType sType; + const void* pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalTensorPropertiesARM; + +typedef struct VkExternalMemoryTensorCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryTensorCreateInfoARM; + +typedef struct VkPhysicalDeviceDescriptorBufferTensorFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 descriptorBufferTensorDescriptors; +} VkPhysicalDeviceDescriptorBufferTensorFeaturesARM; + +typedef struct VkPhysicalDeviceDescriptorBufferTensorPropertiesARM { + VkStructureType sType; + void* pNext; + size_t tensorCaptureReplayDescriptorDataSize; + size_t tensorViewCaptureReplayDescriptorDataSize; + size_t tensorDescriptorSize; +} VkPhysicalDeviceDescriptorBufferTensorPropertiesARM; + +typedef struct VkDescriptorGetTensorInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorViewARM tensorView; +} VkDescriptorGetTensorInfoARM; + +typedef struct VkTensorCaptureDescriptorDataInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorARM tensor; +} VkTensorCaptureDescriptorDataInfoARM; + +typedef struct VkTensorViewCaptureDescriptorDataInfoARM { + VkStructureType sType; + const void* pNext; + VkTensorViewARM tensorView; +} VkTensorViewCaptureDescriptorDataInfoARM; + +typedef struct VkFrameBoundaryTensorsARM { + VkStructureType sType; + const void* pNext; + uint32_t tensorCount; + const VkTensorARM* pTensors; +} VkFrameBoundaryTensorsARM; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateTensorARM)(VkDevice device, const VkTensorCreateInfoARM* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkTensorARM* pTensor); +typedef void (VKAPI_PTR *PFN_vkDestroyTensorARM)(VkDevice device, VkTensorARM tensor, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateTensorViewARM)(VkDevice device, const VkTensorViewCreateInfoARM* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkTensorViewARM* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyTensorViewARM)(VkDevice device, VkTensorViewARM tensorView, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetTensorMemoryRequirementsARM)(VkDevice device, const VkTensorMemoryRequirementsInfoARM* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindTensorMemoryARM)(VkDevice device, uint32_t bindInfoCount, const VkBindTensorMemoryInfoARM* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkGetDeviceTensorMemoryRequirementsARM)(VkDevice device, const VkDeviceTensorMemoryRequirementsARM* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdCopyTensorARM)(VkCommandBuffer commandBuffer, const VkCopyTensorInfoARM* pCopyTensorInfo); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalTensorPropertiesARM)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo, VkExternalTensorPropertiesARM* pExternalTensorProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetTensorOpaqueCaptureDescriptorDataARM)(VkDevice device, const VkTensorCaptureDescriptorDataInfoARM* pInfo, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetTensorViewOpaqueCaptureDescriptorDataARM)(VkDevice device, const VkTensorViewCaptureDescriptorDataInfoARM* pInfo, void* pData); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateTensorARM( + VkDevice device, + const VkTensorCreateInfoARM* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkTensorARM* pTensor); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyTensorARM( + VkDevice device, + VkTensorARM tensor, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateTensorViewARM( + VkDevice device, + const VkTensorViewCreateInfoARM* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkTensorViewARM* pView); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyTensorViewARM( + VkDevice device, + VkTensorViewARM tensorView, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetTensorMemoryRequirementsARM( + VkDevice device, + const VkTensorMemoryRequirementsInfoARM* pInfo, + VkMemoryRequirements2* pMemoryRequirements); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkBindTensorMemoryARM( + VkDevice device, + uint32_t bindInfoCount, + const VkBindTensorMemoryInfoARM* pBindInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceTensorMemoryRequirementsARM( + VkDevice device, + const VkDeviceTensorMemoryRequirementsARM* pInfo, + VkMemoryRequirements2* pMemoryRequirements); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyTensorARM( + VkCommandBuffer commandBuffer, + const VkCopyTensorInfoARM* pCopyTensorInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalTensorPropertiesARM( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo, + VkExternalTensorPropertiesARM* pExternalTensorProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetTensorOpaqueCaptureDescriptorDataARM( + VkDevice device, + const VkTensorCaptureDescriptorDataInfoARM* pInfo, + void* pData); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetTensorViewOpaqueCaptureDescriptorDataARM( + VkDevice device, + const VkTensorViewCaptureDescriptorDataInfoARM* pInfo, + void* pData); +#endif +#endif + + // VK_EXT_shader_module_identifier is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_shader_module_identifier 1 #define VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT 32U @@ -18318,16 +23075,20 @@ typedef void (VKAPI_PTR *PFN_vkGetShaderModuleIdentifierEXT)(VkDevice device, Vk typedef void (VKAPI_PTR *PFN_vkGetShaderModuleCreateInfoIdentifierEXT)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleIdentifierEXT( VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT* pIdentifier); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT( VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier); #endif +#endif // VK_EXT_rasterization_order_attachment_access is a preprocessor guard. Do not pass it to API calls. @@ -18429,7 +23190,7 @@ typedef struct VkOpticalFlowImageFormatInfoNV { typedef struct VkOpticalFlowImageFormatPropertiesNV { VkStructureType sType; - const void* pNext; + void* pNext; VkFormat format; } VkOpticalFlowImageFormatPropertiesNV; @@ -18470,40 +23231,50 @@ typedef VkResult (VKAPI_PTR *PFN_vkBindOpticalFlowSessionImageNV)(VkDevice devic typedef void (VKAPI_PTR *PFN_vkCmdOpticalFlowExecuteNV)(VkCommandBuffer commandBuffer, VkOpticalFlowSessionNV session, const VkOpticalFlowExecuteInfoNV* pExecuteInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceOpticalFlowImageFormatsNV( VkPhysicalDevice physicalDevice, const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo, uint32_t* pFormatCount, VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateOpticalFlowSessionNV( VkDevice device, const VkOpticalFlowSessionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkOpticalFlowSessionNV* pSession); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyOpticalFlowSessionNV( VkDevice device, VkOpticalFlowSessionNV session, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBindOpticalFlowSessionImageNV( VkDevice device, VkOpticalFlowSessionNV session, VkOpticalFlowSessionBindingPointNV bindingPoint, VkImageView view, VkImageLayout layout); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdOpticalFlowExecuteNV( VkCommandBuffer commandBuffer, VkOpticalFlowSessionNV session, const VkOpticalFlowExecuteInfoNV* pExecuteInfo); #endif +#endif // VK_EXT_legacy_dithering is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_legacy_dithering 1 -#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 1 +#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 2 #define VK_EXT_LEGACY_DITHERING_EXTENSION_NAME "VK_EXT_legacy_dithering" typedef struct VkPhysicalDeviceLegacyDitheringFeaturesEXT { VkStructureType sType; @@ -18517,12 +23288,57 @@ typedef struct VkPhysicalDeviceLegacyDitheringFeaturesEXT { #define VK_EXT_pipeline_protected_access 1 #define VK_EXT_PIPELINE_PROTECTED_ACCESS_SPEC_VERSION 1 #define VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME "VK_EXT_pipeline_protected_access" -typedef struct VkPhysicalDevicePipelineProtectedAccessFeaturesEXT { +typedef VkPhysicalDevicePipelineProtectedAccessFeatures VkPhysicalDevicePipelineProtectedAccessFeaturesEXT; + + + +// VK_AMD_anti_lag is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_anti_lag 1 +#define VK_AMD_ANTI_LAG_SPEC_VERSION 1 +#define VK_AMD_ANTI_LAG_EXTENSION_NAME "VK_AMD_anti_lag" + +typedef enum VkAntiLagModeAMD { + VK_ANTI_LAG_MODE_DRIVER_CONTROL_AMD = 0, + VK_ANTI_LAG_MODE_ON_AMD = 1, + VK_ANTI_LAG_MODE_OFF_AMD = 2, + VK_ANTI_LAG_MODE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkAntiLagModeAMD; + +typedef enum VkAntiLagStageAMD { + VK_ANTI_LAG_STAGE_INPUT_AMD = 0, + VK_ANTI_LAG_STAGE_PRESENT_AMD = 1, + VK_ANTI_LAG_STAGE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkAntiLagStageAMD; +typedef struct VkPhysicalDeviceAntiLagFeaturesAMD { VkStructureType sType; void* pNext; - VkBool32 pipelineProtectedAccess; -} VkPhysicalDevicePipelineProtectedAccessFeaturesEXT; + VkBool32 antiLag; +} VkPhysicalDeviceAntiLagFeaturesAMD; +typedef struct VkAntiLagPresentationInfoAMD { + VkStructureType sType; + void* pNext; + VkAntiLagStageAMD stage; + uint64_t frameIndex; +} VkAntiLagPresentationInfoAMD; + +typedef struct VkAntiLagDataAMD { + VkStructureType sType; + const void* pNext; + VkAntiLagModeAMD mode; + uint32_t maxFPS; + const VkAntiLagPresentationInfoAMD* pPresentationInfo; +} VkAntiLagDataAMD; + +typedef void (VKAPI_PTR *PFN_vkAntiLagUpdateAMD)(VkDevice device, const VkAntiLagDataAMD* pData); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkAntiLagUpdateAMD( + VkDevice device, + const VkAntiLagDataAMD* pData); +#endif +#endif // VK_EXT_shader_object is a preprocessor guard. Do not pass it to API calls. @@ -18537,14 +23353,26 @@ typedef enum VkShaderCodeTypeEXT { VK_SHADER_CODE_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkShaderCodeTypeEXT; +typedef enum VkDepthClampModeEXT { + VK_DEPTH_CLAMP_MODE_VIEWPORT_RANGE_EXT = 0, + VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT = 1, + VK_DEPTH_CLAMP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDepthClampModeEXT; + typedef enum VkShaderCreateFlagBitsEXT { VK_SHADER_CREATE_LINK_STAGE_BIT_EXT = 0x00000001, + VK_SHADER_CREATE_DESCRIPTOR_HEAP_BIT_EXT = 0x00000400, + VK_SHADER_CREATE_INSTRUMENT_SHADER_BIT_ARM = 0x00000800, VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000002, VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000004, VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT = 0x00000008, VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT = 0x00000010, VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT = 0x00000020, VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00000040, + VK_SHADER_CREATE_INDIRECT_BINDABLE_BIT_EXT = 0x00000080, + VK_SHADER_CREATE_OPACITY_MICROMAP_DISALLOW_MIXED_SPECIAL_INDEX_BIT_EXT = 0x00001000, + VK_SHADER_CREATE_64_BIT_INDEXING_BIT_EXT = 0x00008000, + VK_SHADER_CREATE_INDEPENDENT_SETS_BIT_KHR = 0x00040000, VK_SHADER_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkShaderCreateFlagBitsEXT; typedef VkFlags VkShaderCreateFlagsEXT; @@ -18580,30 +23408,43 @@ typedef struct VkShaderCreateInfoEXT { typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkShaderRequiredSubgroupSizeCreateInfoEXT; +typedef struct VkDepthClampRangeEXT { + float minDepthClamp; + float maxDepthClamp; +} VkDepthClampRangeEXT; + typedef VkResult (VKAPI_PTR *PFN_vkCreateShadersEXT)(VkDevice device, uint32_t createInfoCount, const VkShaderCreateInfoEXT* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkShaderEXT* pShaders); typedef void (VKAPI_PTR *PFN_vkDestroyShaderEXT)(VkDevice device, VkShaderEXT shader, const VkAllocationCallbacks* pAllocator); typedef VkResult (VKAPI_PTR *PFN_vkGetShaderBinaryDataEXT)(VkDevice device, VkShaderEXT shader, size_t* pDataSize, void* pData); typedef void (VKAPI_PTR *PFN_vkCmdBindShadersEXT)(VkCommandBuffer commandBuffer, uint32_t stageCount, const VkShaderStageFlagBits* pStages, const VkShaderEXT* pShaders); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClampRangeEXT)(VkCommandBuffer commandBuffer, VkDepthClampModeEXT depthClampMode, const VkDepthClampRangeEXT* pDepthClampRange); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateShadersEXT( VkDevice device, uint32_t createInfoCount, const VkShaderCreateInfoEXT* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkShaderEXT* pShaders); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyShaderEXT( VkDevice device, VkShaderEXT shader, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderBinaryDataEXT( VkDevice device, VkShaderEXT shader, size_t* pDataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBindShadersEXT( VkCommandBuffer commandBuffer, uint32_t stageCount, @@ -18611,6 +23452,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBindShadersEXT( const VkShaderEXT* pShaders); #endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClampRangeEXT( + VkCommandBuffer commandBuffer, + VkDepthClampModeEXT depthClampMode, + const VkDepthClampRangeEXT* pDepthClampRange); +#endif +#endif + // VK_QCOM_tile_properties is a preprocessor guard. Do not pass it to API calls. #define VK_QCOM_tile_properties 1 @@ -18634,17 +23483,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetFramebufferTilePropertiesQCOM)(VkDevice de typedef VkResult (VKAPI_PTR *PFN_vkGetDynamicRenderingTilePropertiesQCOM)(VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetFramebufferTilePropertiesQCOM( VkDevice device, VkFramebuffer framebuffer, uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDynamicRenderingTilePropertiesQCOM( VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties); #endif +#endif // VK_SEC_amigo_profiling is a preprocessor guard. Do not pass it to API calls. @@ -18683,15 +23536,19 @@ typedef struct VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM { #define VK_NV_RAY_TRACING_INVOCATION_REORDER_SPEC_VERSION 1 #define VK_NV_RAY_TRACING_INVOCATION_REORDER_EXTENSION_NAME "VK_NV_ray_tracing_invocation_reorder" -typedef enum VkRayTracingInvocationReorderModeNV { - VK_RAY_TRACING_INVOCATION_REORDER_MODE_NONE_NV = 0, - VK_RAY_TRACING_INVOCATION_REORDER_MODE_REORDER_NV = 1, - VK_RAY_TRACING_INVOCATION_REORDER_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkRayTracingInvocationReorderModeNV; +typedef enum VkRayTracingInvocationReorderModeEXT { + VK_RAY_TRACING_INVOCATION_REORDER_MODE_NONE_EXT = 0, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_REORDER_EXT = 1, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_NONE_NV = VK_RAY_TRACING_INVOCATION_REORDER_MODE_NONE_EXT, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_REORDER_NV = VK_RAY_TRACING_INVOCATION_REORDER_MODE_REORDER_EXT, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkRayTracingInvocationReorderModeEXT; +typedef VkRayTracingInvocationReorderModeEXT VkRayTracingInvocationReorderModeNV; + typedef struct VkPhysicalDeviceRayTracingInvocationReorderPropertiesNV { - VkStructureType sType; - void* pNext; - VkRayTracingInvocationReorderModeNV rayTracingInvocationReorderReorderingHint; + VkStructureType sType; + void* pNext; + VkRayTracingInvocationReorderModeEXT rayTracingInvocationReorderReorderingHint; } VkPhysicalDeviceRayTracingInvocationReorderPropertiesNV; typedef struct VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV { @@ -18702,6 +23559,89 @@ typedef struct VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV { +// VK_NV_cooperative_vector is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cooperative_vector 1 +#define VK_NV_COOPERATIVE_VECTOR_SPEC_VERSION 4 +#define VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME "VK_NV_cooperative_vector" + +typedef enum VkCooperativeVectorMatrixLayoutNV { + VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV = 0, + VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV = 1, + VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_INFERENCING_OPTIMAL_NV = 2, + VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_TRAINING_OPTIMAL_NV = 3, + VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_MAX_ENUM_NV = 0x7FFFFFFF +} VkCooperativeVectorMatrixLayoutNV; +typedef struct VkPhysicalDeviceCooperativeVectorPropertiesNV { + VkStructureType sType; + void* pNext; + VkShaderStageFlags cooperativeVectorSupportedStages; + VkBool32 cooperativeVectorTrainingFloat16Accumulation; + VkBool32 cooperativeVectorTrainingFloat32Accumulation; + uint32_t maxCooperativeVectorComponents; +} VkPhysicalDeviceCooperativeVectorPropertiesNV; + +typedef struct VkPhysicalDeviceCooperativeVectorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeVector; + VkBool32 cooperativeVectorTraining; +} VkPhysicalDeviceCooperativeVectorFeaturesNV; + +typedef struct VkCooperativeVectorPropertiesNV { + VkStructureType sType; + void* pNext; + VkComponentTypeKHR inputType; + VkComponentTypeKHR inputInterpretation; + VkComponentTypeKHR matrixInterpretation; + VkComponentTypeKHR biasInterpretation; + VkComponentTypeKHR resultType; + VkBool32 transpose; +} VkCooperativeVectorPropertiesNV; + +typedef struct VkConvertCooperativeVectorMatrixInfoNV { + VkStructureType sType; + const void* pNext; + size_t srcSize; + VkDeviceOrHostAddressConstKHR srcData; + size_t* pDstSize; + VkDeviceOrHostAddressKHR dstData; + VkComponentTypeKHR srcComponentType; + VkComponentTypeKHR dstComponentType; + uint32_t numRows; + uint32_t numColumns; + VkCooperativeVectorMatrixLayoutNV srcLayout; + size_t srcStride; + VkCooperativeVectorMatrixLayoutNV dstLayout; + size_t dstStride; +} VkConvertCooperativeVectorMatrixInfoNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeVectorPropertiesNV* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkConvertCooperativeVectorMatrixNV)(VkDevice device, const VkConvertCooperativeVectorMatrixInfoNV* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdConvertCooperativeVectorMatrixNV)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkConvertCooperativeVectorMatrixInfoNV* pInfos); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeVectorPropertiesNV( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkCooperativeVectorPropertiesNV* pProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkConvertCooperativeVectorMatrixNV( + VkDevice device, + const VkConvertCooperativeVectorMatrixInfoNV* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdConvertCooperativeVectorMatrixNV( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkConvertCooperativeVectorMatrixInfoNV* pInfos); +#endif +#endif + + // VK_NV_extended_sparse_address_space is a preprocessor guard. Do not pass it to API calls. #define VK_NV_extended_sparse_address_space 1 #define VK_NV_EXTENDED_SPARSE_ADDRESS_SPACE_SPEC_VERSION 1 @@ -18728,6 +23668,24 @@ typedef struct VkPhysicalDeviceExtendedSparseAddressSpacePropertiesNV { #define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_EXT_mutable_descriptor_type" +// VK_EXT_legacy_vertex_attributes is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_legacy_vertex_attributes 1 +#define VK_EXT_LEGACY_VERTEX_ATTRIBUTES_SPEC_VERSION 1 +#define VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME "VK_EXT_legacy_vertex_attributes" +typedef struct VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 legacyVertexAttributes; +} VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT; + +typedef struct VkPhysicalDeviceLegacyVertexAttributesPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 nativeUnalignedPerformance; +} VkPhysicalDeviceLegacyVertexAttributesPropertiesEXT; + + + // VK_EXT_layer_settings is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_layer_settings 1 #define VK_EXT_LAYER_SETTINGS_SPEC_VERSION 2 @@ -18855,7 +23813,7 @@ typedef struct VkSetLatencyMarkerInfoNV { typedef struct VkLatencyTimingsFrameReportNV { VkStructureType sType; - const void* pNext; + void* pNext; uint64_t presentID; uint64_t inputSampleTimeUs; uint64_t simStartTimeUs; @@ -18911,30 +23869,406 @@ typedef void (VKAPI_PTR *PFN_vkGetLatencyTimingsNV)(VkDevice device, VkSwapchain typedef void (VKAPI_PTR *PFN_vkQueueNotifyOutOfBandNV)(VkQueue queue, const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetLatencySleepModeNV( VkDevice device, VkSwapchainKHR swapchain, const VkLatencySleepModeInfoNV* pSleepModeInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkLatencySleepNV( VkDevice device, VkSwapchainKHR swapchain, const VkLatencySleepInfoNV* pSleepInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkSetLatencyMarkerNV( VkDevice device, VkSwapchainKHR swapchain, const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetLatencyTimingsNV( VkDevice device, VkSwapchainKHR swapchain, VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkQueueNotifyOutOfBandNV( VkQueue queue, const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo); #endif +#endif + + +// VK_ARM_data_graph is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_data_graph 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDataGraphPipelineSessionARM) +#define VK_MAX_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_SET_NAME_SIZE_ARM 128U +#define VK_ARM_DATA_GRAPH_SPEC_VERSION 1 +#define VK_ARM_DATA_GRAPH_EXTENSION_NAME "VK_ARM_data_graph" + +typedef enum VkDataGraphPipelineSessionBindPointARM { + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM = 0, + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_OPTICAL_FLOW_CACHE_ARM = 1000631001, + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_NEURAL_ACCELERATOR_STATISTICS_ARM = 1000676000, + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphPipelineSessionBindPointARM; + +typedef enum VkDataGraphPipelineSessionBindPointTypeARM { + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TYPE_MEMORY_ARM = 0, + VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TYPE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphPipelineSessionBindPointTypeARM; + +typedef enum VkDataGraphPipelinePropertyARM { + VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM = 0, + VK_DATA_GRAPH_PIPELINE_PROPERTY_IDENTIFIER_ARM = 1, + VK_DATA_GRAPH_PIPELINE_PROPERTY_NEURAL_ACCELERATOR_DEBUG_DATABASE_ARM = 1000676000, + VK_DATA_GRAPH_PIPELINE_PROPERTY_NEURAL_ACCELERATOR_STATISTICS_INFO_ARM = 1000676001, + VK_DATA_GRAPH_PIPELINE_PROPERTY_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphPipelinePropertyARM; + +typedef enum VkPhysicalDeviceDataGraphProcessingEngineTypeARM { + VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_DEFAULT_ARM = 0, + VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_NEURAL_QCOM = 1000629000, + VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_COMPUTE_QCOM = 1000629001, + VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkPhysicalDeviceDataGraphProcessingEngineTypeARM; + +typedef enum VkPhysicalDeviceDataGraphOperationTypeARM { + VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_SPIRV_EXTENDED_INSTRUCTION_SET_ARM = 0, + VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_NEURAL_MODEL_QCOM = 1000629000, + VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_BUILTIN_MODEL_QCOM = 1000629001, + VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_OPTICAL_FLOW_ARM = 1000631000, + VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkPhysicalDeviceDataGraphOperationTypeARM; +typedef VkFlags64 VkDataGraphPipelineSessionCreateFlagsARM; + +// Flag bits for VkDataGraphPipelineSessionCreateFlagBitsARM +typedef VkFlags64 VkDataGraphPipelineSessionCreateFlagBitsARM; +static const VkDataGraphPipelineSessionCreateFlagBitsARM VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM = 0x00000001ULL; +static const VkDataGraphPipelineSessionCreateFlagBitsARM VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_OPTICAL_FLOW_CACHE_BIT_ARM = 0x00000002ULL; + +typedef VkFlags64 VkDataGraphPipelineDispatchFlagsARM; + +// Flag bits for VkDataGraphPipelineDispatchFlagBitsARM +typedef VkFlags64 VkDataGraphPipelineDispatchFlagBitsARM; + +typedef struct VkPhysicalDeviceDataGraphFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 dataGraph; + VkBool32 dataGraphUpdateAfterBind; + VkBool32 dataGraphSpecializationConstants; + VkBool32 dataGraphDescriptorBuffer; + VkBool32 dataGraphShaderModule; +} VkPhysicalDeviceDataGraphFeaturesARM; + +typedef struct VkDataGraphPipelineConstantARM { + VkStructureType sType; + const void* pNext; + uint32_t id; + const void* pConstantData; +} VkDataGraphPipelineConstantARM; + +typedef struct VkDataGraphPipelineResourceInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSet; + uint32_t binding; + uint32_t arrayElement; +} VkDataGraphPipelineResourceInfoARM; + +typedef struct VkDataGraphPipelineCompilerControlCreateInfoARM { + VkStructureType sType; + const void* pNext; + const char* pVendorOptions; +} VkDataGraphPipelineCompilerControlCreateInfoARM; + +typedef struct VkDataGraphPipelineCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags2 flags; + VkPipelineLayout layout; + uint32_t resourceInfoCount; + const VkDataGraphPipelineResourceInfoARM* pResourceInfos; +} VkDataGraphPipelineCreateInfoARM; + +typedef struct VkDataGraphPipelineShaderModuleCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkShaderModule module; + const char* pName; + const VkSpecializationInfo* pSpecializationInfo; + uint32_t constantCount; + const VkDataGraphPipelineConstantARM* pConstants; +} VkDataGraphPipelineShaderModuleCreateInfoARM; + +typedef struct VkDataGraphPipelineSessionCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkDataGraphPipelineSessionCreateFlagsARM flags; + VkPipeline dataGraphPipeline; +} VkDataGraphPipelineSessionCreateInfoARM; + +typedef struct VkDataGraphPipelineSessionBindPointRequirementsInfoARM { + VkStructureType sType; + const void* pNext; + VkDataGraphPipelineSessionARM session; +} VkDataGraphPipelineSessionBindPointRequirementsInfoARM; + +typedef struct VkDataGraphPipelineSessionBindPointRequirementARM { + VkStructureType sType; + void* pNext; + VkDataGraphPipelineSessionBindPointARM bindPoint; + VkDataGraphPipelineSessionBindPointTypeARM bindPointType; + uint32_t numObjects; +} VkDataGraphPipelineSessionBindPointRequirementARM; + +typedef struct VkDataGraphPipelineSessionMemoryRequirementsInfoARM { + VkStructureType sType; + const void* pNext; + VkDataGraphPipelineSessionARM session; + VkDataGraphPipelineSessionBindPointARM bindPoint; + uint32_t objectIndex; +} VkDataGraphPipelineSessionMemoryRequirementsInfoARM; + +typedef struct VkBindDataGraphPipelineSessionMemoryInfoARM { + VkStructureType sType; + const void* pNext; + VkDataGraphPipelineSessionARM session; + VkDataGraphPipelineSessionBindPointARM bindPoint; + uint32_t objectIndex; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindDataGraphPipelineSessionMemoryInfoARM; + +typedef struct VkDataGraphPipelineInfoARM { + VkStructureType sType; + const void* pNext; + VkPipeline dataGraphPipeline; +} VkDataGraphPipelineInfoARM; + +typedef struct VkDataGraphPipelinePropertyQueryResultARM { + VkStructureType sType; + void* pNext; + VkDataGraphPipelinePropertyARM property; + VkBool32 isText; + size_t dataSize; + void* pData; +} VkDataGraphPipelinePropertyQueryResultARM; + +typedef struct VkDataGraphPipelineIdentifierCreateInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t identifierSize; + const uint8_t* pIdentifier; +} VkDataGraphPipelineIdentifierCreateInfoARM; + +typedef struct VkDataGraphPipelineDispatchInfoARM { + VkStructureType sType; + void* pNext; + VkDataGraphPipelineDispatchFlagsARM flags; +} VkDataGraphPipelineDispatchInfoARM; + +typedef struct VkPhysicalDeviceDataGraphProcessingEngineARM { + VkPhysicalDeviceDataGraphProcessingEngineTypeARM type; + VkBool32 isForeign; +} VkPhysicalDeviceDataGraphProcessingEngineARM; + +typedef struct VkPhysicalDeviceDataGraphOperationSupportARM { + VkPhysicalDeviceDataGraphOperationTypeARM operationType; + char name[VK_MAX_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_SET_NAME_SIZE_ARM]; + uint32_t version; +} VkPhysicalDeviceDataGraphOperationSupportARM; + +typedef struct VkQueueFamilyDataGraphPropertiesARM { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceDataGraphProcessingEngineARM engine; + VkPhysicalDeviceDataGraphOperationSupportARM operation; +} VkQueueFamilyDataGraphPropertiesARM; + +typedef struct VkDataGraphProcessingEngineCreateInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t processingEngineCount; + VkPhysicalDeviceDataGraphProcessingEngineARM* pProcessingEngines; +} VkDataGraphProcessingEngineCreateInfoARM; + +typedef struct VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + VkPhysicalDeviceDataGraphProcessingEngineTypeARM engineType; +} VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM; + +typedef struct VkQueueFamilyDataGraphProcessingEnginePropertiesARM { + VkStructureType sType; + void* pNext; + VkExternalSemaphoreHandleTypeFlags foreignSemaphoreHandleTypes; + VkExternalMemoryHandleTypeFlags foreignMemoryHandleTypes; +} VkQueueFamilyDataGraphProcessingEnginePropertiesARM; + +typedef struct VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t dimension; + uint32_t zeroCount; + uint32_t groupSize; +} VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDataGraphPipelinesARM)(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkDataGraphPipelineCreateInfoARM* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDataGraphPipelineSessionARM)(VkDevice device, const VkDataGraphPipelineSessionCreateInfoARM* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDataGraphPipelineSessionARM* pSession); +typedef VkResult (VKAPI_PTR *PFN_vkGetDataGraphPipelineSessionBindPointRequirementsARM)(VkDevice device, const VkDataGraphPipelineSessionBindPointRequirementsInfoARM* pInfo, uint32_t* pBindPointRequirementCount, VkDataGraphPipelineSessionBindPointRequirementARM* pBindPointRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDataGraphPipelineSessionMemoryRequirementsARM)(VkDevice device, const VkDataGraphPipelineSessionMemoryRequirementsInfoARM* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindDataGraphPipelineSessionMemoryARM)(VkDevice device, uint32_t bindInfoCount, const VkBindDataGraphPipelineSessionMemoryInfoARM* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkDestroyDataGraphPipelineSessionARM)(VkDevice device, VkDataGraphPipelineSessionARM session, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchDataGraphARM)(VkCommandBuffer commandBuffer, VkDataGraphPipelineSessionARM session, const VkDataGraphPipelineDispatchInfoARM* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetDataGraphPipelineAvailablePropertiesARM)(VkDevice device, const VkDataGraphPipelineInfoARM* pPipelineInfo, uint32_t* pPropertiesCount, VkDataGraphPipelinePropertyARM* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDataGraphPipelinePropertiesARM)(VkDevice device, const VkDataGraphPipelineInfoARM* pPipelineInfo, uint32_t propertiesCount, VkDataGraphPipelinePropertyQueryResultARM* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pQueueFamilyDataGraphPropertyCount, VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo, VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDataGraphPipelinesARM( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkDataGraphPipelineCreateInfoARM* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDataGraphPipelineSessionARM( + VkDevice device, + const VkDataGraphPipelineSessionCreateInfoARM* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDataGraphPipelineSessionARM* pSession); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDataGraphPipelineSessionBindPointRequirementsARM( + VkDevice device, + const VkDataGraphPipelineSessionBindPointRequirementsInfoARM* pInfo, + uint32_t* pBindPointRequirementCount, + VkDataGraphPipelineSessionBindPointRequirementARM* pBindPointRequirements); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDataGraphPipelineSessionMemoryRequirementsARM( + VkDevice device, + const VkDataGraphPipelineSessionMemoryRequirementsInfoARM* pInfo, + VkMemoryRequirements2* pMemoryRequirements); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkBindDataGraphPipelineSessionMemoryARM( + VkDevice device, + uint32_t bindInfoCount, + const VkBindDataGraphPipelineSessionMemoryInfoARM* pBindInfos); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyDataGraphPipelineSessionARM( + VkDevice device, + VkDataGraphPipelineSessionARM session, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchDataGraphARM( + VkCommandBuffer commandBuffer, + VkDataGraphPipelineSessionARM session, + const VkDataGraphPipelineDispatchInfoARM* pInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDataGraphPipelineAvailablePropertiesARM( + VkDevice device, + const VkDataGraphPipelineInfoARM* pPipelineInfo, + uint32_t* pPropertiesCount, + VkDataGraphPipelinePropertyARM* pProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDataGraphPipelinePropertiesARM( + VkDevice device, + const VkDataGraphPipelineInfoARM* pPipelineInfo, + uint32_t propertiesCount, + VkDataGraphPipelinePropertyQueryResultARM* pProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + uint32_t* pQueueFamilyDataGraphPropertyCount, + VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo, + VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties); +#endif +#endif + + +// VK_ARM_data_graph_instruction_set_tosa is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_data_graph_instruction_set_tosa 1 +#define VK_MAX_DATA_GRAPH_TOSA_NAME_SIZE_ARM 128U +#define VK_ARM_DATA_GRAPH_INSTRUCTION_SET_TOSA_SPEC_VERSION 1 +#define VK_ARM_DATA_GRAPH_INSTRUCTION_SET_TOSA_EXTENSION_NAME "VK_ARM_data_graph_instruction_set_tosa" + +typedef enum VkDataGraphTOSALevelARM { + VK_DATA_GRAPH_TOSA_LEVEL_NONE_ARM = 0, + VK_DATA_GRAPH_TOSA_LEVEL_8K_ARM = 1, + VK_DATA_GRAPH_TOSALEVEL_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphTOSALevelARM; + +typedef enum VkDataGraphTOSAQualityFlagBitsARM { + VK_DATA_GRAPH_TOSA_QUALITY_ACCELERATED_ARM = 0x00000001, + VK_DATA_GRAPH_TOSA_QUALITY_CONFORMANT_ARM = 0x00000002, + VK_DATA_GRAPH_TOSA_QUALITY_EXPERIMENTAL_ARM = 0x00000004, + VK_DATA_GRAPH_TOSA_QUALITY_DEPRECATED_ARM = 0x00000008, + VK_DATA_GRAPH_TOSAQUALITY_FLAG_BITS_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphTOSAQualityFlagBitsARM; +typedef VkFlags VkDataGraphTOSAQualityFlagsARM; +typedef struct VkDataGraphTOSANameQualityARM { + char name[VK_MAX_DATA_GRAPH_TOSA_NAME_SIZE_ARM]; + VkDataGraphTOSAQualityFlagsARM qualityFlags; +} VkDataGraphTOSANameQualityARM; + +typedef struct VkQueueFamilyDataGraphTOSAPropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t profileCount; + const VkDataGraphTOSANameQualityARM* pProfiles; + uint32_t extensionCount; + const VkDataGraphTOSANameQualityARM* pExtensions; + VkDataGraphTOSALevelARM level; +} VkQueueFamilyDataGraphTOSAPropertiesARM; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties, VkBaseOutStructure* pProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + const VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties, + VkBaseOutStructure* pProperties); +#endif +#endif // VK_QCOM_multiview_per_view_render_areas is a preprocessor guard. Do not pass it to API calls. @@ -19076,10 +24410,12 @@ typedef struct VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT { typedef void (VKAPI_PTR *PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT)(VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetAttachmentFeedbackLoopEnableEXT( VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask); #endif +#endif // VK_MSFT_layered_driver is a preprocessor guard. Do not pass it to API calls. @@ -19112,6 +24448,120 @@ typedef struct VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV { +// VK_QCOM_tile_memory_heap is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_tile_memory_heap 1 +#define VK_QCOM_TILE_MEMORY_HEAP_SPEC_VERSION 1 +#define VK_QCOM_TILE_MEMORY_HEAP_EXTENSION_NAME "VK_QCOM_tile_memory_heap" +typedef struct VkPhysicalDeviceTileMemoryHeapFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 tileMemoryHeap; +} VkPhysicalDeviceTileMemoryHeapFeaturesQCOM; + +typedef struct VkPhysicalDeviceTileMemoryHeapPropertiesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 queueSubmitBoundary; + VkBool32 tileBufferTransfers; +} VkPhysicalDeviceTileMemoryHeapPropertiesQCOM; + +typedef struct VkTileMemoryRequirementsQCOM { + VkStructureType sType; + void* pNext; + VkDeviceSize size; + VkDeviceSize alignment; +} VkTileMemoryRequirementsQCOM; + +typedef struct VkTileMemoryBindInfoQCOM { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkTileMemoryBindInfoQCOM; + +typedef struct VkTileMemorySizeInfoQCOM { + VkStructureType sType; + const void* pNext; + VkDeviceSize size; +} VkTileMemorySizeInfoQCOM; + +typedef void (VKAPI_PTR *PFN_vkCmdBindTileMemoryQCOM)(VkCommandBuffer commandBuffer, const VkTileMemoryBindInfoQCOM* pTileMemoryBindInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindTileMemoryQCOM( + VkCommandBuffer commandBuffer, + const VkTileMemoryBindInfoQCOM* pTileMemoryBindInfo); +#endif +#endif + + +// VK_EXT_memory_decompression is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_memory_decompression 1 +#define VK_EXT_MEMORY_DECOMPRESSION_SPEC_VERSION 1 +#define VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME "VK_EXT_memory_decompression" +typedef struct VkDecompressMemoryRegionEXT { + VkDeviceAddress srcAddress; + VkDeviceAddress dstAddress; + VkDeviceSize compressedSize; + VkDeviceSize decompressedSize; +} VkDecompressMemoryRegionEXT; + +typedef struct VkDecompressMemoryInfoEXT { + VkStructureType sType; + const void* pNext; + VkMemoryDecompressionMethodFlagsEXT decompressionMethod; + uint32_t regionCount; + const VkDecompressMemoryRegionEXT* pRegions; +} VkDecompressMemoryInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryEXT)(VkCommandBuffer commandBuffer, const VkDecompressMemoryInfoEXT* pDecompressMemoryInfoEXT); +typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryIndirectCountEXT)(VkCommandBuffer commandBuffer, VkMemoryDecompressionMethodFlagsEXT decompressionMethod, VkDeviceAddress indirectCommandsAddress, VkDeviceAddress indirectCommandsCountAddress, uint32_t maxDecompressionCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryEXT( + VkCommandBuffer commandBuffer, + const VkDecompressMemoryInfoEXT* pDecompressMemoryInfoEXT); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryIndirectCountEXT( + VkCommandBuffer commandBuffer, + VkMemoryDecompressionMethodFlagsEXT decompressionMethod, + VkDeviceAddress indirectCommandsAddress, + VkDeviceAddress indirectCommandsCountAddress, + uint32_t maxDecompressionCount, + uint32_t stride); +#endif +#endif + + +// VK_NV_display_stereo is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_display_stereo 1 +#define VK_NV_DISPLAY_STEREO_SPEC_VERSION 1 +#define VK_NV_DISPLAY_STEREO_EXTENSION_NAME "VK_NV_display_stereo" + +typedef enum VkDisplaySurfaceStereoTypeNV { + VK_DISPLAY_SURFACE_STEREO_TYPE_NONE_NV = 0, + VK_DISPLAY_SURFACE_STEREO_TYPE_ONBOARD_DIN_NV = 1, + VK_DISPLAY_SURFACE_STEREO_TYPE_HDMI_3D_NV = 2, + VK_DISPLAY_SURFACE_STEREO_TYPE_INBAND_DISPLAYPORT_NV = 3, + VK_DISPLAY_SURFACE_STEREO_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkDisplaySurfaceStereoTypeNV; +typedef struct VkDisplaySurfaceStereoCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDisplaySurfaceStereoTypeNV stereoType; +} VkDisplaySurfaceStereoCreateInfoNV; + +typedef struct VkDisplayModeStereoPropertiesNV { + VkStructureType sType; + void* pNext; + VkBool32 hdmi3DSupported; +} VkDisplayModeStereoPropertiesNV; + + + // VK_NV_raw_access_chains is a preprocessor guard. Do not pass it to API calls. #define VK_NV_raw_access_chains 1 #define VK_NV_RAW_ACCESS_CHAINS_SPEC_VERSION 1 @@ -19124,6 +24574,77 @@ typedef struct VkPhysicalDeviceRawAccessChainsFeaturesNV { +// VK_NV_external_compute_queue is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_external_compute_queue 1 +VK_DEFINE_HANDLE(VkExternalComputeQueueNV) +#define VK_NV_EXTERNAL_COMPUTE_QUEUE_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_COMPUTE_QUEUE_EXTENSION_NAME "VK_NV_external_compute_queue" +typedef struct VkExternalComputeQueueDeviceCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t reservedExternalQueues; +} VkExternalComputeQueueDeviceCreateInfoNV; + +typedef struct VkExternalComputeQueueCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkQueue preferredQueue; +} VkExternalComputeQueueCreateInfoNV; + +typedef struct VkExternalComputeQueueDataParamsNV { + VkStructureType sType; + const void* pNext; + uint32_t deviceIndex; +} VkExternalComputeQueueDataParamsNV; + +typedef struct VkPhysicalDeviceExternalComputeQueuePropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t externalDataSize; + uint32_t maxExternalQueues; +} VkPhysicalDeviceExternalComputeQueuePropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateExternalComputeQueueNV)(VkDevice device, const VkExternalComputeQueueCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkExternalComputeQueueNV* pExternalQueue); +typedef void (VKAPI_PTR *PFN_vkDestroyExternalComputeQueueNV)(VkDevice device, VkExternalComputeQueueNV externalQueue, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetExternalComputeQueueDataNV)(VkExternalComputeQueueNV externalQueue, VkExternalComputeQueueDataParamsNV* params, void* pData); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateExternalComputeQueueNV( + VkDevice device, + const VkExternalComputeQueueCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkExternalComputeQueueNV* pExternalQueue); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyExternalComputeQueueNV( + VkDevice device, + VkExternalComputeQueueNV externalQueue, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetExternalComputeQueueDataNV( + VkExternalComputeQueueNV externalQueue, + VkExternalComputeQueueDataParamsNV* params, + void* pData); +#endif +#endif + + +// VK_NV_command_buffer_inheritance is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_command_buffer_inheritance 1 +#define VK_NV_COMMAND_BUFFER_INHERITANCE_SPEC_VERSION 1 +#define VK_NV_COMMAND_BUFFER_INHERITANCE_EXTENSION_NAME "VK_NV_command_buffer_inheritance" +typedef struct VkPhysicalDeviceCommandBufferInheritanceFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 commandBufferInheritance; +} VkPhysicalDeviceCommandBufferInheritanceFeaturesNV; + + + // VK_NV_shader_atomic_float16_vector is a preprocessor guard. Do not pass it to API calls. #define VK_NV_shader_atomic_float16_vector 1 #define VK_NV_SHADER_ATOMIC_FLOAT16_VECTOR_SPEC_VERSION 1 @@ -19136,6 +24657,31 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV { +// VK_EXT_shader_replicated_composites is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_replicated_composites 1 +#define VK_EXT_SHADER_REPLICATED_COMPOSITES_SPEC_VERSION 1 +#define VK_EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME "VK_EXT_shader_replicated_composites" +typedef struct VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderReplicatedComposites; +} VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT; + + + +// VK_EXT_shader_float8 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_float8 1 +#define VK_EXT_SHADER_FLOAT8_SPEC_VERSION 1 +#define VK_EXT_SHADER_FLOAT8_EXTENSION_NAME "VK_EXT_shader_float8" +typedef struct VkPhysicalDeviceShaderFloat8FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloat8; + VkBool32 shaderFloat8CooperativeMatrix; +} VkPhysicalDeviceShaderFloat8FeaturesEXT; + + + // VK_NV_ray_tracing_validation is a preprocessor guard. Do not pass it to API calls. #define VK_NV_ray_tracing_validation 1 #define VK_NV_RAY_TRACING_VALIDATION_SPEC_VERSION 1 @@ -19148,6 +24694,1517 @@ typedef struct VkPhysicalDeviceRayTracingValidationFeaturesNV { +// VK_NV_cluster_acceleration_structure is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cluster_acceleration_structure 1 +#define VK_NV_CLUSTER_ACCELERATION_STRUCTURE_SPEC_VERSION 4 +#define VK_NV_CLUSTER_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_NV_cluster_acceleration_structure" + +typedef enum VkClusterAccelerationStructureTypeNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_TYPE_CLUSTERS_BOTTOM_LEVEL_NV = 0, + VK_CLUSTER_ACCELERATION_STRUCTURE_TYPE_TRIANGLE_CLUSTER_NV = 1, + VK_CLUSTER_ACCELERATION_STRUCTURE_TYPE_TRIANGLE_CLUSTER_TEMPLATE_NV = 2, + VK_CLUSTER_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureTypeNV; + +typedef enum VkClusterAccelerationStructureOpTypeNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_MOVE_OBJECTS_NV = 0, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_BUILD_CLUSTERS_BOTTOM_LEVEL_NV = 1, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_BUILD_TRIANGLE_CLUSTER_NV = 2, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_BUILD_TRIANGLE_CLUSTER_TEMPLATE_NV = 3, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_INSTANTIATE_TRIANGLE_CLUSTER_NV = 4, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_GET_CLUSTER_TEMPLATE_INDICES_NV = 5, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureOpTypeNV; + +typedef enum VkClusterAccelerationStructureOpModeNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_MODE_IMPLICIT_DESTINATIONS_NV = 0, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_MODE_EXPLICIT_DESTINATIONS_NV = 1, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_MODE_COMPUTE_SIZES_NV = 2, + VK_CLUSTER_ACCELERATION_STRUCTURE_OP_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureOpModeNV; + +typedef enum VkClusterAccelerationStructureAddressResolutionFlagBitsNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_NONE_NV = 0, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_DST_IMPLICIT_DATA_BIT_NV = 0x00000001, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_SCRATCH_DATA_BIT_NV = 0x00000002, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_DST_ADDRESS_ARRAY_BIT_NV = 0x00000004, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_DST_SIZES_ARRAY_BIT_NV = 0x00000008, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_SRC_INFOS_ARRAY_BIT_NV = 0x00000010, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_INDIRECTED_SRC_INFOS_COUNT_BIT_NV = 0x00000020, + VK_CLUSTER_ACCELERATION_STRUCTURE_ADDRESS_RESOLUTION_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureAddressResolutionFlagBitsNV; +typedef VkFlags VkClusterAccelerationStructureAddressResolutionFlagsNV; + +typedef enum VkClusterAccelerationStructureClusterFlagBitsNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_CLUSTER_ALLOW_DISABLE_OPACITY_MICROMAPS_NV = 0x00000001, + VK_CLUSTER_ACCELERATION_STRUCTURE_CLUSTER_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureClusterFlagBitsNV; +typedef VkFlags VkClusterAccelerationStructureClusterFlagsNV; + +typedef enum VkClusterAccelerationStructureGeometryFlagBitsNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_GEOMETRY_CULL_DISABLE_BIT_NV = 0x00000001, + VK_CLUSTER_ACCELERATION_STRUCTURE_GEOMETRY_NO_DUPLICATE_ANYHIT_INVOCATION_BIT_NV = 0x00000002, + VK_CLUSTER_ACCELERATION_STRUCTURE_GEOMETRY_OPAQUE_BIT_NV = 0x00000004, + VK_CLUSTER_ACCELERATION_STRUCTURE_GEOMETRY_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureGeometryFlagBitsNV; +typedef VkFlags VkClusterAccelerationStructureGeometryFlagsNV; + +typedef enum VkClusterAccelerationStructureIndexFormatFlagBitsNV { + VK_CLUSTER_ACCELERATION_STRUCTURE_INDEX_FORMAT_8BIT_NV = 0x00000001, + VK_CLUSTER_ACCELERATION_STRUCTURE_INDEX_FORMAT_16BIT_NV = 0x00000002, + VK_CLUSTER_ACCELERATION_STRUCTURE_INDEX_FORMAT_32BIT_NV = 0x00000004, + VK_CLUSTER_ACCELERATION_STRUCTURE_INDEX_FORMAT_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkClusterAccelerationStructureIndexFormatFlagBitsNV; +typedef VkFlags VkClusterAccelerationStructureIndexFormatFlagsNV; +typedef struct VkPhysicalDeviceClusterAccelerationStructureFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 clusterAccelerationStructure; +} VkPhysicalDeviceClusterAccelerationStructureFeaturesNV; + +typedef struct VkPhysicalDeviceClusterAccelerationStructurePropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxVerticesPerCluster; + uint32_t maxTrianglesPerCluster; + uint32_t clusterScratchByteAlignment; + uint32_t clusterByteAlignment; + uint32_t clusterTemplateByteAlignment; + uint32_t clusterBottomLevelByteAlignment; + uint32_t clusterTemplateBoundsByteAlignment; + uint32_t maxClusterGeometryIndex; +} VkPhysicalDeviceClusterAccelerationStructurePropertiesNV; + +typedef struct VkClusterAccelerationStructureClustersBottomLevelInputNV { + VkStructureType sType; + void* pNext; + uint32_t maxTotalClusterCount; + uint32_t maxClusterCountPerAccelerationStructure; +} VkClusterAccelerationStructureClustersBottomLevelInputNV; + +typedef struct VkClusterAccelerationStructureTriangleClusterInputNV { + VkStructureType sType; + void* pNext; + VkFormat vertexFormat; + uint32_t maxGeometryIndexValue; + uint32_t maxClusterUniqueGeometryCount; + uint32_t maxClusterTriangleCount; + uint32_t maxClusterVertexCount; + uint32_t maxTotalTriangleCount; + uint32_t maxTotalVertexCount; + uint32_t minPositionTruncateBitCount; +} VkClusterAccelerationStructureTriangleClusterInputNV; + +typedef struct VkClusterAccelerationStructureMoveObjectsInputNV { + VkStructureType sType; + void* pNext; + VkClusterAccelerationStructureTypeNV type; + VkBool32 noMoveOverlap; + VkDeviceSize maxMovedBytes; +} VkClusterAccelerationStructureMoveObjectsInputNV; + +typedef union VkClusterAccelerationStructureOpInputNV { + VkClusterAccelerationStructureClustersBottomLevelInputNV* pClustersBottomLevel; + VkClusterAccelerationStructureTriangleClusterInputNV* pTriangleClusters; + VkClusterAccelerationStructureMoveObjectsInputNV* pMoveObjects; +} VkClusterAccelerationStructureOpInputNV; + +typedef struct VkClusterAccelerationStructureInputInfoNV { + VkStructureType sType; + void* pNext; + uint32_t maxAccelerationStructureCount; + VkBuildAccelerationStructureFlagsKHR flags; + VkClusterAccelerationStructureOpTypeNV opType; + VkClusterAccelerationStructureOpModeNV opMode; + VkClusterAccelerationStructureOpInputNV opInput; +} VkClusterAccelerationStructureInputInfoNV; + +typedef struct VkStridedDeviceAddressRegionKHR { + VkDeviceAddress deviceAddress; + VkDeviceSize stride; + VkDeviceSize size; +} VkStridedDeviceAddressRegionKHR; + +typedef struct VkClusterAccelerationStructureCommandsInfoNV { + VkStructureType sType; + void* pNext; + VkClusterAccelerationStructureInputInfoNV input; + VkDeviceAddress dstImplicitData; + VkDeviceAddress scratchData; + VkStridedDeviceAddressRegionKHR dstAddressesArray; + VkStridedDeviceAddressRegionKHR dstSizesArray; + VkStridedDeviceAddressRegionKHR srcInfosArray; + VkDeviceAddress srcInfosCount; + VkClusterAccelerationStructureAddressResolutionFlagsNV addressResolutionFlags; +} VkClusterAccelerationStructureCommandsInfoNV; + +typedef struct VkStridedDeviceAddressNV { + VkDeviceAddress startAddress; + VkDeviceSize strideInBytes; +} VkStridedDeviceAddressNV; + +typedef struct VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV { + uint32_t geometryIndex:24; + uint32_t reserved:5; + uint32_t geometryFlags:3; +} VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV; + +typedef struct VkClusterAccelerationStructureMoveObjectsInfoNV { + VkDeviceAddress srcAccelerationStructure; +} VkClusterAccelerationStructureMoveObjectsInfoNV; + +typedef struct VkClusterAccelerationStructureBuildClustersBottomLevelInfoNV { + uint32_t clusterReferencesCount; + uint32_t clusterReferencesStride; + VkDeviceAddress clusterReferences; +} VkClusterAccelerationStructureBuildClustersBottomLevelInfoNV; + +typedef struct VkClusterAccelerationStructureBuildTriangleClusterInfoNV { + uint32_t clusterID; + VkClusterAccelerationStructureClusterFlagsNV clusterFlags; + uint32_t triangleCount:9; + uint32_t vertexCount:9; + uint32_t positionTruncateBitCount:6; + uint32_t indexType:4; + uint32_t opacityMicromapIndexType:4; + VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV baseGeometryIndexAndGeometryFlags; + uint16_t indexBufferStride; + uint16_t vertexBufferStride; + uint16_t geometryIndexAndFlagsBufferStride; + uint16_t opacityMicromapIndexBufferStride; + VkDeviceAddress indexBuffer; + VkDeviceAddress vertexBuffer; + VkDeviceAddress geometryIndexAndFlagsBuffer; + VkDeviceAddress opacityMicromapArray; + VkDeviceAddress opacityMicromapIndexBuffer; +} VkClusterAccelerationStructureBuildTriangleClusterInfoNV; + +typedef struct VkClusterAccelerationStructureBuildTriangleClusterTemplateInfoNV { + uint32_t clusterID; + VkClusterAccelerationStructureClusterFlagsNV clusterFlags; + uint32_t triangleCount:9; + uint32_t vertexCount:9; + uint32_t positionTruncateBitCount:6; + uint32_t indexType:4; + uint32_t opacityMicromapIndexType:4; + VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV baseGeometryIndexAndGeometryFlags; + uint16_t indexBufferStride; + uint16_t vertexBufferStride; + uint16_t geometryIndexAndFlagsBufferStride; + uint16_t opacityMicromapIndexBufferStride; + VkDeviceAddress indexBuffer; + VkDeviceAddress vertexBuffer; + VkDeviceAddress geometryIndexAndFlagsBuffer; + VkDeviceAddress opacityMicromapArray; + VkDeviceAddress opacityMicromapIndexBuffer; + VkDeviceAddress instantiationBoundingBoxLimit; +} VkClusterAccelerationStructureBuildTriangleClusterTemplateInfoNV; + +typedef struct VkClusterAccelerationStructureInstantiateClusterInfoNV { + uint32_t clusterIdOffset; + uint32_t geometryIndexOffset:24; + uint32_t reserved:8; + VkDeviceAddress clusterTemplateAddress; + VkStridedDeviceAddressNV vertexBuffer; +} VkClusterAccelerationStructureInstantiateClusterInfoNV; + +typedef struct VkClusterAccelerationStructureGetTemplateIndicesInfoNV { + VkDeviceAddress clusterTemplateAddress; +} VkClusterAccelerationStructureGetTemplateIndicesInfoNV; + +typedef struct VkAccelerationStructureBuildSizesInfoKHR { + VkStructureType sType; + void* pNext; + VkDeviceSize accelerationStructureSize; + VkDeviceSize updateScratchSize; + VkDeviceSize buildScratchSize; +} VkAccelerationStructureBuildSizesInfoKHR; + +typedef struct VkRayTracingPipelineClusterAccelerationStructureCreateInfoNV { + VkStructureType sType; + void* pNext; + VkBool32 allowClusterAccelerationStructure; +} VkRayTracingPipelineClusterAccelerationStructureCreateInfoNV; + +typedef void (VKAPI_PTR *PFN_vkGetClusterAccelerationStructureBuildSizesNV)(VkDevice device, const VkClusterAccelerationStructureInputInfoNV* pInfo, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBuildClusterAccelerationStructureIndirectNV)(VkCommandBuffer commandBuffer, const VkClusterAccelerationStructureCommandsInfoNV* pCommandInfos); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetClusterAccelerationStructureBuildSizesNV( + VkDevice device, + const VkClusterAccelerationStructureInputInfoNV* pInfo, + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBuildClusterAccelerationStructureIndirectNV( + VkCommandBuffer commandBuffer, + const VkClusterAccelerationStructureCommandsInfoNV* pCommandInfos); +#endif +#endif + + +// VK_NV_partitioned_acceleration_structure is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_partitioned_acceleration_structure 1 +#define VK_NV_PARTITIONED_ACCELERATION_STRUCTURE_SPEC_VERSION 1 +#define VK_NV_PARTITIONED_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_NV_partitioned_acceleration_structure" +#define VK_PARTITIONED_ACCELERATION_STRUCTURE_PARTITION_INDEX_GLOBAL_NV (~0U) + +typedef enum VkPartitionedAccelerationStructureOpTypeNV { + VK_PARTITIONED_ACCELERATION_STRUCTURE_OP_TYPE_WRITE_INSTANCE_NV = 0, + VK_PARTITIONED_ACCELERATION_STRUCTURE_OP_TYPE_UPDATE_INSTANCE_NV = 1, + VK_PARTITIONED_ACCELERATION_STRUCTURE_OP_TYPE_WRITE_PARTITION_TRANSLATION_NV = 2, + VK_PARTITIONED_ACCELERATION_STRUCTURE_OP_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkPartitionedAccelerationStructureOpTypeNV; + +typedef enum VkPartitionedAccelerationStructureInstanceFlagBitsNV { + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_TRIANGLE_FACING_CULL_DISABLE_BIT_NV = 0x00000001, + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_TRIANGLE_FLIP_FACING_BIT_NV = 0x00000002, + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_FORCE_OPAQUE_BIT_NV = 0x00000004, + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_FORCE_NO_OPAQUE_BIT_NV = 0x00000008, + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_ENABLE_EXPLICIT_BOUNDING_BOX_NV = 0x00000010, + VK_PARTITIONED_ACCELERATION_STRUCTURE_INSTANCE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkPartitionedAccelerationStructureInstanceFlagBitsNV; +typedef VkFlags VkPartitionedAccelerationStructureInstanceFlagsNV; +typedef struct VkPhysicalDevicePartitionedAccelerationStructureFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 partitionedAccelerationStructure; +} VkPhysicalDevicePartitionedAccelerationStructureFeaturesNV; + +typedef struct VkPhysicalDevicePartitionedAccelerationStructurePropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxPartitionCount; +} VkPhysicalDevicePartitionedAccelerationStructurePropertiesNV; + +typedef struct VkPartitionedAccelerationStructureFlagsNV { + VkStructureType sType; + void* pNext; + VkBool32 enablePartitionTranslation; +} VkPartitionedAccelerationStructureFlagsNV; + +typedef struct VkBuildPartitionedAccelerationStructureIndirectCommandNV { + VkPartitionedAccelerationStructureOpTypeNV opType; + uint32_t argCount; + VkStridedDeviceAddressNV argData; +} VkBuildPartitionedAccelerationStructureIndirectCommandNV; + +typedef struct VkPartitionedAccelerationStructureWriteInstanceDataNV { + VkTransformMatrixKHR transform; + float explicitAABB[6]; + uint32_t instanceID; + uint32_t instanceMask; + uint32_t instanceContributionToHitGroupIndex; + VkPartitionedAccelerationStructureInstanceFlagsNV instanceFlags; + uint32_t instanceIndex; + uint32_t partitionIndex; + VkDeviceAddress accelerationStructure; +} VkPartitionedAccelerationStructureWriteInstanceDataNV; + +typedef struct VkPartitionedAccelerationStructureUpdateInstanceDataNV { + uint32_t instanceIndex; + uint32_t instanceContributionToHitGroupIndex; + VkDeviceAddress accelerationStructure; +} VkPartitionedAccelerationStructureUpdateInstanceDataNV; + +typedef struct VkPartitionedAccelerationStructureWritePartitionTranslationDataNV { + uint32_t partitionIndex; + float partitionTranslation[3]; +} VkPartitionedAccelerationStructureWritePartitionTranslationDataNV; + +typedef struct VkWriteDescriptorSetPartitionedAccelerationStructureNV { + VkStructureType sType; + void* pNext; + uint32_t accelerationStructureCount; + const VkDeviceAddress* pAccelerationStructures; +} VkWriteDescriptorSetPartitionedAccelerationStructureNV; + +typedef struct VkPartitionedAccelerationStructureInstancesInputNV { + VkStructureType sType; + void* pNext; + VkBuildAccelerationStructureFlagsKHR flags; + uint32_t instanceCount; + uint32_t maxInstancePerPartitionCount; + uint32_t partitionCount; + uint32_t maxInstanceInGlobalPartitionCount; +} VkPartitionedAccelerationStructureInstancesInputNV; + +typedef struct VkBuildPartitionedAccelerationStructureInfoNV { + VkStructureType sType; + void* pNext; + VkPartitionedAccelerationStructureInstancesInputNV input; + VkDeviceAddress srcAccelerationStructureData; + VkDeviceAddress dstAccelerationStructureData; + VkDeviceAddress scratchData; + VkDeviceAddress srcInfos; + VkDeviceAddress srcInfosCount; +} VkBuildPartitionedAccelerationStructureInfoNV; + +typedef void (VKAPI_PTR *PFN_vkGetPartitionedAccelerationStructuresBuildSizesNV)(VkDevice device, const VkPartitionedAccelerationStructureInstancesInputNV* pInfo, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBuildPartitionedAccelerationStructuresNV)(VkCommandBuffer commandBuffer, const VkBuildPartitionedAccelerationStructureInfoNV* pBuildInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPartitionedAccelerationStructuresBuildSizesNV( + VkDevice device, + const VkPartitionedAccelerationStructureInstancesInputNV* pInfo, + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBuildPartitionedAccelerationStructuresNV( + VkCommandBuffer commandBuffer, + const VkBuildPartitionedAccelerationStructureInfoNV* pBuildInfo); +#endif +#endif + + +// VK_EXT_device_generated_commands is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_device_generated_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectExecutionSetEXT) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutEXT) +#define VK_EXT_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 1 +#define VK_EXT_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_EXT_device_generated_commands" + +typedef enum VkIndirectExecutionSetInfoTypeEXT { + VK_INDIRECT_EXECUTION_SET_INFO_TYPE_PIPELINES_EXT = 0, + VK_INDIRECT_EXECUTION_SET_INFO_TYPE_SHADER_OBJECTS_EXT = 1, + VK_INDIRECT_EXECUTION_SET_INFO_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkIndirectExecutionSetInfoTypeEXT; + +typedef enum VkIndirectCommandsTokenTypeEXT { + VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT = 0, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT = 1, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_SEQUENCE_INDEX_EXT = 2, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_EXT = 3, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_EXT = 4, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT = 5, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT = 6, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT = 8, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT = 9, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_EXT = 1000135000, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_SEQUENCE_INDEX_EXT = 1000135001, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV_EXT = 1000202002, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_NV_EXT = 1000202003, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT = 1000328000, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT = 1000328001, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT = 1000386004, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkIndirectCommandsTokenTypeEXT; + +typedef enum VkIndirectCommandsInputModeFlagBitsEXT { + VK_INDIRECT_COMMANDS_INPUT_MODE_VULKAN_INDEX_BUFFER_EXT = 0x00000001, + VK_INDIRECT_COMMANDS_INPUT_MODE_DXGI_INDEX_BUFFER_EXT = 0x00000002, + VK_INDIRECT_COMMANDS_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkIndirectCommandsInputModeFlagBitsEXT; +typedef VkFlags VkIndirectCommandsInputModeFlagsEXT; + +typedef enum VkIndirectCommandsLayoutUsageFlagBitsEXT { + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_EXT = 0x00000001, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_EXT = 0x00000002, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkIndirectCommandsLayoutUsageFlagBitsEXT; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsEXT; +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 deviceGeneratedCommands; + VkBool32 dynamicGeneratedPipelineLayout; +} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesEXT; + +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxIndirectPipelineCount; + uint32_t maxIndirectShaderObjectCount; + uint32_t maxIndirectSequenceCount; + uint32_t maxIndirectCommandsTokenCount; + uint32_t maxIndirectCommandsTokenOffset; + uint32_t maxIndirectCommandsIndirectStride; + VkIndirectCommandsInputModeFlagsEXT supportedIndirectCommandsInputModes; + VkShaderStageFlags supportedIndirectCommandsShaderStages; + VkShaderStageFlags supportedIndirectCommandsShaderStagesPipelineBinding; + VkShaderStageFlags supportedIndirectCommandsShaderStagesShaderBinding; + VkBool32 deviceGeneratedCommandsTransformFeedback; + VkBool32 deviceGeneratedCommandsMultiDrawIndirectCount; +} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesEXT; + +typedef struct VkGeneratedCommandsMemoryRequirementsInfoEXT { + VkStructureType sType; + const void* pNext; + VkIndirectExecutionSetEXT indirectExecutionSet; + VkIndirectCommandsLayoutEXT indirectCommandsLayout; + uint32_t maxSequenceCount; + uint32_t maxDrawCount; +} VkGeneratedCommandsMemoryRequirementsInfoEXT; + +typedef struct VkIndirectExecutionSetPipelineInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipeline initialPipeline; + uint32_t maxPipelineCount; +} VkIndirectExecutionSetPipelineInfoEXT; + +typedef struct VkIndirectExecutionSetShaderLayoutInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; +} VkIndirectExecutionSetShaderLayoutInfoEXT; + +typedef struct VkIndirectExecutionSetShaderInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t shaderCount; + const VkShaderEXT* pInitialShaders; + const VkIndirectExecutionSetShaderLayoutInfoEXT* pSetLayoutInfos; + uint32_t maxShaderCount; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; +} VkIndirectExecutionSetShaderInfoEXT; + +typedef union VkIndirectExecutionSetInfoEXT { + const VkIndirectExecutionSetPipelineInfoEXT* pPipelineInfo; + const VkIndirectExecutionSetShaderInfoEXT* pShaderInfo; +} VkIndirectExecutionSetInfoEXT; + +typedef struct VkIndirectExecutionSetCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkIndirectExecutionSetInfoTypeEXT type; + VkIndirectExecutionSetInfoEXT info; +} VkIndirectExecutionSetCreateInfoEXT; + +typedef struct VkGeneratedCommandsInfoEXT { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags shaderStages; + VkIndirectExecutionSetEXT indirectExecutionSet; + VkIndirectCommandsLayoutEXT indirectCommandsLayout; + VkDeviceAddress indirectAddress; + VkDeviceSize indirectAddressSize; + VkDeviceAddress preprocessAddress; + VkDeviceSize preprocessSize; + uint32_t maxSequenceCount; + VkDeviceAddress sequenceCountAddress; + uint32_t maxDrawCount; +} VkGeneratedCommandsInfoEXT; + +typedef struct VkWriteIndirectExecutionSetPipelineEXT { + VkStructureType sType; + const void* pNext; + uint32_t index; + VkPipeline pipeline; +} VkWriteIndirectExecutionSetPipelineEXT; + +typedef struct VkIndirectCommandsPushConstantTokenEXT { + VkPushConstantRange updateRange; +} VkIndirectCommandsPushConstantTokenEXT; + +typedef struct VkIndirectCommandsVertexBufferTokenEXT { + uint32_t vertexBindingUnit; +} VkIndirectCommandsVertexBufferTokenEXT; + +typedef struct VkIndirectCommandsIndexBufferTokenEXT { + VkIndirectCommandsInputModeFlagBitsEXT mode; +} VkIndirectCommandsIndexBufferTokenEXT; + +typedef struct VkIndirectCommandsExecutionSetTokenEXT { + VkIndirectExecutionSetInfoTypeEXT type; + VkShaderStageFlags shaderStages; +} VkIndirectCommandsExecutionSetTokenEXT; + +typedef union VkIndirectCommandsTokenDataEXT { + const VkIndirectCommandsPushConstantTokenEXT* pPushConstant; + const VkIndirectCommandsVertexBufferTokenEXT* pVertexBuffer; + const VkIndirectCommandsIndexBufferTokenEXT* pIndexBuffer; + const VkIndirectCommandsExecutionSetTokenEXT* pExecutionSet; +} VkIndirectCommandsTokenDataEXT; + +typedef struct VkIndirectCommandsLayoutTokenEXT { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsTokenTypeEXT type; + VkIndirectCommandsTokenDataEXT data; + uint32_t offset; +} VkIndirectCommandsLayoutTokenEXT; + +typedef struct VkIndirectCommandsLayoutCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsLayoutUsageFlagsEXT flags; + VkShaderStageFlags shaderStages; + uint32_t indirectStride; + VkPipelineLayout pipelineLayout; + uint32_t tokenCount; + const VkIndirectCommandsLayoutTokenEXT* pTokens; +} VkIndirectCommandsLayoutCreateInfoEXT; + +typedef struct VkDrawIndirectCountIndirectCommandEXT { + VkDeviceAddress bufferAddress; + uint32_t stride; + uint32_t commandCount; +} VkDrawIndirectCountIndirectCommandEXT; + +typedef struct VkBindVertexBufferIndirectCommandEXT { + VkDeviceAddress bufferAddress; + uint32_t size; + uint32_t stride; +} VkBindVertexBufferIndirectCommandEXT; + +typedef struct VkBindIndexBufferIndirectCommandEXT { + VkDeviceAddress bufferAddress; + uint32_t size; + VkIndexType indexType; +} VkBindIndexBufferIndirectCommandEXT; + +typedef struct VkGeneratedCommandsPipelineInfoEXT { + VkStructureType sType; + void* pNext; + VkPipeline pipeline; +} VkGeneratedCommandsPipelineInfoEXT; + +typedef struct VkGeneratedCommandsShaderInfoEXT { + VkStructureType sType; + void* pNext; + uint32_t shaderCount; + const VkShaderEXT* pShaders; +} VkGeneratedCommandsShaderInfoEXT; + +typedef struct VkWriteIndirectExecutionSetShaderEXT { + VkStructureType sType; + const void* pNext; + uint32_t index; + VkShaderEXT shader; +} VkWriteIndirectExecutionSetShaderEXT; + +typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsEXT)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoEXT* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsEXT)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo, VkCommandBuffer stateCommandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsEXT)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutEXT)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutEXT* pIndirectCommandsLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutEXT)(VkDevice device, VkIndirectCommandsLayoutEXT indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectExecutionSetEXT)(VkDevice device, const VkIndirectExecutionSetCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectExecutionSetEXT* pIndirectExecutionSet); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectExecutionSetEXT)(VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateIndirectExecutionSetPipelineEXT)(VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet, uint32_t executionSetWriteCount, const VkWriteIndirectExecutionSetPipelineEXT* pExecutionSetWrites); +typedef void (VKAPI_PTR *PFN_vkUpdateIndirectExecutionSetShaderEXT)(VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet, uint32_t executionSetWriteCount, const VkWriteIndirectExecutionSetShaderEXT* pExecutionSetWrites); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsEXT( + VkDevice device, + const VkGeneratedCommandsMemoryRequirementsInfoEXT* pInfo, + VkMemoryRequirements2* pMemoryRequirements); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsEXT( + VkCommandBuffer commandBuffer, + const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo, + VkCommandBuffer stateCommandBuffer); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsEXT( + VkCommandBuffer commandBuffer, + VkBool32 isPreprocessed, + const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutEXT( + VkDevice device, + const VkIndirectCommandsLayoutCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectCommandsLayoutEXT* pIndirectCommandsLayout); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutEXT( + VkDevice device, + VkIndirectCommandsLayoutEXT indirectCommandsLayout, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectExecutionSetEXT( + VkDevice device, + const VkIndirectExecutionSetCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectExecutionSetEXT* pIndirectExecutionSet); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectExecutionSetEXT( + VkDevice device, + VkIndirectExecutionSetEXT indirectExecutionSet, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkUpdateIndirectExecutionSetPipelineEXT( + VkDevice device, + VkIndirectExecutionSetEXT indirectExecutionSet, + uint32_t executionSetWriteCount, + const VkWriteIndirectExecutionSetPipelineEXT* pExecutionSetWrites); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkUpdateIndirectExecutionSetShaderEXT( + VkDevice device, + VkIndirectExecutionSetEXT indirectExecutionSet, + uint32_t executionSetWriteCount, + const VkWriteIndirectExecutionSetShaderEXT* pExecutionSetWrites); +#endif +#endif + + +// VK_MESA_image_alignment_control is a preprocessor guard. Do not pass it to API calls. +#define VK_MESA_image_alignment_control 1 +#define VK_MESA_IMAGE_ALIGNMENT_CONTROL_SPEC_VERSION 1 +#define VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME "VK_MESA_image_alignment_control" +typedef struct VkPhysicalDeviceImageAlignmentControlFeaturesMESA { + VkStructureType sType; + void* pNext; + VkBool32 imageAlignmentControl; +} VkPhysicalDeviceImageAlignmentControlFeaturesMESA; + +typedef struct VkPhysicalDeviceImageAlignmentControlPropertiesMESA { + VkStructureType sType; + void* pNext; + uint32_t supportedImageAlignmentMask; +} VkPhysicalDeviceImageAlignmentControlPropertiesMESA; + +typedef struct VkImageAlignmentControlCreateInfoMESA { + VkStructureType sType; + const void* pNext; + uint32_t maximumRequestedAlignment; +} VkImageAlignmentControlCreateInfoMESA; + + + +// VK_NV_push_constant_bank is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_push_constant_bank 1 +#define VK_NV_PUSH_CONSTANT_BANK_SPEC_VERSION 1 +#define VK_NV_PUSH_CONSTANT_BANK_EXTENSION_NAME "VK_NV_push_constant_bank" +typedef struct VkPushConstantBankInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t bank; +} VkPushConstantBankInfoNV; + +typedef struct VkPhysicalDevicePushConstantBankFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 pushConstantBank; +} VkPhysicalDevicePushConstantBankFeaturesNV; + +typedef struct VkPhysicalDevicePushConstantBankPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxGraphicsPushConstantBanks; + uint32_t maxComputePushConstantBanks; + uint32_t maxGraphicsPushDataBanks; + uint32_t maxComputePushDataBanks; +} VkPhysicalDevicePushConstantBankPropertiesNV; + + + +// VK_EXT_ray_tracing_invocation_reorder is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_ray_tracing_invocation_reorder 1 +#define VK_EXT_RAY_TRACING_INVOCATION_REORDER_SPEC_VERSION 2 +#define VK_EXT_RAY_TRACING_INVOCATION_REORDER_EXTENSION_NAME "VK_EXT_ray_tracing_invocation_reorder" +typedef struct VkPhysicalDeviceRayTracingInvocationReorderPropertiesEXT { + VkStructureType sType; + void* pNext; + VkRayTracingInvocationReorderModeEXT rayTracingInvocationReorderReorderingHint; + uint32_t maxShaderBindingTableRecordIndex; +} VkPhysicalDeviceRayTracingInvocationReorderPropertiesEXT; + +typedef struct VkPhysicalDeviceRayTracingInvocationReorderFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingInvocationReorder; +} VkPhysicalDeviceRayTracingInvocationReorderFeaturesEXT; + + + +// VK_EXT_depth_clamp_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_clamp_control 1 +#define VK_EXT_DEPTH_CLAMP_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLAMP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clamp_control" +typedef struct VkPhysicalDeviceDepthClampControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClampControl; +} VkPhysicalDeviceDepthClampControlFeaturesEXT; + +typedef struct VkPipelineViewportDepthClampControlCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDepthClampModeEXT depthClampMode; + const VkDepthClampRangeEXT* pDepthClampRange; +} VkPipelineViewportDepthClampControlCreateInfoEXT; + + + +// VK_HUAWEI_hdr_vivid is a preprocessor guard. Do not pass it to API calls. +#define VK_HUAWEI_hdr_vivid 1 +#define VK_HUAWEI_HDR_VIVID_SPEC_VERSION 1 +#define VK_HUAWEI_HDR_VIVID_EXTENSION_NAME "VK_HUAWEI_hdr_vivid" +typedef struct VkPhysicalDeviceHdrVividFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 hdrVivid; +} VkPhysicalDeviceHdrVividFeaturesHUAWEI; + +typedef struct VkHdrVividDynamicMetadataHUAWEI { + VkStructureType sType; + const void* pNext; + size_t dynamicMetadataSize; + const void* pDynamicMetadata; +} VkHdrVividDynamicMetadataHUAWEI; + + + +// VK_NV_cooperative_matrix2 is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cooperative_matrix2 1 +#define VK_NV_COOPERATIVE_MATRIX_2_SPEC_VERSION 1 +#define VK_NV_COOPERATIVE_MATRIX_2_EXTENSION_NAME "VK_NV_cooperative_matrix2" +typedef struct VkCooperativeMatrixFlexibleDimensionsPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t MGranularity; + uint32_t NGranularity; + uint32_t KGranularity; + VkComponentTypeKHR AType; + VkComponentTypeKHR BType; + VkComponentTypeKHR CType; + VkComponentTypeKHR ResultType; + VkBool32 saturatingAccumulation; + VkScopeKHR scope; + uint32_t workgroupInvocations; +} VkCooperativeMatrixFlexibleDimensionsPropertiesNV; + +typedef struct VkPhysicalDeviceCooperativeMatrix2FeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeMatrixWorkgroupScope; + VkBool32 cooperativeMatrixFlexibleDimensions; + VkBool32 cooperativeMatrixReductions; + VkBool32 cooperativeMatrixConversions; + VkBool32 cooperativeMatrixPerElementOperations; + VkBool32 cooperativeMatrixTensorAddressing; + VkBool32 cooperativeMatrixBlockLoads; +} VkPhysicalDeviceCooperativeMatrix2FeaturesNV; + +typedef struct VkPhysicalDeviceCooperativeMatrix2PropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t cooperativeMatrixWorkgroupScopeMaxWorkgroupSize; + uint32_t cooperativeMatrixFlexibleDimensionsMaxDimension; + uint32_t cooperativeMatrixWorkgroupScopeReservedSharedMemory; +} VkPhysicalDeviceCooperativeMatrix2PropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixFlexibleDimensionsPropertiesNV* pProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkCooperativeMatrixFlexibleDimensionsPropertiesNV* pProperties); +#endif +#endif + + +// VK_ARM_pipeline_opacity_micromap is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_pipeline_opacity_micromap 1 +#define VK_ARM_PIPELINE_OPACITY_MICROMAP_SPEC_VERSION 1 +#define VK_ARM_PIPELINE_OPACITY_MICROMAP_EXTENSION_NAME "VK_ARM_pipeline_opacity_micromap" +typedef struct VkPhysicalDevicePipelineOpacityMicromapFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 pipelineOpacityMicromap; +} VkPhysicalDevicePipelineOpacityMicromapFeaturesARM; + + + +// VK_ARM_performance_counters_by_region is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_performance_counters_by_region 1 +#define VK_ARM_PERFORMANCE_COUNTERS_BY_REGION_SPEC_VERSION 1 +#define VK_ARM_PERFORMANCE_COUNTERS_BY_REGION_EXTENSION_NAME "VK_ARM_performance_counters_by_region" +typedef VkFlags VkPerformanceCounterDescriptionFlagsARM; +typedef struct VkPhysicalDevicePerformanceCountersByRegionFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 performanceCountersByRegion; +} VkPhysicalDevicePerformanceCountersByRegionFeaturesARM; + +typedef struct VkPhysicalDevicePerformanceCountersByRegionPropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t maxPerRegionPerformanceCounters; + VkExtent2D performanceCounterRegionSize; + uint32_t rowStrideAlignment; + uint32_t regionAlignment; + VkBool32 identityTransformOrder; +} VkPhysicalDevicePerformanceCountersByRegionPropertiesARM; + +typedef struct VkPerformanceCounterARM { + VkStructureType sType; + void* pNext; + uint32_t counterID; +} VkPerformanceCounterARM; + +typedef struct VkPerformanceCounterDescriptionARM { + VkStructureType sType; + void* pNext; + VkPerformanceCounterDescriptionFlagsARM flags; + char name[VK_MAX_DESCRIPTION_SIZE]; +} VkPerformanceCounterDescriptionARM; + +typedef struct VkRenderPassPerformanceCountersByRegionBeginInfoARM { + VkStructureType sType; + void* pNext; + uint32_t counterAddressCount; + const VkDeviceAddress* pCounterAddresses; + VkBool32 serializeRegions; + uint32_t counterIndexCount; + uint32_t* pCounterIndices; +} VkRenderPassPerformanceCountersByRegionBeginInfoARM; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterARM* pCounters, VkPerformanceCounterDescriptionARM* pCounterDescriptions); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + uint32_t* pCounterCount, + VkPerformanceCounterARM* pCounters, + VkPerformanceCounterDescriptionARM* pCounterDescriptions); +#endif +#endif + + +// VK_ARM_shader_instrumentation is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_shader_instrumentation 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderInstrumentationARM) +#define VK_ARM_SHADER_INSTRUMENTATION_SPEC_VERSION 1 +#define VK_ARM_SHADER_INSTRUMENTATION_EXTENSION_NAME "VK_ARM_shader_instrumentation" +typedef VkFlags VkShaderInstrumentationValuesFlagsARM; +typedef struct VkPhysicalDeviceShaderInstrumentationFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 shaderInstrumentation; +} VkPhysicalDeviceShaderInstrumentationFeaturesARM; + +typedef struct VkPhysicalDeviceShaderInstrumentationPropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t numMetrics; + VkBool32 perBasicBlockGranularity; +} VkPhysicalDeviceShaderInstrumentationPropertiesARM; + +typedef struct VkShaderInstrumentationCreateInfoARM { + VkStructureType sType; + void* pNext; +} VkShaderInstrumentationCreateInfoARM; + +typedef struct VkShaderInstrumentationMetricDescriptionARM { + VkStructureType sType; + void* pNext; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkShaderInstrumentationMetricDescriptionARM; + +typedef struct VkShaderInstrumentationMetricDataHeaderARM { + uint32_t resultIndex; + uint32_t resultSubIndex; + VkShaderStageFlags stages; + uint32_t basicBlockIndex; +} VkShaderInstrumentationMetricDataHeaderARM; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM)(VkPhysicalDevice physicalDevice, uint32_t* pDescriptionCount, VkShaderInstrumentationMetricDescriptionARM* pDescriptions); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderInstrumentationARM)(VkDevice device, const VkShaderInstrumentationCreateInfoARM* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderInstrumentationARM* pInstrumentation); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderInstrumentationARM)(VkDevice device, VkShaderInstrumentationARM instrumentation, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBeginShaderInstrumentationARM)(VkCommandBuffer commandBuffer, VkShaderInstrumentationARM instrumentation); +typedef void (VKAPI_PTR *PFN_vkCmdEndShaderInstrumentationARM)(VkCommandBuffer commandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInstrumentationValuesARM)(VkDevice device, VkShaderInstrumentationARM instrumentation, uint32_t* pMetricBlockCount, void* pMetricValues, VkShaderInstrumentationValuesFlagsARM flags); +typedef void (VKAPI_PTR *PFN_vkClearShaderInstrumentationMetricsARM)(VkDevice device, VkShaderInstrumentationARM instrumentation); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM( + VkPhysicalDevice physicalDevice, + uint32_t* pDescriptionCount, + VkShaderInstrumentationMetricDescriptionARM* pDescriptions); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderInstrumentationARM( + VkDevice device, + const VkShaderInstrumentationCreateInfoARM* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderInstrumentationARM* pInstrumentation); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderInstrumentationARM( + VkDevice device, + VkShaderInstrumentationARM instrumentation, + const VkAllocationCallbacks* pAllocator); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginShaderInstrumentationARM( + VkCommandBuffer commandBuffer, + VkShaderInstrumentationARM instrumentation); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndShaderInstrumentationARM( + VkCommandBuffer commandBuffer); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInstrumentationValuesARM( + VkDevice device, + VkShaderInstrumentationARM instrumentation, + uint32_t* pMetricBlockCount, + void* pMetricValues, + VkShaderInstrumentationValuesFlagsARM flags); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkClearShaderInstrumentationMetricsARM( + VkDevice device, + VkShaderInstrumentationARM instrumentation); +#endif +#endif + + +// VK_EXT_vertex_attribute_robustness is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_vertex_attribute_robustness 1 +#define VK_EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_SPEC_VERSION 1 +#define VK_EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_vertex_attribute_robustness" +typedef struct VkPhysicalDeviceVertexAttributeRobustnessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 vertexAttributeRobustness; +} VkPhysicalDeviceVertexAttributeRobustnessFeaturesEXT; + + + +// VK_ARM_format_pack is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_format_pack 1 +#define VK_ARM_FORMAT_PACK_SPEC_VERSION 1 +#define VK_ARM_FORMAT_PACK_EXTENSION_NAME "VK_ARM_format_pack" +typedef struct VkPhysicalDeviceFormatPackFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 formatPack; +} VkPhysicalDeviceFormatPackFeaturesARM; + + + +// VK_VALVE_fragment_density_map_layered is a preprocessor guard. Do not pass it to API calls. +#define VK_VALVE_fragment_density_map_layered 1 +#define VK_VALVE_FRAGMENT_DENSITY_MAP_LAYERED_SPEC_VERSION 1 +#define VK_VALVE_FRAGMENT_DENSITY_MAP_LAYERED_EXTENSION_NAME "VK_VALVE_fragment_density_map_layered" +typedef struct VkPhysicalDeviceFragmentDensityMapLayeredFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapLayered; +} VkPhysicalDeviceFragmentDensityMapLayeredFeaturesVALVE; + +typedef struct VkPhysicalDeviceFragmentDensityMapLayeredPropertiesVALVE { + VkStructureType sType; + void* pNext; + uint32_t maxFragmentDensityMapLayers; +} VkPhysicalDeviceFragmentDensityMapLayeredPropertiesVALVE; + +typedef struct VkPipelineFragmentDensityMapLayeredCreateInfoVALVE { + VkStructureType sType; + const void* pNext; + uint32_t maxFragmentDensityMapLayers; +} VkPipelineFragmentDensityMapLayeredCreateInfoVALVE; + + + +// VK_NV_present_metering is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_present_metering 1 +#define VK_NV_PRESENT_METERING_SPEC_VERSION 1 +#define VK_NV_PRESENT_METERING_EXTENSION_NAME "VK_NV_present_metering" +typedef struct VkSetPresentConfigNV { + VkStructureType sType; + const void* pNext; + uint32_t numFramesPerBatch; + uint32_t presentConfigFeedback; +} VkSetPresentConfigNV; + +typedef struct VkPhysicalDevicePresentMeteringFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 presentMetering; +} VkPhysicalDevicePresentMeteringFeaturesNV; + + + +// VK_EXT_fragment_density_map_offset is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_fragment_density_map_offset 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_EXT_fragment_density_map_offset" +typedef VkRenderingEndInfoKHR VkRenderingEndInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering2EXT)(VkCommandBuffer commandBuffer, const VkRenderingEndInfoKHR* pRenderingEndInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering2EXT( + VkCommandBuffer commandBuffer, + const VkRenderingEndInfoKHR* pRenderingEndInfo); +#endif +#endif + + +// VK_EXT_zero_initialize_device_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_zero_initialize_device_memory 1 +#define VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_SPEC_VERSION 1 +#define VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_EXTENSION_NAME "VK_EXT_zero_initialize_device_memory" +typedef struct VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 zeroInitializeDeviceMemory; +} VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT; + + + +// VK_EXT_shader_64bit_indexing is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_64bit_indexing 1 +#define VK_EXT_SHADER_64BIT_INDEXING_SPEC_VERSION 1 +#define VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME "VK_EXT_shader_64bit_indexing" +typedef struct VkPhysicalDeviceShader64BitIndexingFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shader64BitIndexing; +} VkPhysicalDeviceShader64BitIndexingFeaturesEXT; + + + +// VK_EXT_custom_resolve is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_custom_resolve 1 +#define VK_EXT_CUSTOM_RESOLVE_SPEC_VERSION 1 +#define VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME "VK_EXT_custom_resolve" +typedef struct VkPhysicalDeviceCustomResolveFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 customResolve; +} VkPhysicalDeviceCustomResolveFeaturesEXT; + +typedef struct VkBeginCustomResolveInfoEXT { + VkStructureType sType; + void* pNext; +} VkBeginCustomResolveInfoEXT; + +typedef struct VkCustomResolveCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 customResolve; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkCustomResolveCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdBeginCustomResolveEXT)(VkCommandBuffer commandBuffer, const VkBeginCustomResolveInfoEXT* pBeginCustomResolveInfo); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginCustomResolveEXT( + VkCommandBuffer commandBuffer, + const VkBeginCustomResolveInfoEXT* pBeginCustomResolveInfo); +#endif +#endif + + +// VK_QCOM_data_graph_model is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_data_graph_model 1 +#define VK_DATA_GRAPH_MODEL_TOOLCHAIN_VERSION_LENGTH_QCOM 3U +#define VK_QCOM_DATA_GRAPH_MODEL_SPEC_VERSION 1 +#define VK_QCOM_DATA_GRAPH_MODEL_EXTENSION_NAME "VK_QCOM_data_graph_model" + +typedef enum VkDataGraphModelCacheTypeQCOM { + VK_DATA_GRAPH_MODEL_CACHE_TYPE_GENERIC_BINARY_QCOM = 0, + VK_DATA_GRAPH_MODEL_CACHE_TYPE_MAX_ENUM_QCOM = 0x7FFFFFFF +} VkDataGraphModelCacheTypeQCOM; +typedef struct VkPipelineCacheHeaderVersionDataGraphQCOM { + uint32_t headerSize; + VkPipelineCacheHeaderVersion headerVersion; + VkDataGraphModelCacheTypeQCOM cacheType; + uint32_t cacheVersion; + uint32_t toolchainVersion[VK_DATA_GRAPH_MODEL_TOOLCHAIN_VERSION_LENGTH_QCOM]; +} VkPipelineCacheHeaderVersionDataGraphQCOM; + +typedef struct VkDataGraphPipelineBuiltinModelCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + const VkPhysicalDeviceDataGraphOperationSupportARM* pOperation; +} VkDataGraphPipelineBuiltinModelCreateInfoQCOM; + +typedef struct VkPhysicalDeviceDataGraphModelFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 dataGraphModel; +} VkPhysicalDeviceDataGraphModelFeaturesQCOM; + + + +// VK_ARM_data_graph_optical_flow is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_data_graph_optical_flow 1 +#define VK_ARM_DATA_GRAPH_OPTICAL_FLOW_SPEC_VERSION 1 +#define VK_ARM_DATA_GRAPH_OPTICAL_FLOW_EXTENSION_NAME "VK_ARM_data_graph_optical_flow" + +typedef enum VkDataGraphOpticalFlowPerformanceLevelARM { + VK_DATA_GRAPH_OPTICAL_FLOW_PERFORMANCE_LEVEL_UNKNOWN_ARM = 0, + VK_DATA_GRAPH_OPTICAL_FLOW_PERFORMANCE_LEVEL_SLOW_ARM = 1, + VK_DATA_GRAPH_OPTICAL_FLOW_PERFORMANCE_LEVEL_MEDIUM_ARM = 2, + VK_DATA_GRAPH_OPTICAL_FLOW_PERFORMANCE_LEVEL_FAST_ARM = 3, + VK_DATA_GRAPH_OPTICAL_FLOW_PERFORMANCE_LEVEL_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphOpticalFlowPerformanceLevelARM; + +typedef enum VkDataGraphPipelineNodeTypeARM { + VK_DATA_GRAPH_PIPELINE_NODE_TYPE_OPTICAL_FLOW_ARM = 1000631000, + VK_DATA_GRAPH_PIPELINE_NODE_TYPE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphPipelineNodeTypeARM; + +typedef enum VkDataGraphPipelineNodeConnectionTypeARM { + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_OPTICAL_FLOW_INPUT_ARM = 1000631000, + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_OPTICAL_FLOW_REFERENCE_ARM = 1000631001, + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_OPTICAL_FLOW_HINT_ARM = 1000631002, + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_OPTICAL_FLOW_FLOW_VECTOR_ARM = 1000631003, + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_OPTICAL_FLOW_COST_ARM = 1000631004, + VK_DATA_GRAPH_PIPELINE_NODE_CONNECTION_TYPE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphPipelineNodeConnectionTypeARM; + +typedef enum VkDataGraphOpticalFlowGridSizeFlagBitsARM { + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_UNKNOWN_ARM = 0, + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_1X1_BIT_ARM = 0x00000001, + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_2X2_BIT_ARM = 0x00000002, + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_4X4_BIT_ARM = 0x00000004, + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_8X8_BIT_ARM = 0x00000008, + VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_FLAG_BITS_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphOpticalFlowGridSizeFlagBitsARM; +typedef VkFlags VkDataGraphOpticalFlowGridSizeFlagsARM; + +typedef enum VkDataGraphOpticalFlowCreateFlagBitsARM { + VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_HINT_BIT_ARM = 0x00000001, + VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_COST_BIT_ARM = 0x00000002, + VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_RESERVED_30_BIT_ARM = 0x40000000, + VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_FLAG_BITS_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphOpticalFlowCreateFlagBitsARM; +typedef VkFlags VkDataGraphOpticalFlowCreateFlagsARM; + +typedef enum VkDataGraphOpticalFlowImageUsageFlagBitsARM { + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_UNKNOWN_ARM = 0, + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_INPUT_BIT_ARM = 0x00000001, + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_OUTPUT_BIT_ARM = 0x00000002, + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_HINT_BIT_ARM = 0x00000004, + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_COST_BIT_ARM = 0x00000008, + VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_FLAG_BITS_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphOpticalFlowImageUsageFlagBitsARM; +typedef VkFlags VkDataGraphOpticalFlowImageUsageFlagsARM; + +typedef enum VkDataGraphOpticalFlowExecuteFlagBitsARM { + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_DISABLE_TEMPORAL_HINTS_BIT_ARM = 0x00000001, + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_INPUT_UNCHANGED_BIT_ARM = 0x00000002, + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_REFERENCE_UNCHANGED_BIT_ARM = 0x00000004, + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_INPUT_IS_PREVIOUS_REFERENCE_BIT_ARM = 0x00000008, + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_REFERENCE_IS_PREVIOUS_INPUT_BIT_ARM = 0x00000010, + VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_FLAG_BITS_MAX_ENUM_ARM = 0x7FFFFFFF +} VkDataGraphOpticalFlowExecuteFlagBitsARM; +typedef VkFlags VkDataGraphOpticalFlowExecuteFlagsARM; +typedef struct VkPhysicalDeviceDataGraphOpticalFlowFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 dataGraphOpticalFlow; +} VkPhysicalDeviceDataGraphOpticalFlowFeaturesARM; + +typedef struct VkQueueFamilyDataGraphOpticalFlowPropertiesARM { + VkStructureType sType; + void* pNext; + VkDataGraphOpticalFlowGridSizeFlagsARM supportedOutputGridSizes; + VkDataGraphOpticalFlowGridSizeFlagsARM supportedHintGridSizes; + VkBool32 hintSupported; + VkBool32 costSupported; + uint32_t minWidth; + uint32_t minHeight; + uint32_t maxWidth; + uint32_t maxHeight; +} VkQueueFamilyDataGraphOpticalFlowPropertiesARM; + +typedef struct VkDataGraphPipelineOpticalFlowCreateInfoARM { + VkStructureType sType; + void* pNext; + uint32_t width; + uint32_t height; + VkFormat imageFormat; + VkFormat flowVectorFormat; + VkFormat costFormat; + VkDataGraphOpticalFlowGridSizeFlagsARM outputGridSize; + VkDataGraphOpticalFlowGridSizeFlagsARM hintGridSize; + VkDataGraphOpticalFlowPerformanceLevelARM performanceLevel; + VkDataGraphOpticalFlowCreateFlagsARM flags; +} VkDataGraphPipelineOpticalFlowCreateInfoARM; + +typedef struct VkDataGraphOpticalFlowImageFormatPropertiesARM { + VkStructureType sType; + void* pNext; + VkFormat format; +} VkDataGraphOpticalFlowImageFormatPropertiesARM; + +typedef struct VkDataGraphOpticalFlowImageFormatInfoARM { + VkStructureType sType; + const void* pNext; + VkDataGraphOpticalFlowImageUsageFlagsARM usage; +} VkDataGraphOpticalFlowImageFormatInfoARM; + +typedef struct VkDataGraphPipelineOpticalFlowDispatchInfoARM { + VkStructureType sType; + void* pNext; + VkDataGraphOpticalFlowExecuteFlagsARM flags; + uint32_t meanFlowL1NormHint; +} VkDataGraphPipelineOpticalFlowDispatchInfoARM; + +typedef struct VkDataGraphPipelineResourceInfoImageLayoutARM { + VkStructureType sType; + const void* pNext; + VkImageLayout layout; +} VkDataGraphPipelineResourceInfoImageLayoutARM; + +typedef struct VkDataGraphPipelineSingleNodeConnectionARM { + VkStructureType sType; + void* pNext; + uint32_t set; + uint32_t binding; + VkDataGraphPipelineNodeConnectionTypeARM connection; +} VkDataGraphPipelineSingleNodeConnectionARM; + +typedef struct VkDataGraphPipelineSingleNodeCreateInfoARM { + VkStructureType sType; + void* pNext; + VkDataGraphPipelineNodeTypeARM nodeType; + uint32_t connectionCount; + const VkDataGraphPipelineSingleNodeConnectionARM* pConnections; +} VkDataGraphPipelineSingleNodeCreateInfoARM; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties, const VkDataGraphOpticalFlowImageFormatInfoARM* pOpticalFlowImageFormatInfo, uint32_t* pFormatCount, VkDataGraphOpticalFlowImageFormatPropertiesARM* pImageFormatProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + const VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties, + const VkDataGraphOpticalFlowImageFormatInfoARM* pOpticalFlowImageFormatInfo, + uint32_t* pFormatCount, + VkDataGraphOpticalFlowImageFormatPropertiesARM* pImageFormatProperties); +#endif +#endif + + +// VK_EXT_shader_long_vector is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_long_vector 1 +#define VK_EXT_SHADER_LONG_VECTOR_SPEC_VERSION 1 +#define VK_EXT_SHADER_LONG_VECTOR_EXTENSION_NAME "VK_EXT_shader_long_vector" +typedef struct VkPhysicalDeviceShaderLongVectorFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 longVector; +} VkPhysicalDeviceShaderLongVectorFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderLongVectorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxVectorComponents; +} VkPhysicalDeviceShaderLongVectorPropertiesEXT; + + + +// VK_SEC_pipeline_cache_incremental_mode is a preprocessor guard. Do not pass it to API calls. +#define VK_SEC_pipeline_cache_incremental_mode 1 +#define VK_SEC_PIPELINE_CACHE_INCREMENTAL_MODE_SPEC_VERSION 1 +#define VK_SEC_PIPELINE_CACHE_INCREMENTAL_MODE_EXTENSION_NAME "VK_SEC_pipeline_cache_incremental_mode" +typedef struct VkPhysicalDevicePipelineCacheIncrementalModeFeaturesSEC { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCacheIncrementalMode; +} VkPhysicalDevicePipelineCacheIncrementalModeFeaturesSEC; + + + +// VK_EXT_shader_uniform_buffer_unsized_array is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_uniform_buffer_unsized_array 1 +#define VK_EXT_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_SPEC_VERSION 1 +#define VK_EXT_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_EXTENSION_NAME "VK_EXT_shader_uniform_buffer_unsized_array" +typedef struct VkPhysicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderUniformBufferUnsizedArray; +} VkPhysicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT; + + + +// VK_NV_compute_occupancy_priority is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_compute_occupancy_priority 1 +#define VK_NV_COMPUTE_OCCUPANCY_PRIORITY_SPEC_VERSION 1 +#define VK_NV_COMPUTE_OCCUPANCY_PRIORITY_EXTENSION_NAME "VK_NV_compute_occupancy_priority" +#define VK_COMPUTE_OCCUPANCY_PRIORITY_LOW_NV 0.25f +#define VK_COMPUTE_OCCUPANCY_PRIORITY_NORMAL_NV 0.50f +#define VK_COMPUTE_OCCUPANCY_PRIORITY_HIGH_NV 0.75f +typedef struct VkComputeOccupancyPriorityParametersNV { + VkStructureType sType; + const void* pNext; + float occupancyPriority; + float occupancyThrottling; +} VkComputeOccupancyPriorityParametersNV; + +typedef struct VkPhysicalDeviceComputeOccupancyPriorityFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 computeOccupancyPriority; +} VkPhysicalDeviceComputeOccupancyPriorityFeaturesNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetComputeOccupancyPriorityNV)(VkCommandBuffer commandBuffer, const VkComputeOccupancyPriorityParametersNV* pParameters); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetComputeOccupancyPriorityNV( + VkCommandBuffer commandBuffer, + const VkComputeOccupancyPriorityParametersNV* pParameters); +#endif +#endif + + +// VK_EXT_shader_subgroup_partitioned is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_subgroup_partitioned 1 +#define VK_EXT_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_EXT_shader_subgroup_partitioned" +typedef struct VkPhysicalDeviceShaderSubgroupPartitionedFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupPartitioned; +} VkPhysicalDeviceShaderSubgroupPartitionedFeaturesEXT; + + + +// VK_VALVE_shader_mixed_float_dot_product is a preprocessor guard. Do not pass it to API calls. +#define VK_VALVE_shader_mixed_float_dot_product 1 +#define VK_VALVE_SHADER_MIXED_FLOAT_DOT_PRODUCT_SPEC_VERSION 1 +#define VK_VALVE_SHADER_MIXED_FLOAT_DOT_PRODUCT_EXTENSION_NAME "VK_VALVE_shader_mixed_float_dot_product" +typedef struct VkPhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 shaderMixedFloatDotProductFloat16AccFloat32; + VkBool32 shaderMixedFloatDotProductFloat16AccFloat16; + VkBool32 shaderMixedFloatDotProductBFloat16Acc; + VkBool32 shaderMixedFloatDotProductFloat8AccFloat32; +} VkPhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE; + + + +// VK_SEC_throttle_hint is a preprocessor guard. Do not pass it to API calls. +#define VK_SEC_throttle_hint 1 +#define VK_SEC_THROTTLE_HINT_SPEC_VERSION 1 +#define VK_SEC_THROTTLE_HINT_EXTENSION_NAME "VK_SEC_throttle_hint" + +typedef enum VkThrottleHintTypeSEC { + VK_THROTTLE_HINT_TYPE_DEFAULT_SEC = 0, + VK_THROTTLE_HINT_TYPE_LOW_SEC = 1, + VK_THROTTLE_HINT_TYPE_HIGH_SEC = 2, + VK_THROTTLE_HINT_TYPE_MAX_ENUM_SEC = 0x7FFFFFFF +} VkThrottleHintTypeSEC; +typedef struct VkThrottleHintSubmitInfoSEC { + VkStructureType sType; + const void* pNext; + VkThrottleHintTypeSEC throttleHint; +} VkThrottleHintSubmitInfoSEC; + +typedef struct VkPhysicalDeviceThrottleHintFeaturesSEC { + VkStructureType sType; + void* pNext; + VkBool32 throttleHint; +} VkPhysicalDeviceThrottleHintFeaturesSEC; + + + +// VK_ARM_data_graph_neural_accelerator_statistics is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_data_graph_neural_accelerator_statistics 1 +#define VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_SPEC_VERSION 1 +#define VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME "VK_ARM_data_graph_neural_accelerator_statistics" + +typedef enum VkNeuralAcceleratorStatisticsModeARM { + VK_NEURAL_ACCELERATOR_STATISTICS_MODE_DISABLED_ARM = 0, + VK_NEURAL_ACCELERATOR_STATISTICS_MODE_STATISTICS0_ARM = 1, + VK_NEURAL_ACCELERATOR_STATISTICS_MODE_STATISTICS1_ARM = 2, + VK_NEURAL_ACCELERATOR_STATISTICS_MODE_MAX_ENUM_ARM = 0x7FFFFFFF +} VkNeuralAcceleratorStatisticsModeARM; +typedef struct VkPhysicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 dataGraphNeuralAcceleratorStatistics; +} VkPhysicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM; + +typedef struct VkDataGraphPipelineNeuralStatisticsCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkBool32 allowNeuralStatistics; +} VkDataGraphPipelineNeuralStatisticsCreateInfoARM; + +typedef struct VkDataGraphPipelineSessionNeuralStatisticsCreateInfoARM { + VkStructureType sType; + const void* pNext; + VkNeuralAcceleratorStatisticsModeARM mode; +} VkDataGraphPipelineSessionNeuralStatisticsCreateInfoARM; + + + +// VK_EXT_primitive_restart_index is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_primitive_restart_index 1 +#define VK_EXT_PRIMITIVE_RESTART_INDEX_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVE_RESTART_INDEX_EXTENSION_NAME "VK_EXT_primitive_restart_index" +typedef struct VkPhysicalDevicePrimitiveRestartIndexFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 primitiveRestartIndex; +} VkPhysicalDevicePrimitiveRestartIndexFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartIndexEXT)(VkCommandBuffer commandBuffer, uint32_t primitiveRestartIndex); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartIndexEXT( + VkCommandBuffer commandBuffer, + uint32_t primitiveRestartIndex); +#endif +#endif + + +// VK_NV_cooperative_matrix_decode_vector is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cooperative_matrix_decode_vector 1 +#define VK_NV_COOPERATIVE_MATRIX_DECODE_VECTOR_SPEC_VERSION 1 +#define VK_NV_COOPERATIVE_MATRIX_DECODE_VECTOR_EXTENSION_NAME "VK_NV_cooperative_matrix_decode_vector" +typedef struct VkPhysicalDeviceCooperativeMatrixDecodeVectorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeMatrixDecodeVector; +} VkPhysicalDeviceCooperativeMatrixDecodeVectorFeaturesNV; + + + // VK_KHR_acceleration_structure is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_acceleration_structure 1 #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 @@ -19158,14 +26215,6 @@ typedef enum VkBuildAccelerationStructureModeKHR { VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1, VK_BUILD_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF } VkBuildAccelerationStructureModeKHR; - -typedef enum VkAccelerationStructureCreateFlagBitsKHR { - VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001, - VK_ACCELERATION_STRUCTURE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000008, - VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004, - VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureCreateFlagBitsKHR; -typedef VkFlags VkAccelerationStructureCreateFlagsKHR; typedef struct VkAccelerationStructureBuildRangeInfoKHR { uint32_t primitiveCount; uint32_t primitiveOffset; @@ -19304,14 +26353,6 @@ typedef struct VkCopyAccelerationStructureInfoKHR { VkCopyAccelerationStructureModeKHR mode; } VkCopyAccelerationStructureInfoKHR; -typedef struct VkAccelerationStructureBuildSizesInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize accelerationStructureSize; - VkDeviceSize updateScratchSize; - VkDeviceSize buildScratchSize; -} VkAccelerationStructureBuildSizesInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); @@ -19330,23 +26371,30 @@ typedef void (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(V typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureBuildSizesKHR)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR( VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR( VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresKHR( VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR( VkCommandBuffer commandBuffer, uint32_t infoCount, @@ -19354,29 +26402,39 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR( const VkDeviceAddress* pIndirectDeviceAddresses, const uint32_t* pIndirectStrides, const uint32_t* const* ppMaxPrimitiveCounts); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructuresKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( VkDevice device, uint32_t accelerationStructureCount, @@ -19385,23 +26443,33 @@ VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( size_t dataSize, void* pData, size_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR( VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR( VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR( VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR( VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, @@ -19409,12 +26477,16 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR( VkDevice device, const VkAccelerationStructureVersionInfoKHR* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR( VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, @@ -19422,6 +26494,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR( const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); #endif +#endif // VK_KHR_ray_tracing_pipeline is a preprocessor guard. Do not pass it to API calls. @@ -19494,12 +26567,6 @@ typedef struct VkPhysicalDeviceRayTracingPipelinePropertiesKHR { uint32_t maxRayHitAttributeSize; } VkPhysicalDeviceRayTracingPipelinePropertiesKHR; -typedef struct VkStridedDeviceAddressRegionKHR { - VkDeviceAddress deviceAddress; - VkDeviceSize stride; - VkDeviceSize size; -} VkStridedDeviceAddressRegionKHR; - typedef struct VkTraceRaysIndirectCommandKHR { uint32_t width; uint32_t height; @@ -19514,6 +26581,7 @@ typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupStackSizeKHR)(VkD typedef void (VKAPI_PTR *PFN_vkCmdSetRayTracingPipelineStackSizeKHR)(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, @@ -19523,7 +26591,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( uint32_t width, uint32_t height, uint32_t depth); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, @@ -19532,7 +26602,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( VkDevice device, VkPipeline pipeline, @@ -19540,7 +26612,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR uint32_t groupCount, size_t dataSize, void* pData); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, @@ -19548,17 +26622,22 @@ VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, VkDeviceAddress indirectDeviceAddress); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetRayTracingShaderGroupStackSizeKHR( VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRayTracingPipelineStackSizeKHR( VkCommandBuffer commandBuffer, uint32_t pipelineStackSize); #endif +#endif // VK_KHR_ray_query is a preprocessor guard. Do not pass it to API calls. @@ -19631,19 +26710,24 @@ typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectEXT)(VkCommandBuffer comm typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountEXT)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksEXT( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectEXT( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountEXT( VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -19653,6 +26737,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountEXT( uint32_t maxDrawCount, uint32_t stride); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_directfb.h b/src/video/khronos/vulkan/vulkan_directfb.h index f06f80b70e..b96e957e14 100644 --- a/src/video/khronos/vulkan/vulkan_directfb.h +++ b/src/video/khronos/vulkan/vulkan_directfb.h @@ -2,7 +2,7 @@ #define VULKAN_DIRECTFB_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,17 +36,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT( VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_fuchsia.h b/src/video/khronos/vulkan/vulkan_fuchsia.h index f60907d10b..ccca6271f3 100644 --- a/src/video/khronos/vulkan/vulkan_fuchsia.h +++ b/src/video/khronos/vulkan/vulkan_fuchsia.h @@ -2,7 +2,7 @@ #define VULKAN_FUCHSIA_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -34,12 +34,14 @@ typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA { typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_FUCHSIA_external_memory is a preprocessor guard. Do not pass it to API calls. @@ -70,17 +72,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA( VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); #endif +#endif // VK_FUCHSIA_external_semaphore is a preprocessor guard. Do not pass it to API calls. @@ -107,15 +113,19 @@ typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA( VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA( VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); #endif +#endif // VK_FUCHSIA_buffer_collection is a preprocessor guard. Do not pass it to API calls. @@ -228,32 +238,42 @@ typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, typedef VkResult (VKAPI_PTR *PFN_vkGetBufferCollectionPropertiesFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA( VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionImageConstraintsFUCHSIA( VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionBufferConstraintsFUCHSIA( VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA( VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferCollectionPropertiesFUCHSIA( VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_ggp.h b/src/video/khronos/vulkan/vulkan_ggp.h index 0a8863a14b..f8a48ec876 100644 --- a/src/video/khronos/vulkan/vulkan_ggp.h +++ b/src/video/khronos/vulkan/vulkan_ggp.h @@ -2,7 +2,7 @@ #define VULKAN_GGP_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -34,12 +34,14 @@ typedef struct VkStreamDescriptorSurfaceCreateInfoGGP { typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP( VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_GGP_frame_token is a preprocessor guard. Do not pass it to API calls. diff --git a/src/video/khronos/vulkan/vulkan_ios.h b/src/video/khronos/vulkan/vulkan_ios.h index 22ed2c039a..089991a4f6 100644 --- a/src/video/khronos/vulkan/vulkan_ios.h +++ b/src/video/khronos/vulkan/vulkan_ios.h @@ -2,7 +2,7 @@ #define VULKAN_IOS_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -34,12 +34,14 @@ typedef struct VkIOSSurfaceCreateInfoMVK { typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK( VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_macos.h b/src/video/khronos/vulkan/vulkan_macos.h index a7f5613a05..7d5d8a1b31 100644 --- a/src/video/khronos/vulkan/vulkan_macos.h +++ b/src/video/khronos/vulkan/vulkan_macos.h @@ -2,7 +2,7 @@ #define VULKAN_MACOS_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -34,12 +34,14 @@ typedef struct VkMacOSSurfaceCreateInfoMVK { typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK( VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_metal.h b/src/video/khronos/vulkan/vulkan_metal.h index 4cb9c69798..92f0c9a764 100644 --- a/src/video/khronos/vulkan/vulkan_metal.h +++ b/src/video/khronos/vulkan/vulkan_metal.h @@ -2,7 +2,7 @@ #define VULKAN_METAL_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -48,12 +48,14 @@ typedef struct VkMetalSurfaceCreateInfoEXT { typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif // VK_EXT_metal_objects is a preprocessor guard. Do not pass it to API calls. @@ -194,10 +196,57 @@ typedef struct VkImportMetalSharedEventInfoEXT { typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT( VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); #endif +#endif + + +// VK_EXT_external_memory_metal is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_external_memory_metal 1 +#define VK_EXT_EXTERNAL_MEMORY_METAL_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME "VK_EXT_external_memory_metal" +typedef struct VkImportMemoryMetalHandleInfoEXT { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + void* handle; +} VkImportMemoryMetalHandleInfoEXT; + +typedef struct VkMemoryMetalHandlePropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryMetalHandlePropertiesEXT; + +typedef struct VkMemoryGetMetalHandleInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetMetalHandleInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryMetalHandleEXT)(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, void** pHandle); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryMetalHandlePropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHandle, VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryMetalHandleEXT( + VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + void** pHandle); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryMetalHandlePropertiesEXT( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + const void* pHandle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties); +#endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_ohos.h b/src/video/khronos/vulkan/vulkan_ohos.h new file mode 100644 index 0000000000..3bde0114f5 --- /dev/null +++ b/src/video/khronos/vulkan/vulkan_ohos.h @@ -0,0 +1,120 @@ +#ifndef VULKAN_OHOS_H_ +#define VULKAN_OHOS_H_ 1 + +/* +** Copyright 2015-2026 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_OHOS_external_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_OHOS_external_memory 1 +struct OH_NativeBuffer; +#define VK_OHOS_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME "VK_OHOS_external_memory" +typedef struct VkNativeBufferUsageOHOS { + VkStructureType sType; + void* pNext; + uint64_t OHOSNativeBufferUsage; +} VkNativeBufferUsageOHOS; + +typedef struct VkNativeBufferPropertiesOHOS { + VkStructureType sType; + void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeBits; +} VkNativeBufferPropertiesOHOS; + +typedef struct VkNativeBufferFormatPropertiesOHOS { + VkStructureType sType; + void* pNext; + VkFormat format; + uint64_t externalFormat; + VkFormatFeatureFlags formatFeatures; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkNativeBufferFormatPropertiesOHOS; + +typedef struct VkImportNativeBufferInfoOHOS { + VkStructureType sType; + const void* pNext; + struct OH_NativeBuffer* buffer; +} VkImportNativeBufferInfoOHOS; + +typedef struct VkMemoryGetNativeBufferInfoOHOS { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkMemoryGetNativeBufferInfoOHOS; + +typedef struct VkExternalFormatOHOS { + VkStructureType sType; + void* pNext; + uint64_t externalFormat; +} VkExternalFormatOHOS; + +typedef VkResult (VKAPI_PTR *PFN_vkGetNativeBufferPropertiesOHOS)(VkDevice device, const struct OH_NativeBuffer* buffer, VkNativeBufferPropertiesOHOS* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryNativeBufferOHOS)(VkDevice device, const VkMemoryGetNativeBufferInfoOHOS* pInfo, struct OH_NativeBuffer** pBuffer); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetNativeBufferPropertiesOHOS( + VkDevice device, + const struct OH_NativeBuffer* buffer, + VkNativeBufferPropertiesOHOS* pProperties); +#endif + +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryNativeBufferOHOS( + VkDevice device, + const VkMemoryGetNativeBufferInfoOHOS* pInfo, + struct OH_NativeBuffer** pBuffer); +#endif +#endif + + +// VK_OHOS_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_OHOS_surface 1 +typedef struct NativeWindow OHNativeWindow; +#define VK_OHOS_SURFACE_SPEC_VERSION 1 +#define VK_OHOS_SURFACE_EXTENSION_NAME "VK_OHOS_surface" +typedef VkFlags VkSurfaceCreateFlagsOHOS; +typedef struct VkSurfaceCreateInfoOHOS { + VkStructureType sType; + const void* pNext; + VkSurfaceCreateFlagsOHOS flags; + OHNativeWindow* window; +} VkSurfaceCreateInfoOHOS; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSurfaceOHOS)(VkInstance instance, const VkSurfaceCreateInfoOHOS* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSurfaceOHOS( + VkInstance instance, + const VkSurfaceCreateInfoOHOS* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video/khronos/vulkan/vulkan_screen.h b/src/video/khronos/vulkan/vulkan_screen.h index 7e84d4d965..15e9d09028 100644 --- a/src/video/khronos/vulkan/vulkan_screen.h +++ b/src/video/khronos/vulkan/vulkan_screen.h @@ -2,7 +2,7 @@ #define VULKAN_SCREEN_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,17 +36,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX( VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window); #endif +#endif // VK_QNX_external_memory_screen_buffer is a preprocessor guard. Do not pass it to API calls. @@ -95,11 +99,13 @@ typedef struct VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX { typedef VkResult (VKAPI_PTR *PFN_vkGetScreenBufferPropertiesQNX)(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetScreenBufferPropertiesQNX( VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_vi.h b/src/video/khronos/vulkan/vulkan_vi.h index c145f4a800..97d1a3c5f9 100644 --- a/src/video/khronos/vulkan/vulkan_vi.h +++ b/src/video/khronos/vulkan/vulkan_vi.h @@ -2,7 +2,7 @@ #define VULKAN_VI_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -34,12 +34,14 @@ typedef struct VkViSurfaceCreateInfoNN { typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN( VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_wayland.h b/src/video/khronos/vulkan/vulkan_wayland.h index ec706a114b..41025db43b 100644 --- a/src/video/khronos/vulkan/vulkan_wayland.h +++ b/src/video/khronos/vulkan/vulkan_wayland.h @@ -2,7 +2,7 @@ #define VULKAN_WAYLAND_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,17 +36,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_win32.h b/src/video/khronos/vulkan/vulkan_win32.h index d7a0b2bab4..5c7e8bd6d7 100644 --- a/src/video/khronos/vulkan/vulkan_win32.h +++ b/src/video/khronos/vulkan/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,16 +36,20 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, c typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); #endif +#endif // VK_KHR_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. @@ -85,17 +89,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, con typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR( VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); #endif +#endif // VK_KHR_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. @@ -158,15 +166,19 @@ typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice devic typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR( VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); #endif +#endif // VK_KHR_external_fence_win32 is a preprocessor guard. Do not pass it to API calls. @@ -202,15 +214,19 @@ typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, c typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR( VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); #endif +#endif // VK_NV_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. @@ -234,12 +250,14 @@ typedef struct VkExportMemoryWin32HandleInfoNV { typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); #endif +#endif // VK_NV_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. @@ -296,25 +314,33 @@ typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice d typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT( VkDevice device, VkSwapchainKHR swapchain); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT( VkDevice device, VkSwapchainKHR swapchain); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT( VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes); #endif +#endif // VK_NV_acquire_winrt_display is a preprocessor guard. Do not pass it to API calls. @@ -325,15 +351,19 @@ typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physi typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV( VkPhysicalDevice physicalDevice, VkDisplayKHR display); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV( VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_xcb.h b/src/video/khronos/vulkan/vulkan_xcb.h index cdf6b5269f..473f8c2887 100644 --- a/src/video/khronos/vulkan/vulkan_xcb.h +++ b/src/video/khronos/vulkan/vulkan_xcb.h @@ -2,7 +2,7 @@ #define VULKAN_XCB_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,18 +36,22 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, con typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_xlib.h b/src/video/khronos/vulkan/vulkan_xlib.h index b3c3e27d77..dfd107c3e2 100644 --- a/src/video/khronos/vulkan/vulkan_xlib.h +++ b/src/video/khronos/vulkan/vulkan_xlib.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -36,18 +36,22 @@ typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, co typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); #endif +#endif #ifdef __cplusplus } diff --git a/src/video/khronos/vulkan/vulkan_xlib_xrandr.h b/src/video/khronos/vulkan/vulkan_xlib_xrandr.h index 8e99190b4f..a272e246ce 100644 --- a/src/video/khronos/vulkan/vulkan_xlib_xrandr.h +++ b/src/video/khronos/vulkan/vulkan_xlib_xrandr.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_XRANDR_H_ 1 /* -** Copyright 2015-2024 The Khronos Group Inc. +** Copyright 2015-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -27,17 +27,21 @@ typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physi typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); #ifndef VK_NO_PROTOTYPES +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT( VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); +#endif +#ifndef VK_ONLY_EXPORTED_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT( VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); #endif +#endif #ifdef __cplusplus } From 4aeac49311a15a187a8c999fc01b7fee73222edd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 11:55:50 +0300 Subject: [PATCH 337/407] update openxr headers from khronos. --- src/video/khronos/openxr/openxr.h | 4602 ++++++++++++++++- .../openxr/openxr_loader_negotiation.h | 2 +- src/video/khronos/openxr/openxr_platform.h | 65 +- .../khronos/openxr/openxr_platform_defines.h | 2 +- src/video/khronos/openxr/openxr_reflection.h | 3614 ++++++++++++- .../openxr/openxr_reflection_parent_structs.h | 99 +- .../openxr/openxr_reflection_structs.h | 854 +++ 7 files changed, 9202 insertions(+), 36 deletions(-) create mode 100644 src/video/khronos/openxr/openxr_reflection_structs.h diff --git a/src/video/khronos/openxr/openxr.h b/src/video/khronos/openxr/openxr.h index 3c82798e76..44aba6287c 100644 --- a/src/video/khronos/openxr/openxr.h +++ b/src/video/khronos/openxr/openxr.h @@ -2,7 +2,7 @@ #define OPENXR_H_ 1 /* -** Copyright 2017-2025 The Khronos Group Inc. +** Copyright 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -26,7 +26,7 @@ extern "C" { ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 45) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 59) // OpenXR 1.0 version number #define XR_API_VERSION_1_0 XR_MAKE_VERSION(1, 0, XR_VERSION_PATCH(XR_CURRENT_API_VERSION)) @@ -255,12 +255,41 @@ typedef enum XrResult { XR_ERROR_SPACE_NETWORK_TIMEOUT_FB = -1000169002, XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB = -1000169003, XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB = -1000169004, + XR_ERROR_SPACE_INSUFFICIENT_RESOURCES_META = -1000259000, + XR_ERROR_SPACE_STORAGE_AT_CAPACITY_META = -1000259001, + XR_ERROR_SPACE_INSUFFICIENT_VIEW_META = -1000259002, + XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META = -1000259003, + XR_ERROR_SPACE_RATE_LIMITED_META = -1000259004, + XR_ERROR_SPACE_TOO_DARK_META = -1000259005, + XR_ERROR_SPACE_TOO_BRIGHT_META = -1000259006, XR_ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META = -1000266000, XR_ENVIRONMENT_DEPTH_NOT_AVAILABLE_META = 1000291000, + XR_ERROR_RENDER_MODEL_ID_INVALID_EXT = -1000300000, + XR_ERROR_RENDER_MODEL_ASSET_UNAVAILABLE_EXT = -1000300001, + XR_ERROR_RENDER_MODEL_GLTF_EXTENSION_REQUIRED_EXT = -1000300002, + XR_ERROR_NOT_INTERACTION_RENDER_MODEL_EXT = -1000301000, XR_ERROR_HINT_ALREADY_SET_QCOM = -1000306000, XR_ERROR_NOT_AN_ANCHOR_HTC = -1000319000, + XR_ERROR_SPATIAL_ENTITY_ID_INVALID_BD = -1000389000, + XR_ERROR_SPATIAL_SENSING_SERVICE_UNAVAILABLE_BD = -1000389001, + XR_ERROR_ANCHOR_NOT_SUPPORTED_FOR_ENTITY_BD = -1000389002, + XR_ERROR_SPATIAL_ANCHOR_NOT_FOUND_BD = -1000390000, + XR_ERROR_SPATIAL_ANCHOR_SHARING_NETWORK_TIMEOUT_BD = -1000391000, + XR_ERROR_SPATIAL_ANCHOR_SHARING_AUTHENTICATION_FAILURE_BD = -1000391001, + XR_ERROR_SPATIAL_ANCHOR_SHARING_NETWORK_FAILURE_BD = -1000391002, + XR_ERROR_SPATIAL_ANCHOR_SHARING_LOCALIZATION_FAIL_BD = -1000391003, + XR_ERROR_SPATIAL_ANCHOR_SHARING_MAP_INSUFFICIENT_BD = -1000391004, + XR_ERROR_SCENE_CAPTURE_FAILURE_BD = -1000392000, XR_ERROR_SPACE_NOT_LOCATABLE_EXT = -1000429000, XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001, + XR_ERROR_MISMATCHING_TRACKABLE_TYPE_ANDROID = -1000455000, + XR_ERROR_TRACKABLE_TYPE_NOT_SUPPORTED_ANDROID = -1000455001, + XR_ERROR_ANCHOR_ID_NOT_FOUND_ANDROID = -1000457000, + XR_ERROR_ANCHOR_ALREADY_PERSISTED_ANDROID = -1000457001, + XR_ERROR_ANCHOR_NOT_TRACKING_ANDROID = -1000457002, + XR_ERROR_PERSISTED_DATA_NOT_READY_ANDROID = -1000457003, + XR_ERROR_SERVICE_NOT_READY_ANDROID = -1000458000, + XR_ERROR_MESH_DATA_LIMIT_EXCEEDED_ANDROID = -1000462000, XR_ERROR_FUTURE_PENDING_EXT = -1000469001, XR_ERROR_FUTURE_INVALID_EXT = -1000469002, XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML = -1000473000, @@ -268,11 +297,24 @@ typedef enum XrResult { XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML = -1000474000, XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML = -1000474001, XR_ERROR_FACIAL_EXPRESSION_PERMISSION_DENIED_ML = 1000482000, + XR_BOUNDARY_VISIBILITY_SUPPRESSION_NOT_ALLOWED_META = 1000528000, XR_ERROR_COLOCATION_DISCOVERY_NETWORK_FAILED_META = -1000571001, XR_ERROR_COLOCATION_DISCOVERY_NO_DISCOVERY_METHOD_META = -1000571002, XR_COLOCATION_DISCOVERY_ALREADY_ADVERTISING_META = 1000571003, XR_COLOCATION_DISCOVERY_ALREADY_DISCOVERING_META = 1000571004, XR_ERROR_SPACE_GROUP_NOT_FOUND_META = -1000572002, + XR_ERROR_ANCHOR_NOT_OWNED_BY_CALLER_ANDROID = -1000701000, + XR_ERROR_IMAGE_FORMAT_UNSUPPORTED_ANDROID = -1000709000, + XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT = -1000740001, + XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT = -1000740002, + XR_ERROR_SPATIAL_BUFFER_ID_INVALID_EXT = -1000740003, + XR_ERROR_SPATIAL_COMPONENT_UNSUPPORTED_FOR_CAPABILITY_EXT = -1000740004, + XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT = -1000740005, + XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT = -1000740006, + XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT = -1000763001, + XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_INCOMPATIBLE_EXT = -1000781001, + XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID = -1000790001, + XR_ERROR_SPATIAL_ANCHOR_ENTITY_ID_INVALID_ANDROID = -1000795001, XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED_KHR = XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED, XR_ERROR_PERMISSION_INSUFFICIENT_KHR = XR_ERROR_PERMISSION_INSUFFICIENT, XR_RESULT_MAX_ENUM = 0x7FFFFFFF @@ -605,8 +647,21 @@ typedef enum XrStructureType { XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB = 1000238001, XR_TYPE_SPACE_USER_CREATE_INFO_FB = 1000241001, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META = 1000245000, + XR_TYPE_SYSTEM_SPACE_DISCOVERY_PROPERTIES_META = 1000247000, + XR_TYPE_SPACE_DISCOVERY_INFO_META = 1000247001, + XR_TYPE_SPACE_FILTER_UUID_META = 1000247003, + XR_TYPE_SPACE_FILTER_COMPONENT_META = 1000247004, + XR_TYPE_SPACE_DISCOVERY_RESULT_META = 1000247005, + XR_TYPE_SPACE_DISCOVERY_RESULTS_META = 1000247006, + XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META = 1000247007, + XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META = 1000247008, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_META = 1000254000, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_GET_INFO_META = 1000254001, + XR_TYPE_SYSTEM_SPACE_PERSISTENCE_PROPERTIES_META = 1000259000, + XR_TYPE_SPACES_SAVE_INFO_META = 1000259001, + XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META = 1000259002, + XR_TYPE_SPACES_ERASE_INFO_META = 1000259003, + XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META = 1000259004, XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META = 1000266000, XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META = 1000266001, XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META = 1000266002, @@ -614,7 +669,13 @@ typedef enum XrStructureType { XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META = 1000266101, XR_TYPE_SPACE_TRIANGLE_MESH_GET_INFO_META = 1000269001, XR_TYPE_SPACE_TRIANGLE_MESH_META = 1000269002, + XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FULL_BODY_META = 1000274000, XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META = 1000282000, + XR_TYPE_BODY_TRACKING_CALIBRATION_INFO_META = 1000283002, + XR_TYPE_BODY_TRACKING_CALIBRATION_STATUS_META = 1000283003, + XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_CALIBRATION_META = 1000283004, + XR_TYPE_BODY_TRACKING_FIDELITY_STATUS_META = 1000284000, + XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FIDELITY_META = 1000284001, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES2_FB = 1000287013, XR_TYPE_FACE_TRACKER_CREATE_INFO2_FB = 1000287014, XR_TYPE_FACE_EXPRESSION_INFO2_FB = 1000287015, @@ -630,6 +691,22 @@ typedef enum XrStructureType { XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_META = 1000291005, XR_TYPE_ENVIRONMENT_DEPTH_HAND_REMOVAL_SET_INFO_META = 1000291006, XR_TYPE_SYSTEM_ENVIRONMENT_DEPTH_PROPERTIES_META = 1000291007, + XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_TIMESTAMP_META = 1000291008, + XR_TYPE_RENDER_MODEL_CREATE_INFO_EXT = 1000300000, + XR_TYPE_RENDER_MODEL_PROPERTIES_GET_INFO_EXT = 1000300001, + XR_TYPE_RENDER_MODEL_PROPERTIES_EXT = 1000300002, + XR_TYPE_RENDER_MODEL_SPACE_CREATE_INFO_EXT = 1000300003, + XR_TYPE_RENDER_MODEL_STATE_GET_INFO_EXT = 1000300004, + XR_TYPE_RENDER_MODEL_STATE_EXT = 1000300005, + XR_TYPE_RENDER_MODEL_ASSET_CREATE_INFO_EXT = 1000300006, + XR_TYPE_RENDER_MODEL_ASSET_DATA_GET_INFO_EXT = 1000300007, + XR_TYPE_RENDER_MODEL_ASSET_DATA_EXT = 1000300008, + XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_GET_INFO_EXT = 1000300009, + XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_EXT = 1000300010, + XR_TYPE_INTERACTION_RENDER_MODEL_IDS_ENUMERATE_INFO_EXT = 1000301000, + XR_TYPE_INTERACTION_RENDER_MODEL_SUBACTION_PATH_INFO_EXT = 1000301001, + XR_TYPE_EVENT_DATA_INTERACTION_RENDER_MODELS_CHANGED_EXT = 1000301002, + XR_TYPE_INTERACTION_RENDER_MODEL_TOP_LEVEL_USER_PATH_GET_INFO_EXT = 1000301003, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC = 1000317001, XR_TYPE_PASSTHROUGH_COLOR_HTC = 1000317002, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC = 1000317003, @@ -651,6 +728,63 @@ typedef enum XrStructureType { XR_TYPE_BODY_JOINTS_LOCATE_INFO_BD = 1000385002, XR_TYPE_BODY_JOINT_LOCATIONS_BD = 1000385003, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_BD = 1000385004, + XR_TYPE_SYSTEM_FACIAL_SIMULATION_PROPERTIES_BD = 1000386001, + XR_TYPE_FACE_TRACKER_CREATE_INFO_BD = 1000386002, + XR_TYPE_FACIAL_SIMULATION_DATA_GET_INFO_BD = 1000386003, + XR_TYPE_FACIAL_SIMULATION_DATA_BD = 1000386004, + XR_TYPE_LIP_EXPRESSION_DATA_BD = 1000386005, + XR_TYPE_SYSTEM_SPATIAL_SENSING_PROPERTIES_BD = 1000389000, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_GET_INFO_BD = 1000389001, + XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO_BD = 1000389002, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_LOCATION_BD = 1000389003, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_SEMANTIC_BD = 1000389004, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_2D_BD = 1000389005, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_POLYGON_BD = 1000389006, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_3D_BD = 1000389007, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_TRIANGLE_MESH_BD = 1000389008, + XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_BD = 1000389009, + XR_TYPE_SENSE_DATA_PROVIDER_START_INFO_BD = 1000389010, + XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED_BD = 1000389011, + XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED_BD = 1000389012, + XR_TYPE_SENSE_DATA_QUERY_INFO_BD = 1000389013, + XR_TYPE_SENSE_DATA_QUERY_COMPLETION_BD = 1000389014, + XR_TYPE_SENSE_DATA_FILTER_UUID_BD = 1000389015, + XR_TYPE_SENSE_DATA_FILTER_SEMANTIC_BD = 1000389016, + XR_TYPE_QUERIED_SENSE_DATA_GET_INFO_BD = 1000389017, + XR_TYPE_QUERIED_SENSE_DATA_BD = 1000389018, + XR_TYPE_SPATIAL_ENTITY_STATE_BD = 1000389019, + XR_TYPE_SPATIAL_ENTITY_ANCHOR_CREATE_INFO_BD = 1000389020, + XR_TYPE_ANCHOR_SPACE_CREATE_INFO_BD = 1000389021, + XR_TYPE_SYSTEM_SPATIAL_ANCHOR_PROPERTIES_BD = 1000390000, + XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_BD = 1000390001, + XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION_BD = 1000390002, + XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO_BD = 1000390003, + XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO_BD = 1000390004, + XR_TYPE_SYSTEM_SPATIAL_ANCHOR_SHARING_PROPERTIES_BD = 1000391000, + XR_TYPE_SPATIAL_ANCHOR_SHARE_INFO_BD = 1000391001, + XR_TYPE_SHARED_SPATIAL_ANCHOR_DOWNLOAD_INFO_BD = 1000391002, + XR_TYPE_SYSTEM_SPATIAL_SCENE_PROPERTIES_BD = 1000392000, + XR_TYPE_SCENE_CAPTURE_INFO_BD = 1000392001, + XR_TYPE_SYSTEM_SPATIAL_MESH_PROPERTIES_BD = 1000393000, + XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_MESH_BD = 1000393001, + XR_TYPE_FUTURE_POLL_RESULT_PROGRESS_BD = 1000394001, + XR_TYPE_SYSTEM_SPATIAL_PLANE_PROPERTIES_BD = 1000396000, + XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_PLANE_ORIENTATION_BD = 1000396001, + XR_TYPE_SENSE_DATA_FILTER_PLANE_ORIENTATION_BD = 1000396002, + XR_TYPE_SPATIAL_AUDIO_RENDERER_CREATE_INFO_BD = 1000409000, + XR_TYPE_AUDIO_BUFFER_BD = 1000409001, + XR_TYPE_SOUND_OBJECT_DIRECTIVITY_CARDIOID_BD = 1000409003, + XR_TYPE_SOUND_OBJECT_SHAPE_SPHERE_BD = 1000409004, + XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_BD = 1000409005, + XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_CURVE_BD = 1000409006, + XR_TYPE_SOUND_OBJECT_CONFIG_BD = 1000409007, + XR_TYPE_SOUND_FIELD_CONFIG_BD = 1000409008, + XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_SURROUND_BD = 1000409009, + XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_AMBIX_BD = 1000409010, + XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_FUMA_BD = 1000409011, + XR_TYPE_SOUND_TRIANGLE_MESH_BD = 1000409012, + XR_TYPE_SOUND_OBSTACLE_CONFIG_BD = 1000409013, + XR_TYPE_SOUND_OBSTACLE_MATERIAL_CONFIG_BD = 1000409014, XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT = 1000428000, XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT = 1000428001, XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT = 1000429001, @@ -660,6 +794,36 @@ typedef enum XrStructureType { XR_TYPE_PLANE_DETECTOR_LOCATION_EXT = 1000429005, XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT = 1000429006, XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT = 1000429007, + XR_TYPE_TRACKABLE_GET_INFO_ANDROID = 1000455000, + XR_TYPE_ANCHOR_SPACE_CREATE_INFO_ANDROID = 1000455001, + XR_TYPE_TRACKABLE_PLANE_ANDROID = 1000455003, + XR_TYPE_TRACKABLE_TRACKER_CREATE_INFO_ANDROID = 1000455004, + XR_TYPE_SYSTEM_TRACKABLES_PROPERTIES_ANDROID = 1000455005, + XR_TYPE_EYES_ANDROID = 1000456000, + XR_TYPE_EYE_TRACKER_CREATE_INFO_ANDROID = 1000456001, + XR_TYPE_EYES_GET_INFO_ANDROID = 1000456002, + XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_ANDROID = 1000456004, + XR_TYPE_PERSISTED_ANCHOR_SPACE_CREATE_INFO_ANDROID = 1000457001, + XR_TYPE_PERSISTED_ANCHOR_SPACE_INFO_ANDROID = 1000457002, + XR_TYPE_DEVICE_ANCHOR_PERSISTENCE_CREATE_INFO_ANDROID = 1000457003, + XR_TYPE_SYSTEM_DEVICE_ANCHOR_PERSISTENCE_PROPERTIES_ANDROID = 1000457004, + XR_TYPE_FACE_TRACKER_CREATE_INFO_ANDROID = 1000458000, + XR_TYPE_FACE_STATE_GET_INFO_ANDROID = 1000458001, + XR_TYPE_FACE_STATE_ANDROID = 1000458002, + XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_ANDROID = 1000458003, + XR_TYPE_PASSTHROUGH_CAMERA_STATE_GET_INFO_ANDROID = 1000460000, + XR_TYPE_SYSTEM_PASSTHROUGH_CAMERA_STATE_PROPERTIES_ANDROID = 1000460001, + XR_TYPE_EVENT_DATA_RECOMMENDED_RESOLUTION_CHANGED_ANDROID = 1000461000, + XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_ANDROID = 1000462000, + XR_TYPE_PASSTHROUGH_LAYER_MESH_ANDROID = 1000462001, + XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_ANDROID = 1000462002, + XR_TYPE_SYSTEM_PASSTHROUGH_LAYER_PROPERTIES_ANDROID = 1000462003, + XR_TYPE_RAYCAST_INFO_ANDROID = 1000463000, + XR_TYPE_RAYCAST_HIT_RESULTS_ANDROID = 1000463001, + XR_TYPE_PERFORMANCE_METRICS_STATE_ANDROID = 1000465000, + XR_TYPE_PERFORMANCE_METRICS_COUNTER_ANDROID = 1000465001, + XR_TYPE_TRACKABLE_OBJECT_ANDROID = 1000466000, + XR_TYPE_TRACKABLE_OBJECT_CONFIGURATION_ANDROID = 1000466001, XR_TYPE_FUTURE_CANCEL_INFO_EXT = 1000469000, XR_TYPE_FUTURE_POLL_INFO_EXT = 1000469001, XR_TYPE_FUTURE_COMPLETION_EXT = 1000469002, @@ -683,6 +847,16 @@ typedef enum XrStructureType { XR_TYPE_FACIAL_EXPRESSION_CLIENT_CREATE_INFO_ML = 1000482005, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_GET_INFO_ML = 1000482006, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_ML = 1000482007, + XR_TYPE_SYSTEM_BOUNDARY_VISIBILITY_PROPERTIES_META = 1000528000, + XR_TYPE_EVENT_DATA_BOUNDARY_VISIBILITY_CHANGED_META = 1000528001, + XR_TYPE_SYSTEM_SIMULTANEOUS_HANDS_AND_CONTROLLERS_PROPERTIES_META = 1000532001, + XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_RESUME_INFO_META = 1000532002, + XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_PAUSE_INFO_META = 1000532003, + XR_TYPE_FACE_TRACKING_VISEMES_META = 1000541000, + XR_TYPE_SYSTEM_FACE_TRACKING_VISEMES_PROPERTIES_META = 1000541001, + XR_TYPE_ROOM_MESH_FACE_INDICES_META = 1000553000, + XR_TYPE_SPACE_ROOM_MESH_GET_INFO_META = 1000553001, + XR_TYPE_ROOM_MESH_META = 1000553002, XR_TYPE_COLOCATION_DISCOVERY_START_INFO_META = 1000571010, XR_TYPE_COLOCATION_DISCOVERY_STOP_INFO_META = 1000571011, XR_TYPE_COLOCATION_ADVERTISEMENT_START_INFO_META = 1000571012, @@ -698,6 +872,99 @@ typedef enum XrStructureType { XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META = 1000572000, XR_TYPE_SPACE_GROUP_UUID_FILTER_INFO_META = 1000572001, XR_TYPE_SYSTEM_SPATIAL_ENTITY_GROUP_SHARING_PROPERTIES_META = 1000572100, + XR_TYPE_SYSTEM_ENVIRONMENT_RAYCAST_PROPERTIES_META = 1000592000, + XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_INFO_META = 1000592001, + XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_COMPLETION_META = 1000592002, + XR_TYPE_ENVIRONMENT_RAYCAST_HIT_GET_INFO_META = 1000592003, + XR_TYPE_ENVIRONMENT_RAYCAST_HIT_META = 1000592004, + XR_TYPE_ENVIRONMENT_RAYCAST_FILTER_DISTANCE_META = 1000592005, + XR_TYPE_TILE_PROPERTIES_META = 1000609000, + XR_TYPE_TILE_PROPERTIES_HINT_META = 1000609001, + XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID = 1000700000, + XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID = 1000700001, + XR_TYPE_LIGHT_ESTIMATE_ANDROID = 1000700002, + XR_TYPE_DIRECTIONAL_LIGHT_ANDROID = 1000700003, + XR_TYPE_SPHERICAL_HARMONICS_ANDROID = 1000700004, + XR_TYPE_AMBIENT_LIGHT_ANDROID = 1000700005, + XR_TYPE_SYSTEM_LIGHT_ESTIMATION_PROPERTIES_ANDROID = 1000700006, + XR_TYPE_ANCHOR_SHARING_INFO_ANDROID = 1000701000, + XR_TYPE_ANCHOR_SHARING_TOKEN_ANDROID = 1000701001, + XR_TYPE_SYSTEM_ANCHOR_SHARING_EXPORT_PROPERTIES_ANDROID = 1000701002, + XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_ANDROID = 1000707000, + XR_TYPE_TRACKABLE_MARKER_CONFIGURATION_ANDROID = 1000707001, + XR_TYPE_TRACKABLE_MARKER_ANDROID = 1000707002, + XR_TYPE_SYSTEM_QR_CODE_TRACKING_PROPERTIES_ANDROID = 1000708000, + XR_TYPE_TRACKABLE_QR_CODE_CONFIGURATION_ANDROID = 1000708001, + XR_TYPE_TRACKABLE_QR_CODE_ANDROID = 1000708002, + XR_TYPE_SYSTEM_IMAGE_TRACKING_PROPERTIES_ANDROID = 1000709000, + XR_TYPE_TRACKABLE_IMAGE_DATABASE_ENTRY_ANDROID = 1000709001, + XR_TYPE_TRACKABLE_IMAGE_DATABASE_CREATE_INFO_ANDROID = 1000709002, + XR_TYPE_CREATE_TRACKABLE_IMAGE_DATABASE_COMPLETION_ANDROID = 1000709003, + XR_TYPE_TRACKABLE_IMAGE_CONFIGURATION_ANDROID = 1000709004, + XR_TYPE_TRACKABLE_IMAGE_ANDROID = 1000709005, + XR_TYPE_EVENT_DATA_IMAGE_TRACKING_LOST_ANDROID = 1000709006, + XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID = 1000718000, + XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID = 1000718001, + XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID = 1000718002, + XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID = 1000718003, + XR_TYPE_SCENE_SUBMESH_STATE_ANDROID = 1000718004, + XR_TYPE_SCENE_SUBMESH_DATA_ANDROID = 1000718005, + XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT = 1000740000, + XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT = 1000740001, + XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT = 1000740002, + XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT = 1000740003, + XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT = 1000740004, + XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT = 1000740005, + XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT = 1000740006, + XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT = 1000740007, + XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT = 1000740008, + XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT = 1000740009, + XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT = 1000740010, + XR_TYPE_SPATIAL_COMPONENT_PARENT_LIST_EXT = 1000740011, + XR_TYPE_SPATIAL_COMPONENT_MESH_3D_LIST_EXT = 1000740012, + XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT = 1000740013, + XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT = 1000740014, + XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT = 1000740015, + XR_TYPE_SPATIAL_FILTER_TRACKING_STATE_EXT = 1000740016, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT = 1000741000, + XR_TYPE_SPATIAL_COMPONENT_PLANE_ALIGNMENT_LIST_EXT = 1000741001, + XR_TYPE_SPATIAL_COMPONENT_MESH_2D_LIST_EXT = 1000741002, + XR_TYPE_SPATIAL_COMPONENT_POLYGON_2D_LIST_EXT = 1000741003, + XR_TYPE_SPATIAL_COMPONENT_PLANE_SEMANTIC_LABEL_LIST_EXT = 1000741004, + XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_GET_INFO_EXT = 1000742001, + XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_RESULT_EXT = 1000742002, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT = 1000743000, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT = 1000743001, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT = 1000743002, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT = 1000743003, + XR_TYPE_SPATIAL_MARKER_SIZE_EXT = 1000743004, + XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT = 1000743005, + XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT = 1000743006, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT = 1000762000, + XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT = 1000762001, + XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT = 1000762002, + XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT = 1000763000, + XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT = 1000763001, + XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT = 1000763002, + XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT = 1000763003, + XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT = 1000763004, + XR_TYPE_SPATIAL_ENTITY_PERSIST_INFO_EXT = 1000781000, + XR_TYPE_PERSIST_SPATIAL_ENTITY_COMPLETION_EXT = 1000781001, + XR_TYPE_SPATIAL_ENTITY_UNPERSIST_INFO_EXT = 1000781002, + XR_TYPE_UNPERSIST_SPATIAL_ENTITY_COMPLETION_EXT = 1000781003, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID = 1000785000, + XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID = 1000785001, + XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID = 1000786000, + XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID = 1000786001, + XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID = 1000786002, + XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID = 1000786003, + XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID = 1000790000, + XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID = 1000791001, + XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID = 1000791002, + XR_TYPE_SPATIAL_ANCHOR_SPACE_FROM_ID_CREATE_INFO_ANDROID = 1000795000, + XR_TYPE_BATTERY_STATE_DISPLAY_EXT = 1000836000, + XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT = 1000838000, + XR_TYPE_EVENT_DATA_VIEW_CONFIGURATION_VIEWS_CHANGED_EXT = 1000839000, XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR, @@ -738,6 +1005,8 @@ typedef enum XrReferenceSpaceType { XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT = 1000038000, XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO = 1000121000, XR_REFERENCE_SPACE_TYPE_LOCALIZATION_MAP_ML = 1000139000, + XR_REFERENCE_SPACE_TYPE_UNBOUNDED_ANDROID = 1000467000, + XR_REFERENCE_SPACE_TYPE_STATIONARY_EXT = 1000742000, XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT = XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR, XR_REFERENCE_SPACE_TYPE_MAX_ENUM = 0x7FFFFFFF } XrReferenceSpaceType; @@ -804,12 +1073,37 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_FACE_TRACKER2_FB = 1000287012, XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META = 1000291000, XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META = 1000291001, + XR_OBJECT_TYPE_RENDER_MODEL_EXT = 1000300000, + XR_OBJECT_TYPE_RENDER_MODEL_ASSET_EXT = 1000300001, XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000, XR_OBJECT_TYPE_BODY_TRACKER_HTC = 1000320000, XR_OBJECT_TYPE_BODY_TRACKER_BD = 1000385000, + XR_OBJECT_TYPE_FACE_TRACKER_BD = 1000386000, + XR_OBJECT_TYPE_SENSE_DATA_PROVIDER_BD = 1000389000, + XR_OBJECT_TYPE_SENSE_DATA_SNAPSHOT_BD = 1000389001, + XR_OBJECT_TYPE_ANCHOR_BD = 1000389002, + XR_OBJECT_TYPE_SPATIAL_AUDIO_RENDERER_BD = 1000409000, + XR_OBJECT_TYPE_SOUND_FIELD_BD = 1000409001, + XR_OBJECT_TYPE_SOUND_OBJECT_BD = 1000409002, + XR_OBJECT_TYPE_SOUND_OBSTACLE_BD = 1000409003, + XR_OBJECT_TYPE_SOUND_OBSTACLE_MATERIAL_BD = 1000409004, XR_OBJECT_TYPE_PLANE_DETECTOR_EXT = 1000429000, + XR_OBJECT_TYPE_TRACKABLE_TRACKER_ANDROID = 1000455001, + XR_OBJECT_TYPE_EYE_TRACKER_ANDROID = 1000456000, + XR_OBJECT_TYPE_DEVICE_ANCHOR_PERSISTENCE_ANDROID = 1000457000, + XR_OBJECT_TYPE_FACE_TRACKER_ANDROID = 1000458000, + XR_OBJECT_TYPE_PASSTHROUGH_LAYER_ANDROID = 1000462000, XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML = 1000474000, XR_OBJECT_TYPE_FACIAL_EXPRESSION_CLIENT_ML = 1000482000, + XR_OBJECT_TYPE_ENVIRONMENT_RAYCASTER_META = 1000592000, + XR_OBJECT_TYPE_LIGHT_ESTIMATOR_ANDROID = 1000700000, + XR_OBJECT_TYPE_TRACKABLE_IMAGE_DATABASE_ANDROID = 1000709000, + XR_OBJECT_TYPE_SCENE_MESHING_TRACKER_ANDROID = 1000718000, + XR_OBJECT_TYPE_SCENE_MESH_SNAPSHOT_ANDROID = 1000718001, + XR_OBJECT_TYPE_SPATIAL_ENTITY_EXT = 1000740000, + XR_OBJECT_TYPE_SPATIAL_CONTEXT_EXT = 1000740001, + XR_OBJECT_TYPE_SPATIAL_SNAPSHOT_EXT = 1000740002, + XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT = 1000763000, XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } XrObjectType; typedef XrFlags64 XrInstanceCreateFlags; @@ -856,6 +1150,7 @@ static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_KHR = typedef XrFlags64 XrCompositionLayerFlags; // Flag bits for XrCompositionLayerFlags +// XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT is deprecated and should not be used static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT = 0x00000001; static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT = 0x00000002; static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT = 0x00000004; @@ -1993,6 +2288,23 @@ typedef struct XrBindingModificationsKHR { +// XR_KHR_extended_struct_name_lengths is a preprocessor guard. Do not pass it to API calls. +#define XR_KHR_extended_struct_name_lengths 1 +#define XR_KHR_extended_struct_name_lengths_SPEC_VERSION 2 +#define XR_KHR_EXTENDED_STRUCT_NAME_LENGTHS_EXTENSION_NAME "XR_KHR_extended_struct_name_lengths" +#define XR_MAX_STRUCTURE_NAME_SIZE_EXTENDED_KHR 256 +typedef XrResult (XRAPI_PTR *PFN_xrStructureTypeToString2KHR)(XrInstance instance, XrStructureType value, char buffer[XR_MAX_STRUCTURE_NAME_SIZE_EXTENDED_KHR]); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrStructureTypeToString2KHR( + XrInstance instance, + XrStructureType value, + char buffer[XR_MAX_STRUCTURE_NAME_SIZE_EXTENDED_KHR]); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_KHR_swapchain_usage_input_attachment_bit is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_swapchain_usage_input_attachment_bit 1 #define XR_KHR_swapchain_usage_input_attachment_bit_SPEC_VERSION 3 @@ -2041,6 +2353,12 @@ typedef XrFrustumf XrFrustumfKHR; +// XR_KHR_generic_controller is a preprocessor guard. Do not pass it to API calls. +#define XR_KHR_generic_controller 1 +#define XR_KHR_generic_controller_SPEC_VERSION 1 +#define XR_KHR_GENERIC_CONTROLLER_EXTENSION_NAME "XR_KHR_generic_controller" + + // XR_EXT_performance_settings is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_performance_settings 1 #define XR_EXT_performance_settings_SPEC_VERSION 4 @@ -2368,7 +2686,7 @@ typedef struct XrCompositionLayerAlphaBlendFB { // XR_MND_headless is a preprocessor guard. Do not pass it to API calls. #define XR_MND_headless 1 -#define XR_MND_headless_SPEC_VERSION 2 +#define XR_MND_headless_SPEC_VERSION 3 #define XR_MND_HEADLESS_EXTENSION_NAME "XR_MND_headless" @@ -3054,6 +3372,7 @@ typedef enum XrBodyJointFB { typedef enum XrBodyJointSetFB { XR_BODY_JOINT_SET_DEFAULT_FB = 0, + XR_BODY_JOINT_SET_FULL_BODY_META = 1000274000, XR_BODY_JOINT_SET_MAX_ENUM_FB = 0x7FFFFFFF } XrBodyJointSetFB; typedef struct XrBodyJointLocationFB { @@ -3451,6 +3770,7 @@ typedef struct XrSceneMeshBuffersMSFT { void* XR_MAY_ALIAS next; } XrSceneMeshBuffersMSFT; +// XrSceneMeshVertexBufferMSFT extends XrSceneMeshBuffersMSFT typedef struct XrSceneMeshVertexBufferMSFT { XrStructureType type; void* XR_MAY_ALIAS next; @@ -3459,6 +3779,7 @@ typedef struct XrSceneMeshVertexBufferMSFT { XrVector3f* vertices; } XrSceneMeshVertexBufferMSFT; +// XrSceneMeshIndicesUint32MSFT extends XrSceneMeshBuffersMSFT typedef struct XrSceneMeshIndicesUint32MSFT { XrStructureType type; void* XR_MAY_ALIAS next; @@ -3467,6 +3788,7 @@ typedef struct XrSceneMeshIndicesUint32MSFT { uint32_t* indices; } XrSceneMeshIndicesUint32MSFT; +// XrSceneMeshIndicesUint16MSFT extends XrSceneMeshBuffersMSFT typedef struct XrSceneMeshIndicesUint16MSFT { XrStructureType type; void* XR_MAY_ALIAS next; @@ -3953,6 +4275,7 @@ typedef enum XrSpaceComponentTypeFB { XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB = 6, XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB = 7, XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META = 1000269000, + XR_SPACE_COMPONENT_TYPE_ROOM_MESH_META = 1000553000, XR_SPACE_COMPONENT_TYPE_MAX_ENUM_FB = 0x7FFFFFFF } XrSpaceComponentTypeFB; // XrSystemSpatialEntityPropertiesFB extends XrSystemProperties @@ -4264,7 +4587,7 @@ XR_DEFINE_HANDLE(XrPassthroughFB) XR_DEFINE_HANDLE(XrPassthroughLayerFB) XR_DEFINE_HANDLE(XrGeometryInstanceFB) #define XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB 256 -#define XR_FB_passthrough_SPEC_VERSION 4 +#define XR_FB_passthrough_SPEC_VERSION 5 #define XR_FB_PASSTHROUGH_EXTENSION_NAME "XR_FB_passthrough" typedef enum XrPassthroughLayerPurposeFB { @@ -5792,6 +6115,7 @@ typedef struct XrBoundary2DFB { XrVector2f* vertices; } XrBoundary2DFB; +// XrSemanticLabelsSupportInfoFB extends XrSemanticLabelsFB typedef struct XrSemanticLabelsSupportInfoFB { XrStructureType type; const void* XR_MAY_ALIAS next; @@ -6728,6 +7052,12 @@ XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpaceListFB( #endif /* !XR_NO_PROTOTYPES */ +// XR_META_detached_controllers is a preprocessor guard. Do not pass it to API calls. +#define XR_META_detached_controllers 1 +#define XR_META_detached_controllers_SPEC_VERSION 1 +#define XR_META_DETACHED_CONTROLLERS_EXTENSION_NAME "XR_META_detached_controllers" + + // XR_FB_spatial_entity_user is a preprocessor guard. Do not pass it to API calls. #define XR_FB_spatial_entity_user 1 typedef uint64_t XrSpaceUserIdFB; @@ -6773,6 +7103,92 @@ typedef struct XrSystemHeadsetIdPropertiesMETA { +// XR_META_spatial_entity_discovery is a preprocessor guard. Do not pass it to API calls. +#define XR_META_spatial_entity_discovery 1 +#define XR_META_spatial_entity_discovery_SPEC_VERSION 1 +#define XR_META_SPATIAL_ENTITY_DISCOVERY_EXTENSION_NAME "XR_META_spatial_entity_discovery" +// XrSystemSpaceDiscoveryPropertiesMETA extends XrSystemProperties +typedef struct XrSystemSpaceDiscoveryPropertiesMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 supportsSpaceDiscovery; +} XrSystemSpaceDiscoveryPropertiesMETA; + +typedef struct XR_MAY_ALIAS XrSpaceFilterBaseHeaderMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpaceFilterBaseHeaderMETA; + +typedef struct XrSpaceDiscoveryInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t filterCount; + const XrSpaceFilterBaseHeaderMETA* const * filters; +} XrSpaceDiscoveryInfoMETA; + +typedef struct XrSpaceFilterUuidMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCount; + const XrUuidEXT* uuids; +} XrSpaceFilterUuidMETA; + +typedef struct XrSpaceFilterComponentMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceComponentTypeFB componentType; +} XrSpaceFilterComponentMETA; + +typedef struct XrSpaceDiscoveryResultMETA { + XrSpace space; + XrUuidEXT uuid; +} XrSpaceDiscoveryResultMETA; + +typedef struct XrSpaceDiscoveryResultsMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t resultCapacityInput; + uint32_t resultCountOutput; + XrSpaceDiscoveryResultMETA* results; +} XrSpaceDiscoveryResultsMETA; + +typedef struct XrEventDataSpaceDiscoveryResultsAvailableMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; +} XrEventDataSpaceDiscoveryResultsAvailableMETA; + +typedef struct XrEventDataSpaceDiscoveryCompleteMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceDiscoveryCompleteMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrDiscoverSpacesMETA)(XrSession session, const XrSpaceDiscoveryInfoMETA* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrRetrieveSpaceDiscoveryResultsMETA)(XrSession session, XrAsyncRequestIdFB requestId, XrSpaceDiscoveryResultsMETA* results); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrDiscoverSpacesMETA( + XrSession session, + const XrSpaceDiscoveryInfoMETA* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrRetrieveSpaceDiscoveryResultsMETA( + XrSession session, + XrAsyncRequestIdFB requestId, + XrSpaceDiscoveryResultsMETA* results); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_META_hand_tracking_microgestures is a preprocessor guard. Do not pass it to API calls. +#define XR_META_hand_tracking_microgestures 1 +#define XR_META_hand_tracking_microgestures_SPEC_VERSION 1 +#define XR_META_HAND_TRACKING_MICROGESTURES_EXTENSION_NAME "XR_META_hand_tracking_microgestures" + + // XR_META_recommended_layer_resolution is a preprocessor guard. Do not pass it to API calls. #define XR_META_recommended_layer_resolution 1 #define XR_META_recommended_layer_resolution_SPEC_VERSION 1 @@ -6803,6 +7219,65 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetRecommendedLayerResolutionMETA( #endif /* !XR_NO_PROTOTYPES */ +// XR_META_spatial_entity_persistence is a preprocessor guard. Do not pass it to API calls. +#define XR_META_spatial_entity_persistence 1 +#define XR_META_spatial_entity_persistence_SPEC_VERSION 1 +#define XR_META_SPATIAL_ENTITY_PERSISTENCE_EXTENSION_NAME "XR_META_spatial_entity_persistence" +// XrSystemSpacePersistencePropertiesMETA extends XrSystemProperties +typedef struct XrSystemSpacePersistencePropertiesMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 supportsSpacePersistence; +} XrSystemSpacePersistencePropertiesMETA; + +typedef struct XrSpacesSaveInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; +} XrSpacesSaveInfoMETA; + +typedef struct XrEventDataSpacesSaveResultMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpacesSaveResultMETA; + +typedef struct XrSpacesEraseInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; + uint32_t uuidCount; + XrUuidEXT* uuids; +} XrSpacesEraseInfoMETA; + +typedef struct XrEventDataSpacesEraseResultMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpacesEraseResultMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrSaveSpacesMETA)(XrSession session, const XrSpacesSaveInfoMETA* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrEraseSpacesMETA)(XrSession session, const XrSpacesEraseInfoMETA* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpacesMETA( + XrSession session, + const XrSpacesSaveInfoMETA* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrEraseSpacesMETA( + XrSession session, + const XrSpacesEraseInfoMETA* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_META_passthrough_color_lut is a preprocessor guard. Do not pass it to API calls. #define XR_META_passthrough_color_lut 1 XR_DEFINE_HANDLE(XrPassthroughColorLutMETA) @@ -6916,6 +7391,109 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceTriangleMeshMETA( #define XR_META_AUTOMATIC_LAYER_FILTER_EXTENSION_NAME "XR_META_automatic_layer_filter" +// XR_META_body_tracking_full_body is a preprocessor guard. Do not pass it to API calls. +#define XR_META_body_tracking_full_body 1 +#define XR_META_body_tracking_full_body_SPEC_VERSION 1 +#define XR_META_BODY_TRACKING_FULL_BODY_EXTENSION_NAME "XR_META_body_tracking_full_body" + +typedef enum XrFullBodyJointMETA { + XR_FULL_BODY_JOINT_ROOT_META = 0, + XR_FULL_BODY_JOINT_HIPS_META = 1, + XR_FULL_BODY_JOINT_SPINE_LOWER_META = 2, + XR_FULL_BODY_JOINT_SPINE_MIDDLE_META = 3, + XR_FULL_BODY_JOINT_SPINE_UPPER_META = 4, + XR_FULL_BODY_JOINT_CHEST_META = 5, + XR_FULL_BODY_JOINT_NECK_META = 6, + XR_FULL_BODY_JOINT_HEAD_META = 7, + XR_FULL_BODY_JOINT_LEFT_SHOULDER_META = 8, + XR_FULL_BODY_JOINT_LEFT_SCAPULA_META = 9, + XR_FULL_BODY_JOINT_LEFT_ARM_UPPER_META = 10, + XR_FULL_BODY_JOINT_LEFT_ARM_LOWER_META = 11, + XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_TWIST_META = 12, + XR_FULL_BODY_JOINT_RIGHT_SHOULDER_META = 13, + XR_FULL_BODY_JOINT_RIGHT_SCAPULA_META = 14, + XR_FULL_BODY_JOINT_RIGHT_ARM_UPPER_META = 15, + XR_FULL_BODY_JOINT_RIGHT_ARM_LOWER_META = 16, + XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_META = 17, + XR_FULL_BODY_JOINT_LEFT_HAND_PALM_META = 18, + XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_META = 19, + XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_META = 20, + XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_META = 21, + XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_META = 22, + XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_TIP_META = 23, + XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_META = 24, + XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_META = 25, + XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_META = 26, + XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_META = 27, + XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_TIP_META = 28, + XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_META = 29, + XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_META = 30, + XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_META = 31, + XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_META = 32, + XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_META = 33, + XR_FULL_BODY_JOINT_LEFT_HAND_RING_METACARPAL_META = 34, + XR_FULL_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_META = 35, + XR_FULL_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_META = 36, + XR_FULL_BODY_JOINT_LEFT_HAND_RING_DISTAL_META = 37, + XR_FULL_BODY_JOINT_LEFT_HAND_RING_TIP_META = 38, + XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_META = 39, + XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_META = 40, + XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_META = 41, + XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_META = 42, + XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_TIP_META = 43, + XR_FULL_BODY_JOINT_RIGHT_HAND_PALM_META = 44, + XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_META = 45, + XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_META = 46, + XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_META = 47, + XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_META = 48, + XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_TIP_META = 49, + XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_META = 50, + XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_META = 51, + XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_META = 52, + XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_META = 53, + XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_TIP_META = 54, + XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_META = 55, + XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_META = 56, + XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_META = 57, + XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_META = 58, + XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_META = 59, + XR_FULL_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_META = 60, + XR_FULL_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_META = 61, + XR_FULL_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_META = 62, + XR_FULL_BODY_JOINT_RIGHT_HAND_RING_DISTAL_META = 63, + XR_FULL_BODY_JOINT_RIGHT_HAND_RING_TIP_META = 64, + XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_META = 65, + XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_META = 66, + XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_META = 67, + XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_META = 68, + XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_META = 69, + XR_FULL_BODY_JOINT_LEFT_UPPER_LEG_META = 70, + XR_FULL_BODY_JOINT_LEFT_LOWER_LEG_META = 71, + XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_TWIST_META = 72, + XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_META = 73, + XR_FULL_BODY_JOINT_LEFT_FOOT_SUBTALAR_META = 74, + XR_FULL_BODY_JOINT_LEFT_FOOT_TRANSVERSE_META = 75, + XR_FULL_BODY_JOINT_LEFT_FOOT_BALL_META = 76, + XR_FULL_BODY_JOINT_RIGHT_UPPER_LEG_META = 77, + XR_FULL_BODY_JOINT_RIGHT_LOWER_LEG_META = 78, + XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_TWIST_META = 79, + XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_META = 80, + XR_FULL_BODY_JOINT_RIGHT_FOOT_SUBTALAR_META = 81, + XR_FULL_BODY_JOINT_RIGHT_FOOT_TRANSVERSE_META = 82, + XR_FULL_BODY_JOINT_RIGHT_FOOT_BALL_META = 83, + XR_FULL_BODY_JOINT_COUNT_META = 84, + XR_FULL_BODY_JOINT_NONE_META = 85, + XR_FULL_BODY_JOINT_MAX_ENUM_META = 0x7FFFFFFF +} XrFullBodyJointMETA; +// XrSystemPropertiesBodyTrackingFullBodyMETA extends XrSystemProperties +typedef struct XrSystemPropertiesBodyTrackingFullBodyMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFullBodyTracking; +} XrSystemPropertiesBodyTrackingFullBodyMETA; + + + // XR_META_touch_controller_plus is a preprocessor guard. Do not pass it to API calls. #define XR_META_touch_controller_plus 1 #define XR_META_touch_controller_plus_SPEC_VERSION 1 @@ -6934,6 +7512,87 @@ typedef struct XrEventDataPassthroughLayerResumedMETA { +// XR_META_body_tracking_calibration is a preprocessor guard. Do not pass it to API calls. +#define XR_META_body_tracking_calibration 1 +#define XR_META_body_tracking_calibration_SPEC_VERSION 1 +#define XR_META_BODY_TRACKING_CALIBRATION_EXTENSION_NAME "XR_META_body_tracking_calibration" + +typedef enum XrBodyTrackingCalibrationStateMETA { + XR_BODY_TRACKING_CALIBRATION_STATE_VALID_META = 1, + XR_BODY_TRACKING_CALIBRATION_STATE_CALIBRATING_META = 2, + XR_BODY_TRACKING_CALIBRATION_STATE_INVALID_META = 3, + XR_BODY_TRACKING_CALIBRATION_STATE_MAX_ENUM_META = 0x7FFFFFFF +} XrBodyTrackingCalibrationStateMETA; +// XrBodyTrackingCalibrationStatusMETA extends XrBodyJointLocationsFB +typedef struct XrBodyTrackingCalibrationStatusMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBodyTrackingCalibrationStateMETA status; +} XrBodyTrackingCalibrationStatusMETA; + +typedef struct XrBodyTrackingCalibrationInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float bodyHeight; +} XrBodyTrackingCalibrationInfoMETA; + +// XrSystemPropertiesBodyTrackingCalibrationMETA extends XrSystemProperties +typedef struct XrSystemPropertiesBodyTrackingCalibrationMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsHeightOverride; +} XrSystemPropertiesBodyTrackingCalibrationMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrSuggestBodyTrackingCalibrationOverrideMETA)(XrBodyTrackerFB bodyTracker, const XrBodyTrackingCalibrationInfoMETA* calibrationInfo); +typedef XrResult (XRAPI_PTR *PFN_xrResetBodyTrackingCalibrationMETA)(XrBodyTrackerFB bodyTracker); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSuggestBodyTrackingCalibrationOverrideMETA( + XrBodyTrackerFB bodyTracker, + const XrBodyTrackingCalibrationInfoMETA* calibrationInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrResetBodyTrackingCalibrationMETA( + XrBodyTrackerFB bodyTracker); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_META_body_tracking_fidelity is a preprocessor guard. Do not pass it to API calls. +#define XR_META_body_tracking_fidelity 1 +#define XR_META_body_tracking_fidelity_SPEC_VERSION 1 +#define XR_META_BODY_TRACKING_FIDELITY_EXTENSION_NAME "XR_META_body_tracking_fidelity" + +typedef enum XrBodyTrackingFidelityMETA { + XR_BODY_TRACKING_FIDELITY_LOW_META = 1, + XR_BODY_TRACKING_FIDELITY_HIGH_META = 2, + XR_BODY_TRACKING_FIDELITY_MAX_ENUM_META = 0x7FFFFFFF +} XrBodyTrackingFidelityMETA; +// XrSystemPropertiesBodyTrackingFidelityMETA extends XrSystemProperties +typedef struct XrSystemPropertiesBodyTrackingFidelityMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsBodyTrackingFidelity; +} XrSystemPropertiesBodyTrackingFidelityMETA; + +// XrBodyTrackingFidelityStatusMETA extends XrBodyJointLocationsFB +typedef struct XrBodyTrackingFidelityStatusMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBodyTrackingFidelityMETA fidelity; +} XrBodyTrackingFidelityStatusMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrRequestBodyTrackingFidelityMETA)(XrBodyTrackerFB bodyTracker, const XrBodyTrackingFidelityMETA fidelity); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrRequestBodyTrackingFidelityMETA( + XrBodyTrackerFB bodyTracker, + const XrBodyTrackingFidelityMETA fidelity); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_FB_face_tracking2 is a preprocessor guard. Do not pass it to API calls. #define XR_FB_face_tracking2 1 XR_DEFINE_HANDLE(XrFaceTracker2FB) @@ -7137,7 +7796,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrShareSpacesMETA( #define XR_META_environment_depth 1 XR_DEFINE_HANDLE(XrEnvironmentDepthProviderMETA) XR_DEFINE_HANDLE(XrEnvironmentDepthSwapchainMETA) -#define XR_META_environment_depth_SPEC_VERSION 1 +#define XR_META_environment_depth_SPEC_VERSION 2 #define XR_META_ENVIRONMENT_DEPTH_EXTENSION_NAME "XR_META_environment_depth" typedef XrFlags64 XrEnvironmentDepthProviderCreateFlagsMETA; @@ -7189,6 +7848,13 @@ typedef struct XrEnvironmentDepthImageMETA { XrEnvironmentDepthImageViewMETA views[2]; } XrEnvironmentDepthImageMETA; +// XrEnvironmentDepthImageTimestampMETA extends XrEnvironmentDepthImageMETA +typedef struct XrEnvironmentDepthImageTimestampMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime captureTime; +} XrEnvironmentDepthImageTimestampMETA; + typedef struct XrEnvironmentDepthHandRemovalSetInfoMETA { XrStructureType type; const void* XR_MAY_ALIAS next; @@ -7267,9 +7933,207 @@ XRAPI_ATTR XrResult XRAPI_CALL xrSetEnvironmentDepthHandRemovalMETA( #define XR_UUID_SIZE_EXT 16 +// XR_EXT_render_model is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_render_model 1 +XR_DEFINE_ATOM(XrRenderModelIdEXT) +XR_DEFINE_HANDLE(XrRenderModelEXT) +XR_DEFINE_HANDLE(XrRenderModelAssetEXT) +#define XR_MAX_RENDER_MODEL_ASSET_NODE_NAME_SIZE_EXT 64 +#define XR_EXT_render_model_SPEC_VERSION 1 +#define XR_EXT_RENDER_MODEL_EXTENSION_NAME "XR_EXT_render_model" +#define XR_NULL_RENDER_MODEL_ID_EXT 0 +typedef struct XrRenderModelCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrRenderModelIdEXT renderModelId; + uint32_t gltfExtensionCount; + const char* const* gltfExtensions; +} XrRenderModelCreateInfoEXT; + +typedef struct XrRenderModelPropertiesGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrRenderModelPropertiesGetInfoEXT; + +typedef struct XrRenderModelPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT cacheId; + uint32_t animatableNodeCount; +} XrRenderModelPropertiesEXT; + +typedef struct XrRenderModelSpaceCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrRenderModelEXT renderModel; +} XrRenderModelSpaceCreateInfoEXT; + +typedef struct XrRenderModelStateGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime displayTime; +} XrRenderModelStateGetInfoEXT; + +typedef struct XrRenderModelNodeStateEXT { + XrPosef nodePose; + XrBool32 isVisible; +} XrRenderModelNodeStateEXT; + +typedef struct XrRenderModelStateEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t nodeStateCount; + XrRenderModelNodeStateEXT* nodeStates; +} XrRenderModelStateEXT; + +typedef struct XrRenderModelAssetCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidEXT cacheId; +} XrRenderModelAssetCreateInfoEXT; + +typedef struct XrRenderModelAssetDataGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrRenderModelAssetDataGetInfoEXT; + +typedef struct XrRenderModelAssetDataEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + uint8_t* buffer; +} XrRenderModelAssetDataEXT; + +typedef struct XrRenderModelAssetPropertiesGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrRenderModelAssetPropertiesGetInfoEXT; + +typedef struct XrRenderModelAssetNodePropertiesEXT { + char uniqueName[XR_MAX_RENDER_MODEL_ASSET_NODE_NAME_SIZE_EXT]; +} XrRenderModelAssetNodePropertiesEXT; + +typedef struct XrRenderModelAssetPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t nodePropertyCount; + XrRenderModelAssetNodePropertiesEXT* nodeProperties; +} XrRenderModelAssetPropertiesEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateRenderModelEXT)(XrSession session, const XrRenderModelCreateInfoEXT* createInfo, XrRenderModelEXT* renderModel); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyRenderModelEXT)(XrRenderModelEXT renderModel); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelPropertiesEXT)(XrRenderModelEXT renderModel, const XrRenderModelPropertiesGetInfoEXT* getInfo, XrRenderModelPropertiesEXT* properties); +typedef XrResult (XRAPI_PTR *PFN_xrCreateRenderModelSpaceEXT)(XrSession session, const XrRenderModelSpaceCreateInfoEXT* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrCreateRenderModelAssetEXT)(XrSession session, const XrRenderModelAssetCreateInfoEXT* createInfo, XrRenderModelAssetEXT* asset); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyRenderModelAssetEXT)(XrRenderModelAssetEXT asset); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelAssetDataEXT)(XrRenderModelAssetEXT asset, const XrRenderModelAssetDataGetInfoEXT* getInfo, XrRenderModelAssetDataEXT* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelAssetPropertiesEXT)(XrRenderModelAssetEXT asset, const XrRenderModelAssetPropertiesGetInfoEXT* getInfo, XrRenderModelAssetPropertiesEXT* properties); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelStateEXT)(XrRenderModelEXT renderModel, const XrRenderModelStateGetInfoEXT* getInfo, XrRenderModelStateEXT* state); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateRenderModelEXT( + XrSession session, + const XrRenderModelCreateInfoEXT* createInfo, + XrRenderModelEXT* renderModel); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyRenderModelEXT( + XrRenderModelEXT renderModel); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelPropertiesEXT( + XrRenderModelEXT renderModel, + const XrRenderModelPropertiesGetInfoEXT* getInfo, + XrRenderModelPropertiesEXT* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateRenderModelSpaceEXT( + XrSession session, + const XrRenderModelSpaceCreateInfoEXT* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateRenderModelAssetEXT( + XrSession session, + const XrRenderModelAssetCreateInfoEXT* createInfo, + XrRenderModelAssetEXT* asset); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyRenderModelAssetEXT( + XrRenderModelAssetEXT asset); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelAssetDataEXT( + XrRenderModelAssetEXT asset, + const XrRenderModelAssetDataGetInfoEXT* getInfo, + XrRenderModelAssetDataEXT* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelAssetPropertiesEXT( + XrRenderModelAssetEXT asset, + const XrRenderModelAssetPropertiesGetInfoEXT* getInfo, + XrRenderModelAssetPropertiesEXT* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelStateEXT( + XrRenderModelEXT renderModel, + const XrRenderModelStateGetInfoEXT* getInfo, + XrRenderModelStateEXT* state); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_interaction_render_model is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_interaction_render_model 1 +#define XR_EXT_interaction_render_model_SPEC_VERSION 1 +#define XR_EXT_INTERACTION_RENDER_MODEL_EXTENSION_NAME "XR_EXT_interaction_render_model" +typedef struct XrInteractionRenderModelIdsEnumerateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrInteractionRenderModelIdsEnumerateInfoEXT; + +typedef struct XrInteractionRenderModelSubactionPathInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrInteractionRenderModelSubactionPathInfoEXT; + +typedef struct XrInteractionRenderModelTopLevelUserPathGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t topLevelUserPathCount; + const XrPath* topLevelUserPaths; +} XrInteractionRenderModelTopLevelUserPathGetInfoEXT; + +typedef struct XrEventDataInteractionRenderModelsChangedEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEventDataInteractionRenderModelsChangedEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateInteractionRenderModelIdsEXT)(XrSession session, const XrInteractionRenderModelIdsEnumerateInfoEXT* getInfo, uint32_t renderModelIdCapacityInput, uint32_t* renderModelIdCountOutput, XrRenderModelIdEXT* renderModelIds); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateRenderModelSubactionPathsEXT)(XrRenderModelEXT renderModel, const XrInteractionRenderModelSubactionPathInfoEXT* info, uint32_t pathCapacityInput, uint32_t* pathCountOutput, XrPath* paths); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelPoseTopLevelUserPathEXT)(XrRenderModelEXT renderModel, const XrInteractionRenderModelTopLevelUserPathGetInfoEXT* info, XrPath* topLevelUserPath); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateInteractionRenderModelIdsEXT( + XrSession session, + const XrInteractionRenderModelIdsEnumerateInfoEXT* getInfo, + uint32_t renderModelIdCapacityInput, + uint32_t* renderModelIdCountOutput, + XrRenderModelIdEXT* renderModelIds); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateRenderModelSubactionPathsEXT( + XrRenderModelEXT renderModel, + const XrInteractionRenderModelSubactionPathInfoEXT* info, + uint32_t pathCapacityInput, + uint32_t* pathCountOutput, + XrPath* paths); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelPoseTopLevelUserPathEXT( + XrRenderModelEXT renderModel, + const XrInteractionRenderModelTopLevelUserPathGetInfoEXT* info, + XrPath* topLevelUserPath); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_EXT_hand_interaction is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_hand_interaction 1 -#define XR_EXT_hand_interaction_SPEC_VERSION 1 +#define XR_EXT_hand_interaction_SPEC_VERSION 2 #define XR_EXT_HAND_INTERACTION_EXTENSION_NAME "XR_EXT_hand_interaction" @@ -7303,6 +8167,36 @@ XRAPI_ATTR XrResult XRAPI_CALL xrSetTrackingOptimizationSettingsHintQCOM( #endif /* !XR_NO_PROTOTYPES */ +// XR_QCOM_hand_tracking_gesture is a preprocessor guard. Do not pass it to API calls. +#define XR_QCOM_hand_tracking_gesture 1 +#define XR_QCOM_hand_tracking_gesture_SPEC_VERSION 1 +#define XR_QCOM_HAND_TRACKING_GESTURE_EXTENSION_NAME "XR_QCOM_hand_tracking_gesture" + +typedef enum XrHandGestureTypeQCOM { + XR_HAND_GESTURE_TYPE_UNKNOWN_QCOM = -1, + XR_HAND_GESTURE_TYPE_OPEN_HAND_QCOM = 0, + XR_HAND_GESTURE_TYPE_GRAB_QCOM = 2, + XR_HAND_GESTURE_TYPE_PINCH_QCOM = 7, + XR_HAND_GESTURE_TYPE_MAX_ENUM_QCOM = 0x7FFFFFFF +} XrHandGestureTypeQCOM; +typedef struct XrHandGestureQCOM { + XrHandGestureTypeQCOM gesture; + float gestureRatio; + float flipRatio; +} XrHandGestureQCOM; + +typedef XrResult (XRAPI_PTR *PFN_xrGetHandGestureQCOM)(XrHandTrackerEXT handTracker, XrTime time, XrHandGestureQCOM* handGesture); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetHandGestureQCOM( + XrHandTrackerEXT handTracker, + XrTime time, + XrHandGestureQCOM* handGesture); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_HTC_passthrough is a preprocessor guard. Do not pass it to API calls. #define XR_HTC_passthrough 1 XR_DEFINE_HANDLE(XrPassthroughHTC) @@ -7766,6 +8660,1175 @@ XRAPI_ATTR XrResult XRAPI_CALL xrLocateBodyJointsBD( #endif /* !XR_NO_PROTOTYPES */ +// XR_BD_facial_simulation is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_facial_simulation 1 + +#define XR_FACE_EXPRESSION_COUNT_BD 52 + + +#define XR_LIP_EXPRESSION_COUNT_BD 20 + + XR_DEFINE_HANDLE(XrFaceTrackerBD) +#define XR_BD_facial_simulation_SPEC_VERSION 1 +#define XR_BD_FACIAL_SIMULATION_EXTENSION_NAME "XR_BD_facial_simulation" + +typedef enum XrFacialSimulationModeBD { + XR_FACIAL_SIMULATION_MODE_DEFAULT_BD = 0, + XR_FACIAL_SIMULATION_MODE_COMBINED_AUDIO_BD = 1, + XR_FACIAL_SIMULATION_MODE_COMBINED_AUDIO_WITH_LIP_BD = 2, + XR_FACIAL_SIMULATION_MODE_ONLY_AUDIO_WITH_LIP_BD = 3, + XR_FACIAL_SIMULATION_MODE_MAX_ENUM_BD = 0x7FFFFFFF +} XrFacialSimulationModeBD; + +typedef enum XrFaceExpressionBD { + XR_FACE_EXPRESSION_BROW_DROP_L_BD = 0, + XR_FACE_EXPRESSION_BROW_DROP_R_BD = 1, + XR_FACE_EXPRESSION_BROW_INNER_UPWARDS_BD = 2, + XR_FACE_EXPRESSION_BROW_OUTER_UPWARDS_L_BD = 3, + XR_FACE_EXPRESSION_BROW_OUTER_UPWARDS_R_BD = 4, + XR_FACE_EXPRESSION_EYE_BLINK_L_BD = 5, + XR_FACE_EXPRESSION_EYE_LOOK_DROP_L_BD = 6, + XR_FACE_EXPRESSION_EYE_LOOK_IN_L_BD = 7, + XR_FACE_EXPRESSION_EYE_LOOK_OUT_L_BD = 8, + XR_FACE_EXPRESSION_EYE_LOOK_UPWARDS_L_BD = 9, + XR_FACE_EXPRESSION_EYE_LOOK_SQUINT_L_BD = 10, + XR_FACE_EXPRESSION_EYE_LOOK_WIDE_L_BD = 11, + XR_FACE_EXPRESSION_EYE_BLINK_R_BD = 12, + XR_FACE_EXPRESSION_EYE_LOOK_DROP_R_BD = 13, + XR_FACE_EXPRESSION_EYE_LOOK_IN_R_BD = 14, + XR_FACE_EXPRESSION_EYE_LOOK_OUT_R_BD = 15, + XR_FACE_EXPRESSION_EYE_LOOK_UPWARDS_R_BD = 16, + XR_FACE_EXPRESSION_EYE_LOOK_SQUINT_R_BD = 17, + XR_FACE_EXPRESSION_EYE_LOOK_WIDE_R_BD = 18, + XR_FACE_EXPRESSION_NOSE_SNEER_L_BD = 19, + XR_FACE_EXPRESSION_NOSE_SNEER_R_BD = 20, + XR_FACE_EXPRESSION_CHEEK_PUFF_BD = 21, + XR_FACE_EXPRESSION_CHEEK_SQUINT_L_BD = 22, + XR_FACE_EXPRESSION_CHEEK_SQUINT_R_BD = 23, + XR_FACE_EXPRESSION_MOUTH_CLOSE_BD = 24, + XR_FACE_EXPRESSION_MOUTH_FUNNEL_BD = 25, + XR_FACE_EXPRESSION_MOUTH_PUCKER_BD = 26, + XR_FACE_EXPRESSION_MOUTH_L_BD = 27, + XR_FACE_EXPRESSION_MOUTH_R_BD = 28, + XR_FACE_EXPRESSION_MOUTH_SMILE_L_BD = 29, + XR_FACE_EXPRESSION_MOUTH_SMILE_R_BD = 30, + XR_FACE_EXPRESSION_MOUTH_FROWN_L_BD = 31, + XR_FACE_EXPRESSION_MOUTH_FROWN_R_BD = 32, + XR_FACE_EXPRESSION_MOUTH_DIMPLE_L_BD = 33, + XR_FACE_EXPRESSION_MOUTH_DIMPLE_R_BD = 34, + XR_FACE_EXPRESSION_MOUTH_STRETCH_L_BD = 35, + XR_FACE_EXPRESSION_MOUTH_STRETCH_R_BD = 36, + XR_FACE_EXPRESSION_MOUTH_ROLL_LOWER_BD = 37, + XR_FACE_EXPRESSION_MOUTH_ROLL_UPPER_BD = 38, + XR_FACE_EXPRESSION_MOUTH_SHRUG_LOWER_BD = 39, + XR_FACE_EXPRESSION_MOUTH_SHRUG_UPPER_BD = 40, + XR_FACE_EXPRESSION_MOUTH_PRESS_L_BD = 41, + XR_FACE_EXPRESSION_MOUTH_PRESS_R_BD = 42, + XR_FACE_EXPRESSION_MOUTH_LOWER_DROP_L_BD = 43, + XR_FACE_EXPRESSION_MOUTH_LOWER_DROP_R_BD = 44, + XR_FACE_EXPRESSION_MOUTH_UPPER_UPWARDS_L_BD = 45, + XR_FACE_EXPRESSION_MOUTH_UPPER_UPWARDS_R_BD = 46, + XR_FACE_EXPRESSION_JAW_FORWARD_BD = 47, + XR_FACE_EXPRESSION_JAW_L_BD = 48, + XR_FACE_EXPRESSION_JAW_R_BD = 49, + XR_FACE_EXPRESSION_JAW_OPEN_BD = 50, + XR_FACE_EXPRESSION_TONGUE_OUT_BD = 51, + XR_FACE_EXPRESSION_MAX_ENUM_BD = 0x7FFFFFFF +} XrFaceExpressionBD; + +typedef enum XrLipExpressionBD { + XR_LIP_EXPRESSION_PP_BD = 0, + XR_LIP_EXPRESSION_CH_BD = 1, + XR_LIP_EXPRESSION_LO_BD = 2, + XR_LIP_EXPRESSION_O_BD = 3, + XR_LIP_EXPRESSION_I_BD = 4, + XR_LIP_EXPRESSION_LU_BD = 5, + XR_LIP_EXPRESSION_RR_BD = 6, + XR_LIP_EXPRESSION_XX_BD = 7, + XR_LIP_EXPRESSION_LAA_BD = 8, + XR_LIP_EXPRESSION_LI_BD = 9, + XR_LIP_EXPRESSION_FF_BD = 10, + XR_LIP_EXPRESSION_U_BD = 11, + XR_LIP_EXPRESSION_TH_BD = 12, + XR_LIP_EXPRESSION_LKK_BD = 13, + XR_LIP_EXPRESSION_SS_BD = 14, + XR_LIP_EXPRESSION_LE_BD = 15, + XR_LIP_EXPRESSION_DD_BD = 16, + XR_LIP_EXPRESSION_E_BD = 17, + XR_LIP_EXPRESSION_LNN_BD = 18, + XR_LIP_EXPRESSION_SIL_BD = 19, + XR_LIP_EXPRESSION_MAX_ENUM_BD = 0x7FFFFFFF +} XrLipExpressionBD; +// XrSystemFacialSimulationPropertiesBD extends XrSystemProperties +typedef struct XrSystemFacialSimulationPropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFaceTracking; +} XrSystemFacialSimulationPropertiesBD; + +typedef struct XrFaceTrackerCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFacialSimulationModeBD mode; +} XrFaceTrackerCreateInfoBD; + +typedef struct XrFacialSimulationDataGetInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; +} XrFacialSimulationDataGetInfoBD; + +typedef struct XrFacialSimulationDataBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t faceExpressionWeightCount; + float* faceExpressionWeights; + XrBool32 isUpperFaceDataValid; + XrBool32 isLowerFaceDataValid; + XrTime time; +} XrFacialSimulationDataBD; + +// XrLipExpressionDataBD extends XrFacialSimulationDataBD +typedef struct XrLipExpressionDataBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t lipsyncExpressionWeightCount; + float* lipsyncExpressionWeights; +} XrLipExpressionDataBD; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateFacialSimulationModesBD)(XrSession session, uint32_t modeCapacityInput, uint32_t* modeCountOutput, XrFacialSimulationModeBD* modes); +typedef XrResult (XRAPI_PTR *PFN_xrCreateFaceTrackerBD)(XrSession session, const XrFaceTrackerCreateInfoBD* createInfo, XrFaceTrackerBD* tracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFaceTrackerBD)(XrFaceTrackerBD tracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFacialSimulationDataBD)(XrFaceTrackerBD tracker, const XrFacialSimulationDataGetInfoBD*info, XrFacialSimulationDataBD* facialData); +typedef XrResult (XRAPI_PTR *PFN_xrSetFacialSimulationModeBD)(XrFaceTrackerBD tracker, XrFacialSimulationModeBD mode); +typedef XrResult (XRAPI_PTR *PFN_xrGetFacialSimulationModeBD)(XrFaceTrackerBD tracker, XrFacialSimulationModeBD*mode); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateFacialSimulationModesBD( + XrSession session, + uint32_t modeCapacityInput, + uint32_t* modeCountOutput, + XrFacialSimulationModeBD* modes); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFaceTrackerBD( + XrSession session, + const XrFaceTrackerCreateInfoBD* createInfo, + XrFaceTrackerBD* tracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFaceTrackerBD( + XrFaceTrackerBD tracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFacialSimulationDataBD( + XrFaceTrackerBD tracker, + const XrFacialSimulationDataGetInfoBD* info, + XrFacialSimulationDataBD* facialData); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetFacialSimulationModeBD( + XrFaceTrackerBD tracker, + XrFacialSimulationModeBD mode); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFacialSimulationModeBD( + XrFaceTrackerBD tracker, + XrFacialSimulationModeBD* mode); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_BD_spatial_sensing is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_sensing 1 +XR_DEFINE_ATOM(XrSpatialEntityIdBD) +XR_DEFINE_HANDLE(XrSenseDataProviderBD) +XR_DEFINE_HANDLE(XrSenseDataSnapshotBD) +XR_DEFINE_HANDLE(XrAnchorBD) +#define XR_BD_spatial_sensing_SPEC_VERSION 1 +#define XR_BD_SPATIAL_SENSING_EXTENSION_NAME "XR_BD_spatial_sensing" + +typedef enum XrSpatialEntityComponentTypeBD { + XR_SPATIAL_ENTITY_COMPONENT_TYPE_LOCATION_BD = 0, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_SEMANTIC_BD = 1, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_BOUNDING_BOX_2D_BD = 2, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_POLYGON_BD = 3, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_BOUNDING_BOX_3D_BD = 4, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_TRIANGLE_MESH_BD = 5, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_PLANE_ORIENTATION_BD = 1000396000, + XR_SPATIAL_ENTITY_COMPONENT_TYPE_MAX_ENUM_BD = 0x7FFFFFFF +} XrSpatialEntityComponentTypeBD; + +typedef enum XrSemanticLabelBD { + XR_SEMANTIC_LABEL_UNKNOWN_BD = 0, + XR_SEMANTIC_LABEL_FLOOR_BD = 1, + XR_SEMANTIC_LABEL_CEILING_BD = 2, + XR_SEMANTIC_LABEL_WALL_BD = 3, + XR_SEMANTIC_LABEL_DOOR_BD = 4, + XR_SEMANTIC_LABEL_WINDOW_BD = 5, + XR_SEMANTIC_LABEL_OPENING_BD = 6, + XR_SEMANTIC_LABEL_TABLE_BD = 7, + XR_SEMANTIC_LABEL_SOFA_BD = 8, + XR_SEMANTIC_LABEL_CHAIR_BD = 9, + XR_SEMANTIC_LABEL_HUMAN_BD = 10, + XR_SEMANTIC_LABEL_BEAM_BD = 11, + XR_SEMANTIC_LABEL_COLUMN_BD = 12, + XR_SEMANTIC_LABEL_CURTAIN_BD = 13, + XR_SEMANTIC_LABEL_CABINET_BD = 14, + XR_SEMANTIC_LABEL_BED_BD = 15, + XR_SEMANTIC_LABEL_PLANT_BD = 16, + XR_SEMANTIC_LABEL_SCREEN_BD = 17, + XR_SEMANTIC_LABEL_VIRTUAL_WALL_BD = 18, + XR_SEMANTIC_LABEL_REFRIGERATOR_BD = 19, + XR_SEMANTIC_LABEL_WASHING_MACHINE_BD = 20, + XR_SEMANTIC_LABEL_AIR_CONDITIONER_BD = 21, + XR_SEMANTIC_LABEL_LAMP_BD = 22, + XR_SEMANTIC_LABEL_WALL_ART_BD = 23, + XR_SEMANTIC_LABEL_STAIRWAY_BD = 24, + XR_SEMANTIC_LABEL_MAX_ENUM_BD = 0x7FFFFFFF +} XrSemanticLabelBD; + +typedef enum XrSenseDataProviderTypeBD { + XR_SENSE_DATA_PROVIDER_TYPE_ANCHOR_BD = 1000390000, + XR_SENSE_DATA_PROVIDER_TYPE_SCENE_BD = 1000392000, + XR_SENSE_DATA_PROVIDER_TYPE_MESH_BD = 1000393000, + XR_SENSE_DATA_PROVIDER_TYPE_PLANE_BD = 1000396000, + XR_SENSE_DATA_PROVIDER_TYPE_MAX_ENUM_BD = 0x7FFFFFFF +} XrSenseDataProviderTypeBD; + +typedef enum XrSenseDataProviderStateBD { + XR_SENSE_DATA_PROVIDER_STATE_INITIALIZED_BD = 0, + XR_SENSE_DATA_PROVIDER_STATE_RUNNING_BD = 1, + XR_SENSE_DATA_PROVIDER_STATE_STOPPED_BD = 2, + XR_SENSE_DATA_PROVIDER_STATE_MAX_ENUM_BD = 0x7FFFFFFF +} XrSenseDataProviderStateBD; +// XrSystemSpatialSensingPropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialSensingPropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialSensing; +} XrSystemSpatialSensingPropertiesBD; + +typedef struct XrSpatialEntityComponentGetInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialEntityIdBD entityId; + XrSpatialEntityComponentTypeBD componentType; +} XrSpatialEntityComponentGetInfoBD; + +typedef struct XrSpatialEntityComponentDataBaseHeaderBD { + XrStructureType type; + void* XR_MAY_ALIAS next; +} XrSpatialEntityComponentDataBaseHeaderBD; + +// XrSpatialEntityLocationGetInfoBD extends XrSpatialEntityComponentGetInfoBD +typedef struct XrSpatialEntityLocationGetInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; +} XrSpatialEntityLocationGetInfoBD; + +// XrSpatialEntityComponentDataLocationBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataLocationBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpaceLocation location; +} XrSpatialEntityComponentDataLocationBD; + +// XrSpatialEntityComponentDataSemanticBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataSemanticBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t labelCapacityInput; + uint32_t labelCountOutput; + XrSemanticLabelBD* labels; +} XrSpatialEntityComponentDataSemanticBD; + +// XrSpatialEntityComponentDataBoundingBox2DBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataBoundingBox2DBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrRect2Df boundingBox2D; +} XrSpatialEntityComponentDataBoundingBox2DBD; + +// XrSpatialEntityComponentDataPolygonBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataPolygonBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector2f* vertices; +} XrSpatialEntityComponentDataPolygonBD; + +// XrSpatialEntityComponentDataBoundingBox3DBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataBoundingBox3DBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBoxf boundingBox3D; +} XrSpatialEntityComponentDataBoundingBox3DBD; + +// XrSpatialEntityComponentDataTriangleMeshBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataTriangleMeshBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector3f* vertices; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint16_t* indices; +} XrSpatialEntityComponentDataTriangleMeshBD; + +typedef struct XrSenseDataProviderCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSenseDataProviderTypeBD providerType; +} XrSenseDataProviderCreateInfoBD; + +typedef struct XrSenseDataProviderStartInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSenseDataProviderStartInfoBD; + +typedef struct XrEventDataSenseDataProviderStateChangedBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSenseDataProviderBD provider; + XrSenseDataProviderStateBD newState; +} XrEventDataSenseDataProviderStateChangedBD; + +typedef struct XrEventDataSenseDataUpdatedBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSenseDataProviderBD provider; +} XrEventDataSenseDataUpdatedBD; + +typedef struct XrSenseDataQueryInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSenseDataQueryInfoBD; + +typedef struct XrSenseDataQueryCompletionBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSenseDataSnapshotBD snapshot; +} XrSenseDataQueryCompletionBD; + +typedef struct XrQueriedSenseDataGetInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrQueriedSenseDataGetInfoBD; + +typedef struct XrSpatialEntityStateBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpatialEntityIdBD entityId; + XrTime lastUpdateTime; + XrUuidEXT uuid; +} XrSpatialEntityStateBD; + +typedef struct XrQueriedSenseDataBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t stateCapacityInput; + uint32_t stateCountOutput; + XrSpatialEntityStateBD* states; +} XrQueriedSenseDataBD; + +// XrSenseDataFilterUuidBD extends XrSenseDataQueryInfoBD +typedef struct XrSenseDataFilterUuidBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCount; + const XrUuidEXT* uuids; +} XrSenseDataFilterUuidBD; + +// XrSenseDataFilterSemanticBD extends XrSenseDataQueryInfoBD +typedef struct XrSenseDataFilterSemanticBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t labelCount; + const XrSemanticLabelBD* labels; +} XrSenseDataFilterSemanticBD; + +typedef struct XrSpatialEntityAnchorCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSenseDataSnapshotBD snapshot; + XrSpatialEntityIdBD entityId; +} XrSpatialEntityAnchorCreateInfoBD; + +typedef struct XrAnchorSpaceCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAnchorBD anchor; + XrPosef poseInAnchorSpace; +} XrAnchorSpaceCreateInfoBD; + +typedef struct XrFutureCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; +} XrFutureCompletionEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialEntityComponentTypesBD)(XrSenseDataSnapshotBD snapshot, XrSpatialEntityIdBD entityId, uint32_t componentTypeCapacityInput, uint32_t* componentTypeCountOutput, XrSpatialEntityComponentTypeBD* componentTypes); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialEntityUuidBD)(XrSenseDataSnapshotBD snapshot, XrSpatialEntityIdBD entityId, XrUuidEXT* uuid); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialEntityComponentDataBD)(XrSenseDataSnapshotBD snapshot, const XrSpatialEntityComponentGetInfoBD* getInfo, XrSpatialEntityComponentDataBaseHeaderBD* componentData); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSenseDataProviderBD)(XrSession session, const XrSenseDataProviderCreateInfoBD* createInfo, XrSenseDataProviderBD* provider); +typedef XrResult (XRAPI_PTR *PFN_xrStartSenseDataProviderAsyncBD)(XrSenseDataProviderBD provider, const XrSenseDataProviderStartInfoBD* startInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrStartSenseDataProviderCompleteBD)(XrSession session, XrFutureEXT future, XrFutureCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrGetSenseDataProviderStateBD)(XrSenseDataProviderBD provider, XrSenseDataProviderStateBD* state); +typedef XrResult (XRAPI_PTR *PFN_xrQuerySenseDataAsyncBD)(XrSenseDataProviderBD provider, const XrSenseDataQueryInfoBD* queryInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrQuerySenseDataCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrSenseDataQueryCompletionBD* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySenseDataSnapshotBD)(XrSenseDataSnapshotBD snapshot); +typedef XrResult (XRAPI_PTR *PFN_xrGetQueriedSenseDataBD)(XrSenseDataSnapshotBD snapshot, XrQueriedSenseDataGetInfoBD* getInfo, XrQueriedSenseDataBD* queriedSenseData); +typedef XrResult (XRAPI_PTR *PFN_xrStopSenseDataProviderBD)(XrSenseDataProviderBD provider); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySenseDataProviderBD)(XrSenseDataProviderBD provider); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialEntityAnchorBD)(XrSenseDataProviderBD provider, const XrSpatialEntityAnchorCreateInfoBD* createInfo, XrAnchorBD* anchor); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyAnchorBD)(XrAnchorBD anchor); +typedef XrResult (XRAPI_PTR *PFN_xrGetAnchorUuidBD)(XrAnchorBD anchor, XrUuidEXT* uuid); +typedef XrResult (XRAPI_PTR *PFN_xrCreateAnchorSpaceBD)(XrSession session, const XrAnchorSpaceCreateInfoBD* createInfo, XrSpace* space); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialEntityComponentTypesBD( + XrSenseDataSnapshotBD snapshot, + XrSpatialEntityIdBD entityId, + uint32_t componentTypeCapacityInput, + uint32_t* componentTypeCountOutput, + XrSpatialEntityComponentTypeBD* componentTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialEntityUuidBD( + XrSenseDataSnapshotBD snapshot, + XrSpatialEntityIdBD entityId, + XrUuidEXT* uuid); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialEntityComponentDataBD( + XrSenseDataSnapshotBD snapshot, + const XrSpatialEntityComponentGetInfoBD* getInfo, + XrSpatialEntityComponentDataBaseHeaderBD* componentData); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSenseDataProviderBD( + XrSession session, + const XrSenseDataProviderCreateInfoBD* createInfo, + XrSenseDataProviderBD* provider); + +XRAPI_ATTR XrResult XRAPI_CALL xrStartSenseDataProviderAsyncBD( + XrSenseDataProviderBD provider, + const XrSenseDataProviderStartInfoBD* startInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrStartSenseDataProviderCompleteBD( + XrSession session, + XrFutureEXT future, + XrFutureCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSenseDataProviderStateBD( + XrSenseDataProviderBD provider, + XrSenseDataProviderStateBD* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySenseDataAsyncBD( + XrSenseDataProviderBD provider, + const XrSenseDataQueryInfoBD* queryInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySenseDataCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrSenseDataQueryCompletionBD* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySenseDataSnapshotBD( + XrSenseDataSnapshotBD snapshot); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetQueriedSenseDataBD( + XrSenseDataSnapshotBD snapshot, + XrQueriedSenseDataGetInfoBD* getInfo, + XrQueriedSenseDataBD* queriedSenseData); + +XRAPI_ATTR XrResult XRAPI_CALL xrStopSenseDataProviderBD( + XrSenseDataProviderBD provider); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySenseDataProviderBD( + XrSenseDataProviderBD provider); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialEntityAnchorBD( + XrSenseDataProviderBD provider, + const XrSpatialEntityAnchorCreateInfoBD* createInfo, + XrAnchorBD* anchor); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyAnchorBD( + XrAnchorBD anchor); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetAnchorUuidBD( + XrAnchorBD anchor, + XrUuidEXT* uuid); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateAnchorSpaceBD( + XrSession session, + const XrAnchorSpaceCreateInfoBD* createInfo, + XrSpace* space); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_BD_spatial_anchor is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_anchor 1 +#define XR_BD_spatial_anchor_SPEC_VERSION 2 +#define XR_BD_SPATIAL_ANCHOR_EXTENSION_NAME "XR_BD_spatial_anchor" + +typedef enum XrPersistenceLocationBD { + XR_PERSISTENCE_LOCATION_LOCAL_BD = 0, + XR_PERSISTENCE_LOCATION_MAX_ENUM_BD = 0x7FFFFFFF +} XrPersistenceLocationBD; +// XrSystemSpatialAnchorPropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialAnchorPropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialAnchor; +} XrSystemSpatialAnchorPropertiesBD; + +typedef struct XrSpatialAnchorCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrPosef pose; + XrTime time; +} XrSpatialAnchorCreateInfoBD; + +typedef struct XrSpatialAnchorCreateCompletionBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrUuidEXT uuid; + XrAnchorBD anchor; +} XrSpatialAnchorCreateCompletionBD; + +typedef struct XrSpatialAnchorPersistInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPersistenceLocationBD location; + XrAnchorBD anchor; +} XrSpatialAnchorPersistInfoBD; + +typedef struct XrSpatialAnchorUnpersistInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPersistenceLocationBD location; + XrAnchorBD anchor; +} XrSpatialAnchorUnpersistInfoBD; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorAsyncBD)(XrSenseDataProviderBD provider, const XrSpatialAnchorCreateInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrSpatialAnchorCreateCompletionBD* completion); +typedef XrResult (XRAPI_PTR *PFN_xrPersistSpatialAnchorAsyncBD)(XrSenseDataProviderBD provider, const XrSpatialAnchorPersistInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrPersistSpatialAnchorCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrFutureCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistSpatialAnchorAsyncBD)(XrSenseDataProviderBD provider, const XrSpatialAnchorUnpersistInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistSpatialAnchorCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrFutureCompletionEXT* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorAsyncBD( + XrSenseDataProviderBD provider, + const XrSpatialAnchorCreateInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrSpatialAnchorCreateCompletionBD* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrPersistSpatialAnchorAsyncBD( + XrSenseDataProviderBD provider, + const XrSpatialAnchorPersistInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrPersistSpatialAnchorCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrFutureCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistSpatialAnchorAsyncBD( + XrSenseDataProviderBD provider, + const XrSpatialAnchorUnpersistInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistSpatialAnchorCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrFutureCompletionEXT* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_BD_spatial_anchor_sharing is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_anchor_sharing 1 +#define XR_BD_spatial_anchor_sharing_SPEC_VERSION 2 +#define XR_BD_SPATIAL_ANCHOR_SHARING_EXTENSION_NAME "XR_BD_spatial_anchor_sharing" +// XrSystemSpatialAnchorSharingPropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialAnchorSharingPropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialAnchorSharing; +} XrSystemSpatialAnchorSharingPropertiesBD; + +typedef struct XrSpatialAnchorShareInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAnchorBD anchor; +} XrSpatialAnchorShareInfoBD; + +typedef struct XrSharedSpatialAnchorDownloadInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidEXT uuid; +} XrSharedSpatialAnchorDownloadInfoBD; + +typedef XrResult (XRAPI_PTR *PFN_xrShareSpatialAnchorAsyncBD)(XrSenseDataProviderBD provider, const XrSpatialAnchorShareInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrShareSpatialAnchorCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrFutureCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDownloadSharedSpatialAnchorAsyncBD)(XrSenseDataProviderBD provider, const XrSharedSpatialAnchorDownloadInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrDownloadSharedSpatialAnchorCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrFutureCompletionEXT* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrShareSpatialAnchorAsyncBD( + XrSenseDataProviderBD provider, + const XrSpatialAnchorShareInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrShareSpatialAnchorCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrFutureCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDownloadSharedSpatialAnchorAsyncBD( + XrSenseDataProviderBD provider, + const XrSharedSpatialAnchorDownloadInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrDownloadSharedSpatialAnchorCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrFutureCompletionEXT* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_BD_spatial_scene is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_scene 1 +#define XR_BD_spatial_scene_SPEC_VERSION 1 +#define XR_BD_SPATIAL_SCENE_EXTENSION_NAME "XR_BD_spatial_scene" +// XrSystemSpatialScenePropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialScenePropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialScene; +} XrSystemSpatialScenePropertiesBD; + +typedef struct XrSceneCaptureInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSceneCaptureInfoBD; + +typedef XrResult (XRAPI_PTR *PFN_xrCaptureSceneAsyncBD)(XrSenseDataProviderBD provider, const XrSceneCaptureInfoBD* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCaptureSceneCompleteBD)(XrSenseDataProviderBD provider, XrFutureEXT future, XrFutureCompletionEXT* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCaptureSceneAsyncBD( + XrSenseDataProviderBD provider, + const XrSceneCaptureInfoBD* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCaptureSceneCompleteBD( + XrSenseDataProviderBD provider, + XrFutureEXT future, + XrFutureCompletionEXT* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_BD_spatial_mesh is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_mesh 1 +#define XR_BD_spatial_mesh_SPEC_VERSION 1 +#define XR_BD_SPATIAL_MESH_EXTENSION_NAME "XR_BD_spatial_mesh" + +typedef enum XrSpatialMeshLodBD { + XR_SPATIAL_MESH_LOD_COARSE_BD = 0, + XR_SPATIAL_MESH_LOD_MEDIUM_BD = 1, + XR_SPATIAL_MESH_LOD_FINE_BD = 2, + XR_SPATIAL_MESH_LOD_MAX_ENUM_BD = 0x7FFFFFFF +} XrSpatialMeshLodBD; +typedef XrFlags64 XrSpatialMeshConfigFlagsBD; + +// Flag bits for XrSpatialMeshConfigFlagsBD +static const XrSpatialMeshConfigFlagsBD XR_SPATIAL_MESH_CONFIG_SEMANTIC_BIT_BD = 0x00000001; +static const XrSpatialMeshConfigFlagsBD XR_SPATIAL_MESH_CONFIG_ALIGN_SEMANTIC_WITH_VERTEX_BIT_BD = 0x00000002; + +// XrSystemSpatialMeshPropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialMeshPropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialMesh; +} XrSystemSpatialMeshPropertiesBD; + +// XrSenseDataProviderCreateInfoSpatialMeshBD extends XrSenseDataProviderCreateInfoBD +typedef struct XrSenseDataProviderCreateInfoSpatialMeshBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialMeshConfigFlagsBD configFlags; + XrSpatialMeshLodBD lod; +} XrSenseDataProviderCreateInfoSpatialMeshBD; + + + +// XR_BD_future_progress is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_future_progress 1 +#define XR_BD_future_progress_SPEC_VERSION 1 +#define XR_BD_FUTURE_PROGRESS_EXTENSION_NAME "XR_BD_future_progress" +// XrFuturePollResultProgressBD extends XrFuturePollResultEXT +typedef struct XrFuturePollResultProgressBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isSupported; + uint32_t progressPercentage; +} XrFuturePollResultProgressBD; + + + +// XR_BD_spatial_plane is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_plane 1 +#define XR_BD_spatial_plane_SPEC_VERSION 1 +#define XR_BD_SPATIAL_PLANE_EXTENSION_NAME "XR_BD_spatial_plane" + +typedef enum XrPlaneOrientationBD { + XR_PLANE_ORIENTATION_HORIZONTAL_UPWARD_BD = 0, + XR_PLANE_ORIENTATION_HORIZONTAL_DOWNWARD_BD = 1, + XR_PLANE_ORIENTATION_VERTICAL_BD = 2, + XR_PLANE_ORIENTATION_ARBITRARY_BD = 3, + XR_PLANE_ORIENTATION_MAX_ENUM_BD = 0x7FFFFFFF +} XrPlaneOrientationBD; +// XrSystemSpatialPlanePropertiesBD extends XrSystemProperties +typedef struct XrSystemSpatialPlanePropertiesBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialPlane; +} XrSystemSpatialPlanePropertiesBD; + +// XrSpatialEntityComponentDataPlaneOrientationBD extends XrSpatialEntityComponentDataBaseHeaderBD +typedef struct XrSpatialEntityComponentDataPlaneOrientationBD { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPlaneOrientationBD orientation; +} XrSpatialEntityComponentDataPlaneOrientationBD; + +// XrSenseDataFilterPlaneOrientationBD extends XrSenseDataQueryInfoBD +typedef struct XrSenseDataFilterPlaneOrientationBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t orientationCount; + XrPlaneOrientationBD* orientations; +} XrSenseDataFilterPlaneOrientationBD; + + + +// XR_BD_ultra_controller_interaction is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_ultra_controller_interaction 1 +#define XR_BD_ultra_controller_interaction_SPEC_VERSION 1 +#define XR_BD_ULTRA_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_BD_ultra_controller_interaction" + + +// XR_BD_spatial_audio_rendering is a preprocessor guard. Do not pass it to API calls. +#define XR_BD_spatial_audio_rendering 1 +XR_DEFINE_HANDLE(XrSpatialAudioRendererBD) +XR_DEFINE_HANDLE(XrSoundFieldBD) +XR_DEFINE_HANDLE(XrSoundObjectBD) +XR_DEFINE_HANDLE(XrSoundObstacleBD) +XR_DEFINE_HANDLE(XrSoundObstacleMaterialBD) +#define XR_BD_spatial_audio_rendering_SPEC_VERSION 1 +#define XR_BD_SPATIAL_AUDIO_RENDERING_EXTENSION_NAME "XR_BD_spatial_audio_rendering" + +typedef enum XrAudioSampleRateBD { + XR_AUDIO_SAMPLE_RATE_192000_HZ_BD = 1, + XR_AUDIO_SAMPLE_RATE_96000_HZ_BD = 2, + XR_AUDIO_SAMPLE_RATE_48000_HZ_BD = 3, + XR_AUDIO_SAMPLE_RATE_44100_HZ_BD = 4, + XR_AUDIO_SAMPLE_RATE_32000_HZ_BD = 5, + XR_AUDIO_SAMPLE_RATE_24000_HZ_BD = 6, + XR_AUDIO_SAMPLE_RATE_22050_HZ_BD = 7, + XR_AUDIO_SAMPLE_RATE_16000_HZ_BD = 8, + XR_AUDIO_SAMPLE_RATE_12000_HZ_BD = 9, + XR_AUDIO_SAMPLE_RATE_11025_HZ_BD = 10, + XR_AUDIO_SAMPLE_RATE_8000_HZ_BD = 11, + XR_AUDIO_SAMPLE_RATE_MAX_ENUM_BD = 0x7FFFFFFF +} XrAudioSampleRateBD; + +typedef enum XrAudioBufferChannelLayoutBD { + XR_AUDIO_BUFFER_CHANNEL_LAYOUT_INTERLEAVED_BD = 0, + XR_AUDIO_BUFFER_CHANNEL_LAYOUT_PLANAR_BD = 1, + XR_AUDIO_BUFFER_CHANNEL_LAYOUT_MAX_ENUM_BD = 0x7FFFFFFF +} XrAudioBufferChannelLayoutBD; + +typedef enum XrSoundObjectDistanceAttenuationTypeBD { + XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_NONE_BD = 0, + XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_INVERSE_SQUARE_BD = 1, + XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_ROLLOFF_BD = 2, + XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_CUSTOMIZED_BD = 100, + XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_MAX_ENUM_BD = 0x7FFFFFFF +} XrSoundObjectDistanceAttenuationTypeBD; + +typedef enum XrSoundFieldChannelMaskSurroundBD { + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_LEFT_BD = 1, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_RIGHT_BD = 2, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_CENTER_BD = 4, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_LOW_FREQUENCY_BD = 8, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_LEFT_BD = 16, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_RIGHT_BD = 32, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SIDE_LEFT_BD = 64, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SIDE_RIGHT_BD = 128, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_FRONT_LEFT_BD = 256, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_FRONT_RIGHT_BD = 512, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_BACK_LEFT_BD = 1024, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_BACK_RIGHT_BD = 2048, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_CENTER_BD = 4096, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_SIDE_LEFT_BD = 8192, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_SIDE_RIGHT_BD = 16384, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_STEREO_BD = 3, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_2_1_BD = 11, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_3_0_BD = 7, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_4_0_BD = 4099, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_BACK_SURROUND_BD = 48, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_QUAD_BD = 51, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_3_1_BD = 15, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_0_BD = 55, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_SIDE_SURROUND_BD = 192, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_0_SIDE_BD = 199, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_BD = 63, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_SIDE_BD = 207, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_0_BD = 247, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_BD = 255, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_2_BD = 831, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_4_BD = 3903, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_2_BD = 24831, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_4_BD = 4095, + XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_MAX_ENUM_BD = 0x7FFFFFFF +} XrSoundFieldChannelMaskSurroundBD; + +typedef enum XrSoundFieldChannelMaskAmbixBD { + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_1ST_ORDER_BD = 1, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_2ND_ORDER_BD = 2, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_3RD_ORDER_BD = 3, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_4TH_ORDER_BD = 4, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_5TH_ORDER_BD = 5, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_6TH_ORDER_BD = 6, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_7TH_ORDER_BD = 7, + XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_MAX_ENUM_BD = 0x7FFFFFFF +} XrSoundFieldChannelMaskAmbixBD; + +typedef enum XrSoundFieldChannelMaskFumaBD { + XR_SOUND_FIELD_CHANNEL_MASK_FUMA_1ST_ORDER_BD = 1, + XR_SOUND_FIELD_CHANNEL_MASK_FUMA_MAX_ENUM_BD = 0x7FFFFFFF +} XrSoundFieldChannelMaskFumaBD; + +typedef enum XrSoundObstacleMaterialTypeBD { + XR_SOUND_OBSTACLE_MATERIAL_TYPE_ACOUSTIC_TILE_BD = 0, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_BRICK_BD = 1, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_BRICK_PAINTED_BD = 2, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_BD = 3, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_HEAVY_BD = 4, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_HEAVY_PADDED_BD = 5, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CERAMIC_TILE_BD = 6, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BD = 7, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_ROUGH_BD = 8, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BLOCK_BD = 9, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BLOCK_PAINTED_BD = 10, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CURTAIN_BD = 11, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_FOLIAGE_BD = 12, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_GLASS_BD = 13, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_GLASS_HEAVY_BD = 14, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_GRASS_BD = 15, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_GRAVEL_BD = 16, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_GYPSUM_BOARD_BD = 17, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_PLASTER_ON_BRICK_BD = 18, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_PLASTER_ON_CONCRETE_BLOCK_BD = 19, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_SOIL_BD = 20, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_SOUND_PROOF_BD = 21, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_SNOW_BD = 22, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_STEEL_BD = 23, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_WATER_BD = 24, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_THIN_BD = 25, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_THICK_BD = 26, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_FLOOR_BD = 27, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_ON_CONCRETE_BD = 28, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_CUSTOM_BD = 29, + XR_SOUND_OBSTACLE_MATERIAL_TYPE_MAX_ENUM_BD = 0x7FFFFFFF +} XrSoundObstacleMaterialTypeBD; +typedef XrFlags64 XrSoundObstacleFlagsBD; + +// Flag bits for XrSoundObstacleFlagsBD +static const XrSoundObstacleFlagsBD XR_SOUND_OBSTACLE_ENABLED_BIT_BD = 0x00000001; +static const XrSoundObstacleFlagsBD XR_SOUND_OBSTACLE_POSE_BIT_BD = 0x00000002; +static const XrSoundObstacleFlagsBD XR_SOUND_OBSTACLE_MESH_BIT_BD = 0x00000004; +static const XrSoundObstacleFlagsBD XR_SOUND_OBSTACLE_MATERIALS_BIT_BD = 0x00000008; + +typedef XrFlags64 XrSoundObjectFlagsBD; + +// Flag bits for XrSoundObjectFlagsBD +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_ENABLED_BIT_BD = 0x00000001; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_POSE_BIT_BD = 0x00000002; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_DIRECTIVITY_BIT_BD = 0x00000004; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_SHAPE_BIT_BD = 0x00000008; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_MAIN_VOLUME_BIT_BD = 0x00000010; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_REFLECTION_GAIN_BIT_BD = 0x00000020; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_ENABLE_DOPPLER_BIT_BD = 0x00000040; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_DIRECT_SOUND_ATTENUATION_BIT_BD = 0x00000080; +static const XrSoundObjectFlagsBD XR_SOUND_OBJECT_INDIRECT_SOUND_ATTENUATION_BIT_BD = 0x00000100; + +typedef XrFlags64 XrSoundFieldFlagsBD; + +// Flag bits for XrSoundFieldFlagsBD +static const XrSoundFieldFlagsBD XR_SOUND_FIELD_ENABLED_BIT_BD = 0x00000001; +static const XrSoundFieldFlagsBD XR_SOUND_FIELD_ORIENTATION_BIT_BD = 0x00000002; +static const XrSoundFieldFlagsBD XR_SOUND_FIELD_MAIN_VOLUME_BIT_BD = 0x00000004; +static const XrSoundFieldFlagsBD XR_SOUND_FIELD_LFE_GAIN_BIT_BD = 0x00000008; + +typedef struct XrSpatialAudioRendererCreateInfoBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t framesPerBuffer; + XrAudioSampleRateBD sampleRate; +} XrSpatialAudioRendererCreateInfoBD; + +typedef struct XrAudioBufferBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAudioBufferChannelLayoutBD channelLayout; + uint32_t bufferChannels; + uint32_t bufferLength; + float* buffer; +} XrAudioBufferBD; + +// XrSoundObjectDirectivityCardioidBD extends XrSoundObjectConfigBD +typedef struct XrSoundObjectDirectivityCardioidBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float alpha; + float order; +} XrSoundObjectDirectivityCardioidBD; + +// XrSoundObjectShapeSphereBD extends XrSoundObjectConfigBD +typedef struct XrSoundObjectShapeSphereBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float radius; +} XrSoundObjectShapeSphereBD; + +typedef struct XrAttenuationCurvePointBD { + float distance; + float gain; +} XrAttenuationCurvePointBD; + +typedef struct XrSoundObjectDistanceAttenuationCurveBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t curvePointCount; + XrAttenuationCurvePointBD* curvePoints; +} XrSoundObjectDistanceAttenuationCurveBD; + +typedef struct XrSoundObjectDistanceAttenuationBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSoundObjectDistanceAttenuationTypeBD distanceAttenuationType; + float minAttenuationRange; + float maxAttenuationRange; + float referenceDistance; + float rolloffFactor; + XrSoundObjectDistanceAttenuationCurveBD* customDistanceAttenuationCurve; +} XrSoundObjectDistanceAttenuationBD; + +typedef struct XrSoundObjectConfigBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 enabled; + XrPosef pose; + XrSpace baseSpace; + float mainVolume; + float reflectionGain; + XrBool32 enableDoppler; + const XrSoundObjectDistanceAttenuationBD* directSoundAttenuation; + const XrSoundObjectDistanceAttenuationBD* indirectSoundAttenuation; +} XrSoundObjectConfigBD; + +typedef struct XrSoundFieldConfigBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 enabled; + XrQuaternionf orientation; + XrSpace baseSpace; + float mainVolume; + float lfeGain; +} XrSoundFieldConfigBD; + +// XrSoundFieldChannelDefinitionSurroundBD extends XrSoundFieldConfigBD +typedef struct XrSoundFieldChannelDefinitionSurroundBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSoundFieldChannelMaskSurroundBD channelMask; +} XrSoundFieldChannelDefinitionSurroundBD; + +// XrSoundFieldChannelDefinitionAmbixBD extends XrSoundFieldConfigBD +typedef struct XrSoundFieldChannelDefinitionAmbixBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSoundFieldChannelMaskAmbixBD channelMask; +} XrSoundFieldChannelDefinitionAmbixBD; + +// XrSoundFieldChannelDefinitionFumaBD extends XrSoundFieldConfigBD +typedef struct XrSoundFieldChannelDefinitionFumaBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSoundFieldChannelMaskFumaBD channelMask; +} XrSoundFieldChannelDefinitionFumaBD; + +typedef struct XrSoundTriangleMeshBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t vertexCount; + XrVector3f* vertices; + uint32_t indexCount; + uint32_t* indices; +} XrSoundTriangleMeshBD; + +typedef struct XrSoundObstacleConfigBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 enabled; + XrPosef pose; + XrSpace baseSpace; + uint32_t materialCount; + XrSoundObstacleMaterialBD* materials; +} XrSoundObstacleConfigBD; + +typedef struct XrSoundObstacleMaterialConfigBD { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSoundObstacleMaterialTypeBD materialType; + uint32_t bandCount; + float* bandFrequencies; + float* bandAbsorptions; + float* bandScatterings; + float* bandTransmissions; +} XrSoundObstacleMaterialConfigBD; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSupportedAudioSampleRateBD)(XrSession session, uint32_t sampleRateCapacityInput, uint32_t* sampleRateCountOutput, XrAudioSampleRateBD* sampleRates); +typedef XrResult (XRAPI_PTR *PFN_xrQueryFramesPerBufferRangeBD)(XrSession session, XrAudioSampleRateBD sampleRate, uint32_t* min, uint32_t* max); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAudioRendererBD)(XrSession session, const XrSpatialAudioRendererCreateInfoBD* createInfo, XrSpatialAudioRendererBD* renderer); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialAudioRendererBD)(XrSpatialAudioRendererBD renderer); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSoundObstacleMaterialBD)(XrSpatialAudioRendererBD renderer, const XrSoundObstacleMaterialConfigBD* config, XrSoundObstacleMaterialBD* material); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSoundObstacleMaterialConfigBD)(XrSoundObstacleMaterialBD material, const XrSoundObstacleMaterialConfigBD* config); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySoundObstacleMaterialBD)(XrSoundObstacleMaterialBD material); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSoundObstacleBD)(XrSpatialAudioRendererBD renderer, const XrSoundObstacleConfigBD* config, const XrSoundTriangleMeshBD* mesh, XrSoundObstacleBD* soundObstacle); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSoundObstacleConfigBD)(XrSoundObstacleBD soundObstacle, const XrSoundObstacleConfigBD* config, const XrSoundTriangleMeshBD* mesh, XrSoundObstacleFlagsBD flags); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySoundObstacleBD)(XrSoundObstacleBD soundObstacle); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSoundObjectBD)(XrSpatialAudioRendererBD renderer, const XrSoundObjectConfigBD* config, XrSoundObjectBD* soundObject); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSoundObjectConfigBD)(XrSoundObjectBD soundObject, const XrSoundObjectConfigBD* config, XrSoundObjectFlagsBD flags); +typedef XrResult (XRAPI_PTR *PFN_xrSubmitSoundObjectBufferBD)(XrSoundObjectBD soundObject, const XrAudioBufferBD* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySoundObjectBD)(XrSoundObjectBD soundObject); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSoundFieldBD)(XrSpatialAudioRendererBD renderer, const XrSoundFieldConfigBD* config, XrSoundFieldBD* soundField); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSoundFieldConfigBD)(XrSoundFieldBD soundField, const XrSoundFieldConfigBD* config, XrSoundFieldFlagsBD flags); +typedef XrResult (XRAPI_PTR *PFN_xrSubmitSoundFieldBufferBD)(XrSoundFieldBD soundField, const XrAudioBufferBD* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySoundFieldBD)(XrSoundFieldBD soundField); +typedef XrResult (XRAPI_PTR *PFN_xrWaitAudioPeriodBD)(XrSpatialAudioRendererBD renderer, XrDuration timeout); +typedef XrResult (XRAPI_PTR *PFN_xrEndAudioPeriodBD)(XrSpatialAudioRendererBD renderer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSupportedAudioSampleRateBD( + XrSession session, + uint32_t sampleRateCapacityInput, + uint32_t* sampleRateCountOutput, + XrAudioSampleRateBD* sampleRates); + +XRAPI_ATTR XrResult XRAPI_CALL xrQueryFramesPerBufferRangeBD( + XrSession session, + XrAudioSampleRateBD sampleRate, + uint32_t* min, + uint32_t* max); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAudioRendererBD( + XrSession session, + const XrSpatialAudioRendererCreateInfoBD* createInfo, + XrSpatialAudioRendererBD* renderer); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAudioRendererBD( + XrSpatialAudioRendererBD renderer); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSoundObstacleMaterialBD( + XrSpatialAudioRendererBD renderer, + const XrSoundObstacleMaterialConfigBD* config, + XrSoundObstacleMaterialBD* material); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSoundObstacleMaterialConfigBD( + XrSoundObstacleMaterialBD material, + const XrSoundObstacleMaterialConfigBD* config); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySoundObstacleMaterialBD( + XrSoundObstacleMaterialBD material); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSoundObstacleBD( + XrSpatialAudioRendererBD renderer, + const XrSoundObstacleConfigBD* config, + const XrSoundTriangleMeshBD* mesh, + XrSoundObstacleBD* soundObstacle); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSoundObstacleConfigBD( + XrSoundObstacleBD soundObstacle, + const XrSoundObstacleConfigBD* config, + const XrSoundTriangleMeshBD* mesh, + XrSoundObstacleFlagsBD flags); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySoundObstacleBD( + XrSoundObstacleBD soundObstacle); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSoundObjectBD( + XrSpatialAudioRendererBD renderer, + const XrSoundObjectConfigBD* config, + XrSoundObjectBD* soundObject); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSoundObjectConfigBD( + XrSoundObjectBD soundObject, + const XrSoundObjectConfigBD* config, + XrSoundObjectFlagsBD flags); + +XRAPI_ATTR XrResult XRAPI_CALL xrSubmitSoundObjectBufferBD( + XrSoundObjectBD soundObject, + const XrAudioBufferBD* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySoundObjectBD( + XrSoundObjectBD soundObject); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSoundFieldBD( + XrSpatialAudioRendererBD renderer, + const XrSoundFieldConfigBD* config, + XrSoundFieldBD* soundField); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSoundFieldConfigBD( + XrSoundFieldBD soundField, + const XrSoundFieldConfigBD* config, + XrSoundFieldFlagsBD flags); + +XRAPI_ATTR XrResult XRAPI_CALL xrSubmitSoundFieldBufferBD( + XrSoundFieldBD soundField, + const XrAudioBufferBD* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySoundFieldBD( + XrSoundFieldBD soundField); + +XRAPI_ATTR XrResult XRAPI_CALL xrWaitAudioPeriodBD( + XrSpatialAudioRendererBD renderer, + XrDuration timeout); + +XRAPI_ATTR XrResult XRAPI_CALL xrEndAudioPeriodBD( + XrSpatialAudioRendererBD renderer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_EXT_local_floor is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_local_floor 1 #define XR_EXT_local_floor_SPEC_VERSION 1 @@ -7912,7 +9975,7 @@ typedef struct XrPlaneDetectorPolygonBufferEXT { XrVector2f* vertices; } XrPlaneDetectorPolygonBufferEXT; -typedef XrResult (XRAPI_PTR *PFN_xrCreatePlaneDetectorEXT)(XrSession session, const XrPlaneDetectorCreateInfoEXT* createInfo, XrPlaneDetectorEXT* planeDetector); +typedef XrResult (XRAPI_PTR *PFN_xrCreatePlaneDetectorEXT)(XrSession session, const XrPlaneDetectorCreateInfoEXT* createInfo, XrPlaneDetectorEXT* planeDetector); typedef XrResult (XRAPI_PTR *PFN_xrDestroyPlaneDetectorEXT)(XrPlaneDetectorEXT planeDetector); typedef XrResult (XRAPI_PTR *PFN_xrBeginPlaneDetectionEXT)(XrPlaneDetectorEXT planeDetector, const XrPlaneDetectorBeginInfoEXT* beginInfo); typedef XrResult (XRAPI_PTR *PFN_xrGetPlaneDetectionStateEXT)(XrPlaneDetectorEXT planeDetector, XrPlaneDetectionStateEXT* state); @@ -7957,9 +10020,758 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetPlanePolygonBufferEXT( #define XR_OPPO_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_OPPO_controller_interaction" +// XR_ANDROID_trackables is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_trackables 1 + +#define XR_NULL_TRACKABLE_ANDROID 0 + +XR_DEFINE_ATOM(XrTrackableANDROID) +XR_DEFINE_HANDLE(XrTrackableTrackerANDROID) +#define XR_ANDROID_trackables_SPEC_VERSION 2 +#define XR_ANDROID_TRACKABLES_EXTENSION_NAME "XR_ANDROID_trackables" + +typedef enum XrTrackingStateANDROID { + XR_TRACKING_STATE_PAUSED_ANDROID = 0, + XR_TRACKING_STATE_STOPPED_ANDROID = 1, + XR_TRACKING_STATE_TRACKING_ANDROID = 2, + XR_TRACKING_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackingStateANDROID; + +typedef enum XrTrackableTypeANDROID { + XR_TRACKABLE_TYPE_NOT_VALID_ANDROID = 0, + XR_TRACKABLE_TYPE_PLANE_ANDROID = 1, + XR_TRACKABLE_TYPE_DEPTH_ANDROID = 1000463000, + XR_TRACKABLE_TYPE_OBJECT_ANDROID = 1000466000, + XR_TRACKABLE_TYPE_MARKER_ANDROID = 1000707000, + XR_TRACKABLE_TYPE_QR_CODE_ANDROID = 1000708000, + XR_TRACKABLE_TYPE_IMAGE_ANDROID = 1000709000, + XR_TRACKABLE_TYPE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackableTypeANDROID; + +typedef enum XrPlaneTypeANDROID { + XR_PLANE_TYPE_HORIZONTAL_DOWNWARD_FACING_ANDROID = 0, + XR_PLANE_TYPE_HORIZONTAL_UPWARD_FACING_ANDROID = 1, + XR_PLANE_TYPE_VERTICAL_ANDROID = 2, + XR_PLANE_TYPE_ARBITRARY_ANDROID = 3, + XR_PLANE_TYPE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrPlaneTypeANDROID; + +typedef enum XrPlaneLabelANDROID { + XR_PLANE_LABEL_UNKNOWN_ANDROID = 0, + XR_PLANE_LABEL_WALL_ANDROID = 1, + XR_PLANE_LABEL_FLOOR_ANDROID = 2, + XR_PLANE_LABEL_CEILING_ANDROID = 3, + XR_PLANE_LABEL_TABLE_ANDROID = 4, + XR_PLANE_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrPlaneLabelANDROID; +typedef struct XrTrackableTrackerCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTrackableTypeANDROID trackableType; +} XrTrackableTrackerCreateInfoANDROID; + +typedef struct XrTrackableGetInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTrackableANDROID trackable; + XrSpace baseSpace; + XrTime time; +} XrTrackableGetInfoANDROID; + +typedef struct XrTrackablePlaneANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTrackingStateANDROID trackingState; + XrPosef centerPose; + XrExtent2Df extents; + XrPlaneTypeANDROID planeType; + XrPlaneLabelANDROID planeLabel; + XrTrackableANDROID subsumedByPlane; + XrTime lastUpdatedTime; + uint32_t vertexCapacityInput; + uint32_t* vertexCountOutput; + XrVector2f* vertices; +} XrTrackablePlaneANDROID; + +typedef struct XrAnchorSpaceCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrTime time; + XrPosef pose; + XrTrackableANDROID trackable; +} XrAnchorSpaceCreateInfoANDROID; + +// XrSystemTrackablesPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemTrackablesPropertiesANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 supportsAnchor; + uint32_t maxAnchors; +} XrSystemTrackablesPropertiesANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSupportedTrackableTypesANDROID)(XrInstance instance, XrSystemId systemId, uint32_t trackableTypeCapacityInput, uint32_t* trackableTypeCountOutput, XrTrackableTypeANDROID* trackableTypes); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSupportedAnchorTrackableTypesANDROID)(XrInstance instance, XrSystemId systemId, uint32_t trackableTypeCapacityInput, uint32_t* trackableTypeCountOutput, XrTrackableTypeANDROID* trackableTypes); +typedef XrResult (XRAPI_PTR *PFN_xrCreateTrackableTrackerANDROID)(XrSession session, const XrTrackableTrackerCreateInfoANDROID* createInfo, XrTrackableTrackerANDROID* trackableTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyTrackableTrackerANDROID)(XrTrackableTrackerANDROID trackableTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetAllTrackablesANDROID)(XrTrackableTrackerANDROID trackableTracker, uint32_t trackableCapacityInput, uint32_t* trackableCountOutput, XrTrackableANDROID* trackables); +typedef XrResult (XRAPI_PTR *PFN_xrGetTrackablePlaneANDROID)(XrTrackableTrackerANDROID trackableTracker, const XrTrackableGetInfoANDROID* getInfo, XrTrackablePlaneANDROID* planeOutput); +typedef XrResult (XRAPI_PTR *PFN_xrCreateAnchorSpaceANDROID)(XrSession session, const XrAnchorSpaceCreateInfoANDROID* createInfo, XrSpace* anchorOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSupportedTrackableTypesANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t trackableTypeCapacityInput, + uint32_t* trackableTypeCountOutput, + XrTrackableTypeANDROID* trackableTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSupportedAnchorTrackableTypesANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t trackableTypeCapacityInput, + uint32_t* trackableTypeCountOutput, + XrTrackableTypeANDROID* trackableTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateTrackableTrackerANDROID( + XrSession session, + const XrTrackableTrackerCreateInfoANDROID* createInfo, + XrTrackableTrackerANDROID* trackableTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyTrackableTrackerANDROID( + XrTrackableTrackerANDROID trackableTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetAllTrackablesANDROID( + XrTrackableTrackerANDROID trackableTracker, + uint32_t trackableCapacityInput, + uint32_t* trackableCountOutput, + XrTrackableANDROID* trackables); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetTrackablePlaneANDROID( + XrTrackableTrackerANDROID trackableTracker, + const XrTrackableGetInfoANDROID* getInfo, + XrTrackablePlaneANDROID* planeOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateAnchorSpaceANDROID( + XrSession session, + const XrAnchorSpaceCreateInfoANDROID* createInfo, + XrSpace* anchorOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_eye_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_eye_tracking 1 +XR_DEFINE_HANDLE(XrEyeTrackerANDROID) +#define XR_EYE_MAX_ANDROID 2 +#define XR_ANDROID_eye_tracking_SPEC_VERSION 1 +#define XR_ANDROID_EYE_TRACKING_EXTENSION_NAME "XR_ANDROID_eye_tracking" + +typedef enum XrEyeIndexANDROID { + XR_EYE_INDEX_LEFT_ANDROID = 0, + XR_EYE_INDEX_RIGHT_ANDROID = 1, + XR_EYE_INDEX_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrEyeIndexANDROID; + +typedef enum XrEyeStateANDROID { + XR_EYE_STATE_INVALID_ANDROID = 0, + XR_EYE_STATE_GAZING_ANDROID = 1, + XR_EYE_STATE_SHUT_ANDROID = 2, + XR_EYE_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrEyeStateANDROID; + +typedef enum XrEyeTrackingModeANDROID { + XR_EYE_TRACKING_MODE_NOT_TRACKING_ANDROID = 0, + XR_EYE_TRACKING_MODE_RIGHT_ANDROID = 1, + XR_EYE_TRACKING_MODE_LEFT_ANDROID = 2, + XR_EYE_TRACKING_MODE_BOTH_ANDROID = 3, + XR_EYE_TRACKING_MODE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrEyeTrackingModeANDROID; +// XrSystemEyeTrackingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemEyeTrackingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsEyeTracking; +} XrSystemEyeTrackingPropertiesANDROID; + +typedef struct XrEyeANDROID { + XrEyeStateANDROID eyeState; + XrPosef eyePose; +} XrEyeANDROID; + +typedef struct XrEyesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrEyeANDROID eyes[XR_EYE_MAX_ANDROID]; + XrEyeTrackingModeANDROID mode; +} XrEyesANDROID; + +typedef struct XrEyesGetInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; + XrSpace baseSpace; +} XrEyesGetInfoANDROID; + +typedef struct XrEyeTrackerCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEyeTrackerCreateInfoANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateEyeTrackerANDROID)(XrSession session, const XrEyeTrackerCreateInfoANDROID* createInfo, XrEyeTrackerANDROID* eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyEyeTrackerANDROID)(XrEyeTrackerANDROID eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFineTrackingEyesInfoANDROID)(XrEyeTrackerANDROID eyeTracker, const XrEyesGetInfoANDROID* getInfo, XrEyesANDROID* eyesOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetCoarseTrackingEyesInfoANDROID)(XrEyeTrackerANDROID eyeTracker, const XrEyesGetInfoANDROID* getInfo, XrEyesANDROID* eyesOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateEyeTrackerANDROID( + XrSession session, + const XrEyeTrackerCreateInfoANDROID* createInfo, + XrEyeTrackerANDROID* eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyEyeTrackerANDROID( + XrEyeTrackerANDROID eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFineTrackingEyesInfoANDROID( + XrEyeTrackerANDROID eyeTracker, + const XrEyesGetInfoANDROID* getInfo, + XrEyesANDROID* eyesOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetCoarseTrackingEyesInfoANDROID( + XrEyeTrackerANDROID eyeTracker, + const XrEyesGetInfoANDROID* getInfo, + XrEyesANDROID* eyesOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_device_anchor_persistence is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_device_anchor_persistence 1 +XR_DEFINE_HANDLE(XrDeviceAnchorPersistenceANDROID) +#define XR_ANDROID_device_anchor_persistence_SPEC_VERSION 1 +#define XR_ANDROID_DEVICE_ANCHOR_PERSISTENCE_EXTENSION_NAME "XR_ANDROID_device_anchor_persistence" + +typedef enum XrAnchorPersistStateANDROID { + XR_ANCHOR_PERSIST_STATE_PERSIST_NOT_REQUESTED_ANDROID = 0, + XR_ANCHOR_PERSIST_STATE_PERSIST_PENDING_ANDROID = 1, + XR_ANCHOR_PERSIST_STATE_PERSISTED_ANDROID = 2, + XR_ANCHOR_PERSIST_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrAnchorPersistStateANDROID; +typedef struct XrDeviceAnchorPersistenceCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrDeviceAnchorPersistenceCreateInfoANDROID; + +typedef struct XrPersistedAnchorSpaceCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidEXT anchorId; +} XrPersistedAnchorSpaceCreateInfoANDROID; + +typedef struct XrPersistedAnchorSpaceInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace anchor; +} XrPersistedAnchorSpaceInfoANDROID; + +// XrSystemDeviceAnchorPersistencePropertiesANDROID extends XrSystemProperties +typedef struct XrSystemDeviceAnchorPersistencePropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsAnchorPersistence; +} XrSystemDeviceAnchorPersistencePropertiesANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSupportedPersistenceAnchorTypesANDROID)(XrInstance instance, XrSystemId systemId, uint32_t trackableTypeCapacityInput, uint32_t* trackableTypeCountOutput, XrTrackableTypeANDROID* trackableTypes); +typedef XrResult (XRAPI_PTR *PFN_xrCreateDeviceAnchorPersistenceANDROID)(XrSession session, const XrDeviceAnchorPersistenceCreateInfoANDROID* createInfo, XrDeviceAnchorPersistenceANDROID* outHandle); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyDeviceAnchorPersistenceANDROID)(XrDeviceAnchorPersistenceANDROID handle); +typedef XrResult (XRAPI_PTR *PFN_xrPersistAnchorANDROID)(XrDeviceAnchorPersistenceANDROID handle, const XrPersistedAnchorSpaceInfoANDROID* persistedInfo, XrUuidEXT* anchorIdOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetAnchorPersistStateANDROID)(XrDeviceAnchorPersistenceANDROID handle, const XrUuidEXT* anchorId, XrAnchorPersistStateANDROID* persistState); +typedef XrResult (XRAPI_PTR *PFN_xrCreatePersistedAnchorSpaceANDROID)(XrDeviceAnchorPersistenceANDROID handle, const XrPersistedAnchorSpaceCreateInfoANDROID* createInfo, XrSpace* anchorOutput); +typedef XrResult (XRAPI_PTR *PFN_xrEnumeratePersistedAnchorsANDROID)(XrDeviceAnchorPersistenceANDROID handle, uint32_t anchorIdCapacityInput, uint32_t* anchorIdCountOutput, XrUuidEXT* anchorIds); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistAnchorANDROID)(XrDeviceAnchorPersistenceANDROID handle, const XrUuidEXT* anchorId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSupportedPersistenceAnchorTypesANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t trackableTypeCapacityInput, + uint32_t* trackableTypeCountOutput, + XrTrackableTypeANDROID* trackableTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateDeviceAnchorPersistenceANDROID( + XrSession session, + const XrDeviceAnchorPersistenceCreateInfoANDROID* createInfo, + XrDeviceAnchorPersistenceANDROID* outHandle); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyDeviceAnchorPersistenceANDROID( + XrDeviceAnchorPersistenceANDROID handle); + +XRAPI_ATTR XrResult XRAPI_CALL xrPersistAnchorANDROID( + XrDeviceAnchorPersistenceANDROID handle, + const XrPersistedAnchorSpaceInfoANDROID* persistedInfo, + XrUuidEXT* anchorIdOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetAnchorPersistStateANDROID( + XrDeviceAnchorPersistenceANDROID handle, + const XrUuidEXT* anchorId, + XrAnchorPersistStateANDROID* persistState); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePersistedAnchorSpaceANDROID( + XrDeviceAnchorPersistenceANDROID handle, + const XrPersistedAnchorSpaceCreateInfoANDROID* createInfo, + XrSpace* anchorOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumeratePersistedAnchorsANDROID( + XrDeviceAnchorPersistenceANDROID handle, + uint32_t anchorIdCapacityInput, + uint32_t* anchorIdCountOutput, + XrUuidEXT* anchorIds); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistAnchorANDROID( + XrDeviceAnchorPersistenceANDROID handle, + const XrUuidEXT* anchorId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_face_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_face_tracking 1 +XR_DEFINE_HANDLE(XrFaceTrackerANDROID) +#define XR_ANDROID_face_tracking_SPEC_VERSION 1 +#define XR_ANDROID_FACE_TRACKING_EXTENSION_NAME "XR_ANDROID_face_tracking" +#define XR_FACE_PARAMETER_COUNT_ANDROID 68 +#define XR_FACE_REGION_CONFIDENCE_COUNT_ANDROID 3 + +typedef enum XrFaceParameterIndicesANDROID { + XR_FACE_PARAMETER_INDICES_BROW_LOWERER_L_ANDROID = 0, + XR_FACE_PARAMETER_INDICES_BROW_LOWERER_R_ANDROID = 1, + XR_FACE_PARAMETER_INDICES_CHEEK_PUFF_L_ANDROID = 2, + XR_FACE_PARAMETER_INDICES_CHEEK_PUFF_R_ANDROID = 3, + XR_FACE_PARAMETER_INDICES_CHEEK_RAISER_L_ANDROID = 4, + XR_FACE_PARAMETER_INDICES_CHEEK_RAISER_R_ANDROID = 5, + XR_FACE_PARAMETER_INDICES_CHEEK_SUCK_L_ANDROID = 6, + XR_FACE_PARAMETER_INDICES_CHEEK_SUCK_R_ANDROID = 7, + XR_FACE_PARAMETER_INDICES_CHIN_RAISER_B_ANDROID = 8, + XR_FACE_PARAMETER_INDICES_CHIN_RAISER_T_ANDROID = 9, + XR_FACE_PARAMETER_INDICES_DIMPLER_L_ANDROID = 10, + XR_FACE_PARAMETER_INDICES_DIMPLER_R_ANDROID = 11, + XR_FACE_PARAMETER_INDICES_EYES_CLOSED_L_ANDROID = 12, + XR_FACE_PARAMETER_INDICES_EYES_CLOSED_R_ANDROID = 13, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_L_ANDROID = 14, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_R_ANDROID = 15, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_L_ANDROID = 16, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_R_ANDROID = 17, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_L_ANDROID = 18, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_R_ANDROID = 19, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_UP_L_ANDROID = 20, + XR_FACE_PARAMETER_INDICES_EYES_LOOK_UP_R_ANDROID = 21, + XR_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_L_ANDROID = 22, + XR_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_R_ANDROID = 23, + XR_FACE_PARAMETER_INDICES_JAW_DROP_ANDROID = 24, + XR_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_LEFT_ANDROID = 25, + XR_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_RIGHT_ANDROID = 26, + XR_FACE_PARAMETER_INDICES_JAW_THRUST_ANDROID = 27, + XR_FACE_PARAMETER_INDICES_LID_TIGHTENER_L_ANDROID = 28, + XR_FACE_PARAMETER_INDICES_LID_TIGHTENER_R_ANDROID = 29, + XR_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_L_ANDROID = 30, + XR_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_R_ANDROID = 31, + XR_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_L_ANDROID = 32, + XR_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_R_ANDROID = 33, + XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_LB_ANDROID = 34, + XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_LT_ANDROID = 35, + XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_RB_ANDROID = 36, + XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_RT_ANDROID = 37, + XR_FACE_PARAMETER_INDICES_LIP_PRESSOR_L_ANDROID = 38, + XR_FACE_PARAMETER_INDICES_LIP_PRESSOR_R_ANDROID = 39, + XR_FACE_PARAMETER_INDICES_LIP_PUCKER_L_ANDROID = 40, + XR_FACE_PARAMETER_INDICES_LIP_PUCKER_R_ANDROID = 41, + XR_FACE_PARAMETER_INDICES_LIP_STRETCHER_L_ANDROID = 42, + XR_FACE_PARAMETER_INDICES_LIP_STRETCHER_R_ANDROID = 43, + XR_FACE_PARAMETER_INDICES_LIP_SUCK_LB_ANDROID = 44, + XR_FACE_PARAMETER_INDICES_LIP_SUCK_LT_ANDROID = 45, + XR_FACE_PARAMETER_INDICES_LIP_SUCK_RB_ANDROID = 46, + XR_FACE_PARAMETER_INDICES_LIP_SUCK_RT_ANDROID = 47, + XR_FACE_PARAMETER_INDICES_LIP_TIGHTENER_L_ANDROID = 48, + XR_FACE_PARAMETER_INDICES_LIP_TIGHTENER_R_ANDROID = 49, + XR_FACE_PARAMETER_INDICES_LIPS_TOWARD_ANDROID = 50, + XR_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_L_ANDROID = 51, + XR_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_R_ANDROID = 52, + XR_FACE_PARAMETER_INDICES_MOUTH_LEFT_ANDROID = 53, + XR_FACE_PARAMETER_INDICES_MOUTH_RIGHT_ANDROID = 54, + XR_FACE_PARAMETER_INDICES_NOSE_WRINKLER_L_ANDROID = 55, + XR_FACE_PARAMETER_INDICES_NOSE_WRINKLER_R_ANDROID = 56, + XR_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_L_ANDROID = 57, + XR_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_R_ANDROID = 58, + XR_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_L_ANDROID = 59, + XR_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_R_ANDROID = 60, + XR_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_L_ANDROID = 61, + XR_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_R_ANDROID = 62, + XR_FACE_PARAMETER_INDICES_TONGUE_OUT_ANDROID = 63, + XR_FACE_PARAMETER_INDICES_TONGUE_LEFT_ANDROID = 64, + XR_FACE_PARAMETER_INDICES_TONGUE_RIGHT_ANDROID = 65, + XR_FACE_PARAMETER_INDICES_TONGUE_UP_ANDROID = 66, + XR_FACE_PARAMETER_INDICES_TONGUE_DOWN_ANDROID = 67, + XR_FACE_PARAMETER_INDICES_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrFaceParameterIndicesANDROID; + +typedef enum XrFaceTrackingStateANDROID { + XR_FACE_TRACKING_STATE_PAUSED_ANDROID = 0, + XR_FACE_TRACKING_STATE_STOPPED_ANDROID = 1, + XR_FACE_TRACKING_STATE_TRACKING_ANDROID = 2, + XR_FACE_TRACKING_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrFaceTrackingStateANDROID; + +typedef enum XrFaceConfidenceRegionsANDROID { + XR_FACE_CONFIDENCE_REGIONS_LOWER_ANDROID = 0, + XR_FACE_CONFIDENCE_REGIONS_LEFT_UPPER_ANDROID = 1, + XR_FACE_CONFIDENCE_REGIONS_RIGHT_UPPER_ANDROID = 2, + XR_FACE_CONFIDENCE_REGIONS_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrFaceConfidenceRegionsANDROID; +typedef struct XrFaceTrackerCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrFaceTrackerCreateInfoANDROID; + +typedef struct XrFaceStateGetInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; +} XrFaceStateGetInfoANDROID; + +typedef struct XrFaceStateANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t parametersCapacityInput; + uint32_t parametersCountOutput; + float* parameters; + XrFaceTrackingStateANDROID faceTrackingState; + XrTime sampleTime; + XrBool32 isValid; + uint32_t regionConfidencesCapacityInput; + uint32_t regionConfidencesCountOutput; + float* regionConfidences; +} XrFaceStateANDROID; + +// XrSystemFaceTrackingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemFaceTrackingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFaceTracking; +} XrSystemFaceTrackingPropertiesANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateFaceTrackerANDROID)(XrSession session, const XrFaceTrackerCreateInfoANDROID* createInfo, XrFaceTrackerANDROID* faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFaceTrackerANDROID)(XrFaceTrackerANDROID faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFaceStateANDROID)(XrFaceTrackerANDROID faceTracker, const XrFaceStateGetInfoANDROID* getInfo, XrFaceStateANDROID* faceStateOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetFaceCalibrationStateANDROID)(XrFaceTrackerANDROID faceTracker, XrBool32* faceIsCalibratedOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFaceTrackerANDROID( + XrSession session, + const XrFaceTrackerCreateInfoANDROID* createInfo, + XrFaceTrackerANDROID* faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFaceTrackerANDROID( + XrFaceTrackerANDROID faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFaceStateANDROID( + XrFaceTrackerANDROID faceTracker, + const XrFaceStateGetInfoANDROID* getInfo, + XrFaceStateANDROID* faceStateOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFaceCalibrationStateANDROID( + XrFaceTrackerANDROID faceTracker, + XrBool32* faceIsCalibratedOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_passthrough_camera_state is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_passthrough_camera_state 1 +#define XR_ANDROID_passthrough_camera_state_SPEC_VERSION 1 +#define XR_ANDROID_PASSTHROUGH_CAMERA_STATE_EXTENSION_NAME "XR_ANDROID_passthrough_camera_state" + +typedef enum XrPassthroughCameraStateANDROID { + XR_PASSTHROUGH_CAMERA_STATE_DISABLED_ANDROID = 0, + XR_PASSTHROUGH_CAMERA_STATE_INITIALIZING_ANDROID = 1, + XR_PASSTHROUGH_CAMERA_STATE_READY_ANDROID = 2, + XR_PASSTHROUGH_CAMERA_STATE_ERROR_ANDROID = 3, + XR_PASSTHROUGH_CAMERA_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrPassthroughCameraStateANDROID; +// XrSystemPassthroughCameraStatePropertiesANDROID extends XrSystemProperties +typedef struct XrSystemPassthroughCameraStatePropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsPassthroughCameraState; +} XrSystemPassthroughCameraStatePropertiesANDROID; + +typedef struct XrPassthroughCameraStateGetInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrPassthroughCameraStateGetInfoANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrGetPassthroughCameraStateANDROID)(XrSession session, const XrPassthroughCameraStateGetInfoANDROID* getInfo, XrPassthroughCameraStateANDROID* cameraStateOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetPassthroughCameraStateANDROID( + XrSession session, + const XrPassthroughCameraStateGetInfoANDROID* getInfo, + XrPassthroughCameraStateANDROID* cameraStateOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_recommended_resolution is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_recommended_resolution 1 +#define XR_ANDROID_recommended_resolution_SPEC_VERSION 1 +#define XR_ANDROID_RECOMMENDED_RESOLUTION_EXTENSION_NAME "XR_ANDROID_recommended_resolution" +typedef struct XrEventDataRecommendedResolutionChangedANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEventDataRecommendedResolutionChangedANDROID; + + + +// XR_ANDROID_composition_layer_passthrough_mesh is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_composition_layer_passthrough_mesh 1 +XR_DEFINE_HANDLE(XrPassthroughLayerANDROID) +#define XR_ANDROID_composition_layer_passthrough_mesh_SPEC_VERSION 1 +#define XR_ANDROID_COMPOSITION_LAYER_PASSTHROUGH_MESH_EXTENSION_NAME "XR_ANDROID_composition_layer_passthrough_mesh" + +typedef enum XrWindingOrderANDROID { + XR_WINDING_ORDER_UNKNOWN_ANDROID = 0, + XR_WINDING_ORDER_CW_ANDROID = 1, + XR_WINDING_ORDER_CCW_ANDROID = 2, + XR_WINDING_ORDER_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrWindingOrderANDROID; +typedef struct XrPassthroughLayerCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t vertexCapacity; + uint32_t indexCapacity; +} XrPassthroughLayerCreateInfoANDROID; + +// XrPassthroughLayerMeshANDROID extends XrPassthroughLayerCreateInfoANDROID +typedef struct XrPassthroughLayerMeshANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrWindingOrderANDROID windingOrder; + uint32_t vertexCount; + const XrVector3f* vertices; + uint32_t indexCount; + const uint16_t* indices; +} XrPassthroughLayerMeshANDROID; + +typedef struct XrCompositionLayerPassthroughANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrPosef pose; + XrVector3f scale; + float opacity; + XrPassthroughLayerANDROID layer; +} XrCompositionLayerPassthroughANDROID; + +// XrSystemPassthroughLayerPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemPassthroughLayerPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsPassthroughLayer; + uint32_t maxMeshIndexCount; + uint32_t maxMeshVertexCount; +} XrSystemPassthroughLayerPropertiesANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughLayerANDROID)(XrSession session, const XrPassthroughLayerCreateInfoANDROID* createInfo, XrPassthroughLayerANDROID* layer); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughLayerANDROID)(XrPassthroughLayerANDROID layer); +typedef XrResult (XRAPI_PTR *PFN_xrSetPassthroughLayerMeshANDROID)(XrPassthroughLayerANDROID layer, const XrPassthroughLayerMeshANDROID* mesh); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughLayerANDROID( + XrSession session, + const XrPassthroughLayerCreateInfoANDROID* createInfo, + XrPassthroughLayerANDROID* layer); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughLayerANDROID( + XrPassthroughLayerANDROID layer); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetPassthroughLayerMeshANDROID( + XrPassthroughLayerANDROID layer, + const XrPassthroughLayerMeshANDROID* mesh); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_raycast is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_raycast 1 +#define XR_ANDROID_raycast_SPEC_VERSION 1 +#define XR_ANDROID_RAYCAST_EXTENSION_NAME "XR_ANDROID_raycast" +typedef struct XrRaycastInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t maxResults; + uint32_t trackerCount; + const XrTrackableTrackerANDROID* trackers; + XrVector3f origin; + XrVector3f trajectory; + XrSpace space; + XrTime time; +} XrRaycastInfoANDROID; + +typedef struct XrRaycastHitResultANDROID { + XrTrackableTypeANDROID type; + XrTrackableANDROID trackable; + XrPosef pose; +} XrRaycastHitResultANDROID; + +typedef struct XrRaycastHitResultsANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t resultsCapacityInput; + uint32_t resultsCountOutput; + XrRaycastHitResultANDROID* results; +} XrRaycastHitResultsANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateRaycastSupportedTrackableTypesANDROID)(XrInstance instance, XrSystemId systemId, uint32_t trackableTypeCapacityInput, uint32_t* trackableTypeCountOutput, XrTrackableTypeANDROID* trackableTypes); +typedef XrResult (XRAPI_PTR *PFN_xrRaycastANDROID)(XrSession session, const XrRaycastInfoANDROID* rayInfo, XrRaycastHitResultsANDROID* results); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateRaycastSupportedTrackableTypesANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t trackableTypeCapacityInput, + uint32_t* trackableTypeCountOutput, + XrTrackableTypeANDROID* trackableTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrRaycastANDROID( + XrSession session, + const XrRaycastInfoANDROID* rayInfo, + XrRaycastHitResultsANDROID* results); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_performance_metrics is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_performance_metrics 1 +#define XR_ANDROID_performance_metrics_SPEC_VERSION 1 +#define XR_ANDROID_PERFORMANCE_METRICS_EXTENSION_NAME "XR_ANDROID_performance_metrics" + +typedef enum XrPerformanceMetricsCounterUnitANDROID { + XR_PERFORMANCE_METRICS_COUNTER_UNIT_GENERIC_ANDROID = 0, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_PERCENTAGE_ANDROID = 1, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_MILLISECONDS_ANDROID = 2, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_BYTES_ANDROID = 3, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_HERTZ_ANDROID = 4, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrPerformanceMetricsCounterUnitANDROID; +typedef XrFlags64 XrPerformanceMetricsCounterFlagsANDROID; + +// Flag bits for XrPerformanceMetricsCounterFlagsANDROID +static const XrPerformanceMetricsCounterFlagsANDROID XR_PERFORMANCE_METRICS_COUNTER_ANY_VALUE_VALID_BIT_ANDROID = 0x00000001; +static const XrPerformanceMetricsCounterFlagsANDROID XR_PERFORMANCE_METRICS_COUNTER_UINT_VALUE_VALID_BIT_ANDROID = 0x00000002; +static const XrPerformanceMetricsCounterFlagsANDROID XR_PERFORMANCE_METRICS_COUNTER_FLOAT_VALUE_VALID_BIT_ANDROID = 0x00000004; + +typedef struct XrPerformanceMetricsStateANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 enabled; +} XrPerformanceMetricsStateANDROID; + +typedef struct XrPerformanceMetricsCounterANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPerformanceMetricsCounterFlagsANDROID counterFlags; + XrPerformanceMetricsCounterUnitANDROID counterUnit; + uint32_t uintValue; + float floatValue; +} XrPerformanceMetricsCounterANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumeratePerformanceMetricsCounterPathsANDROID)(XrInstance instance, uint32_t counterPathCapacityInput, uint32_t* counterPathCountOutput, XrPath* counterPaths); +typedef XrResult (XRAPI_PTR *PFN_xrSetPerformanceMetricsStateANDROID)(XrSession session, const XrPerformanceMetricsStateANDROID* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetPerformanceMetricsStateANDROID)(XrSession session, XrPerformanceMetricsStateANDROID* state); +typedef XrResult (XRAPI_PTR *PFN_xrQueryPerformanceMetricsCounterANDROID)(XrSession session, XrPath counterPath, XrPerformanceMetricsCounterANDROID* counter); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumeratePerformanceMetricsCounterPathsANDROID( + XrInstance instance, + uint32_t counterPathCapacityInput, + uint32_t* counterPathCountOutput, + XrPath* counterPaths); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetPerformanceMetricsStateANDROID( + XrSession session, + const XrPerformanceMetricsStateANDROID* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPerformanceMetricsStateANDROID( + XrSession session, + XrPerformanceMetricsStateANDROID* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrQueryPerformanceMetricsCounterANDROID( + XrSession session, + XrPath counterPath, + XrPerformanceMetricsCounterANDROID* counter); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_trackables_object is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_trackables_object 1 +#define XR_ANDROID_trackables_object_SPEC_VERSION 2 +#define XR_ANDROID_TRACKABLES_OBJECT_EXTENSION_NAME "XR_ANDROID_trackables_object" + +typedef enum XrObjectLabelANDROID { + XR_OBJECT_LABEL_UNKNOWN_ANDROID = 0, + XR_OBJECT_LABEL_KEYBOARD_ANDROID = 1, + XR_OBJECT_LABEL_MOUSE_ANDROID = 2, + XR_OBJECT_LABEL_LAPTOP_ANDROID = 3, + XR_OBJECT_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrObjectLabelANDROID; +typedef struct XrTrackableObjectANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTrackingStateANDROID trackingState; + XrPosef centerPose; + XrExtent3DfEXT extents; + XrObjectLabelANDROID objectLabel; + XrTime lastUpdatedTime; +} XrTrackableObjectANDROID; + +// XrTrackableObjectConfigurationANDROID extends XrTrackableTrackerCreateInfoANDROID +typedef struct XrTrackableObjectConfigurationANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t labelCount; + const XrObjectLabelANDROID* activeLabels; +} XrTrackableObjectConfigurationANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrGetTrackableObjectANDROID)(XrTrackableTrackerANDROID tracker, const XrTrackableGetInfoANDROID* getInfo, XrTrackableObjectANDROID* objectOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetTrackableObjectANDROID( + XrTrackableTrackerANDROID tracker, + const XrTrackableGetInfoANDROID* getInfo, + XrTrackableObjectANDROID* objectOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_unbounded_reference_space is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_unbounded_reference_space 1 +#define XR_ANDROID_unbounded_reference_space_SPEC_VERSION 1 +#define XR_ANDROID_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME "XR_ANDROID_unbounded_reference_space" + + // XR_EXT_future is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_future 1 -#define XR_EXT_future_SPEC_VERSION 1 +#define XR_EXT_future_SPEC_VERSION 2 #define XR_EXT_FUTURE_EXTENSION_NAME "XR_EXT_future" #define XR_NULL_FUTURE_EXT 0 @@ -7986,12 +10798,6 @@ typedef struct XR_MAY_ALIAS XrFutureCompletionBaseHeaderEXT { XrResult futureResult; } XrFutureCompletionBaseHeaderEXT; -typedef struct XrFutureCompletionEXT { - XrStructureType type; - void* XR_MAY_ALIAS next; - XrResult futureResult; -} XrFutureCompletionEXT; - typedef struct XrFuturePollResultEXT { XrStructureType type; void* XR_MAY_ALIAS next; @@ -8429,6 +11235,190 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetFacialExpressionBlendShapePropertiesML( #define XR_YVR_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_YVR_controller_interaction" +// XR_META_boundary_visibility is a preprocessor guard. Do not pass it to API calls. +#define XR_META_boundary_visibility 1 +#define XR_META_boundary_visibility_SPEC_VERSION 1 +#define XR_META_BOUNDARY_VISIBILITY_EXTENSION_NAME "XR_META_boundary_visibility" + +typedef enum XrBoundaryVisibilityMETA { + XR_BOUNDARY_VISIBILITY_NOT_SUPPRESSED_META = 1, + XR_BOUNDARY_VISIBILITY_SUPPRESSED_META = 2, + XR_BOUNDARY_VISIBILITY_MAX_ENUM_META = 0x7FFFFFFF +} XrBoundaryVisibilityMETA; +// XrSystemBoundaryVisibilityPropertiesMETA extends XrSystemProperties +typedef struct XrSystemBoundaryVisibilityPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsBoundaryVisibility; +} XrSystemBoundaryVisibilityPropertiesMETA; + +typedef struct XrEventDataBoundaryVisibilityChangedMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBoundaryVisibilityMETA boundaryVisibility; +} XrEventDataBoundaryVisibilityChangedMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrRequestBoundaryVisibilityMETA)(XrSession session, XrBoundaryVisibilityMETA boundaryVisibility); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrRequestBoundaryVisibilityMETA( + XrSession session, + XrBoundaryVisibilityMETA boundaryVisibility); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_META_simultaneous_hands_and_controllers is a preprocessor guard. Do not pass it to API calls. +#define XR_META_simultaneous_hands_and_controllers 1 +#define XR_META_simultaneous_hands_and_controllers_SPEC_VERSION 1 +#define XR_META_SIMULTANEOUS_HANDS_AND_CONTROLLERS_EXTENSION_NAME "XR_META_simultaneous_hands_and_controllers" +// XrSystemSimultaneousHandsAndControllersPropertiesMETA extends XrSystemProperties +typedef struct XrSystemSimultaneousHandsAndControllersPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSimultaneousHandsAndControllers; +} XrSystemSimultaneousHandsAndControllersPropertiesMETA; + +typedef struct XrSimultaneousHandsAndControllersTrackingResumeInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSimultaneousHandsAndControllersTrackingResumeInfoMETA; + +typedef struct XrSimultaneousHandsAndControllersTrackingPauseInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSimultaneousHandsAndControllersTrackingPauseInfoMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrResumeSimultaneousHandsAndControllersTrackingMETA)(XrSession session, const XrSimultaneousHandsAndControllersTrackingResumeInfoMETA* resumeInfo); +typedef XrResult (XRAPI_PTR *PFN_xrPauseSimultaneousHandsAndControllersTrackingMETA)(XrSession session, const XrSimultaneousHandsAndControllersTrackingPauseInfoMETA* pauseInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrResumeSimultaneousHandsAndControllersTrackingMETA( + XrSession session, + const XrSimultaneousHandsAndControllersTrackingResumeInfoMETA* resumeInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrPauseSimultaneousHandsAndControllersTrackingMETA( + XrSession session, + const XrSimultaneousHandsAndControllersTrackingPauseInfoMETA* pauseInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_META_face_tracking_visemes is a preprocessor guard. Do not pass it to API calls. +#define XR_META_face_tracking_visemes 1 +#define XR_FACE_TRACKING_VISEME_COUNT_META 15 +#define XR_META_face_tracking_visemes_SPEC_VERSION 1 +#define XR_META_FACE_TRACKING_VISEMES_EXTENSION_NAME "XR_META_face_tracking_visemes" + +typedef enum XrFaceTrackingVisemeMETA { + XR_FACE_TRACKING_VISEME_SIL_META = 0, + XR_FACE_TRACKING_VISEME_PP_META = 1, + XR_FACE_TRACKING_VISEME_FF_META = 2, + XR_FACE_TRACKING_VISEME_TH_META = 3, + XR_FACE_TRACKING_VISEME_DD_META = 4, + XR_FACE_TRACKING_VISEME_KK_META = 5, + XR_FACE_TRACKING_VISEME_CH_META = 6, + XR_FACE_TRACKING_VISEME_SS_META = 7, + XR_FACE_TRACKING_VISEME_NN_META = 8, + XR_FACE_TRACKING_VISEME_RR_META = 9, + XR_FACE_TRACKING_VISEME_AA_META = 10, + XR_FACE_TRACKING_VISEME_E_META = 11, + XR_FACE_TRACKING_VISEME_IH_META = 12, + XR_FACE_TRACKING_VISEME_OH_META = 13, + XR_FACE_TRACKING_VISEME_OU_META = 14, + XR_FACE_TRACKING_VISEME_MAX_ENUM_META = 0x7FFFFFFF +} XrFaceTrackingVisemeMETA; +// XrFaceTrackingVisemesMETA extends XrFaceExpressionWeights2FB +typedef struct XrFaceTrackingVisemesMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 isValid; + float visemes[XR_FACE_TRACKING_VISEME_COUNT_META]; +} XrFaceTrackingVisemesMETA; + +// XrSystemFaceTrackingVisemesPropertiesMETA extends XrSystemProperties +typedef struct XrSystemFaceTrackingVisemesPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsVisemes; +} XrSystemFaceTrackingVisemesPropertiesMETA; + + + +// XR_META_spatial_entity_semantic_label is a preprocessor guard. Do not pass it to API calls. +#define XR_META_spatial_entity_semantic_label 1 +#define XR_META_spatial_entity_semantic_label_SPEC_VERSION 1 +#define XR_META_SPATIAL_ENTITY_SEMANTIC_LABEL_EXTENSION_NAME "XR_META_spatial_entity_semantic_label" + +typedef enum XrSemanticLabelMETA { + XR_SEMANTIC_LABEL_UNKNOWN_META = 0, + XR_SEMANTIC_LABEL_FLOOR_META = 1, + XR_SEMANTIC_LABEL_CEILING_META = 2, + XR_SEMANTIC_LABEL_WALL_FACE_META = 3, + XR_SEMANTIC_LABEL_INNER_WALL_FACE_META = 4, + XR_SEMANTIC_LABEL_INVISIBLE_WALL_FACE_META = 5, + XR_SEMANTIC_LABEL_DOOR_FRAME_META = 6, + XR_SEMANTIC_LABEL_WINDOW_FRAME_META = 7, + XR_SEMANTIC_LABEL_MAX_ENUM_META = 0x7FFFFFFF +} XrSemanticLabelMETA; + + +// XR_META_spatial_entity_room_mesh is a preprocessor guard. Do not pass it to API calls. +#define XR_META_spatial_entity_room_mesh 1 +#define XR_META_spatial_entity_room_mesh_SPEC_VERSION 1 +#define XR_META_SPATIAL_ENTITY_ROOM_MESH_EXTENSION_NAME "XR_META_spatial_entity_room_mesh" +typedef struct XrRoomMeshFaceMETA { + XrUuid uuid; + XrUuid parentUuid; + XrSemanticLabelMETA semanticLabel; +} XrRoomMeshFaceMETA; + +typedef struct XrRoomMeshFaceIndicesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint32_t* indices; +} XrRoomMeshFaceIndicesMETA; + +typedef struct XrSpaceRoomMeshGetInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t recognizedSemanticLabelCount; + const XrSemanticLabelMETA* recognizedSemanticLabels; +} XrSpaceRoomMeshGetInfoMETA; + +typedef struct XrRoomMeshMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector3f* vertices; + uint32_t faceCapacityInput; + uint32_t faceCountOutput; + XrRoomMeshFaceMETA* faces; +} XrRoomMeshMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceRoomMeshMETA)(XrSpace space, const XrSpaceRoomMeshGetInfoMETA* getInfo, XrRoomMeshMETA* roomMeshOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceRoomMeshFaceIndicesMETA)(XrSpace space, const XrUuid* faceUuid, XrRoomMeshFaceIndicesMETA* roomMeshFaceIndicesOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceRoomMeshMETA( + XrSpace space, + const XrSpaceRoomMeshGetInfoMETA* getInfo, + XrRoomMeshMETA* roomMeshOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceRoomMeshFaceIndicesMETA( + XrSpace space, + const XrUuid* faceUuid, + XrRoomMeshFaceIndicesMETA* roomMeshFaceIndicesOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + // XR_EXT_composition_layer_inverted_alpha is a preprocessor guard. Do not pass it to API calls. #define XR_EXT_composition_layer_inverted_alpha 1 #define XR_EXT_composition_layer_inverted_alpha_SPEC_VERSION 1 @@ -8569,6 +11559,7 @@ typedef struct XrShareSpacesRecipientGroupsMETA { XrUuid* groups; } XrShareSpacesRecipientGroupsMETA; +// XrSpaceGroupUuidFilterInfoMETA extends XrSpaceQueryInfoBaseHeaderFB typedef struct XrSpaceGroupUuidFilterInfoMETA { XrStructureType type; const void* XR_MAY_ALIAS next; @@ -8576,6 +11567,1589 @@ typedef struct XrSpaceGroupUuidFilterInfoMETA { } XrSpaceGroupUuidFilterInfoMETA; + +// XR_META_environment_raycast is a preprocessor guard. Do not pass it to API calls. +#define XR_META_environment_raycast 1 +XR_DEFINE_HANDLE(XrEnvironmentRaycasterMETA) +#define XR_META_environment_raycast_SPEC_VERSION 1 +#define XR_META_ENVIRONMENT_RAYCAST_EXTENSION_NAME "XR_META_environment_raycast" + +typedef enum XrEnvironmentRaycastHitStatusMETA { + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_META = 1, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_NO_HIT_META = 2, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_POINT_OCCLUDED_META = 3, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_POINT_OUTSIDE_OF_FOV_META = 4, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_RAY_OCCLUDED_META = 5, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_INVALID_ORIENTATION_META = 6, + XR_ENVIRONMENT_RAYCAST_HIT_STATUS_MAX_ENUM_META = 0x7FFFFFFF +} XrEnvironmentRaycastHitStatusMETA; +// XrSystemEnvironmentRaycastPropertiesMETA extends XrSystemProperties +typedef struct XrSystemEnvironmentRaycastPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsEnvironmentRaycast; +} XrSystemEnvironmentRaycastPropertiesMETA; + +typedef struct XrEnvironmentRaycasterCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEnvironmentRaycasterCreateInfoMETA; + +typedef struct XrEnvironmentRaycasterCreateCompletionMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrEnvironmentRaycasterMETA environmentRaycaster; +} XrEnvironmentRaycasterCreateCompletionMETA; + +typedef struct XR_MAY_ALIAS XrEnvironmentRaycastFilterBaseHeaderMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEnvironmentRaycastFilterBaseHeaderMETA; + +typedef struct XrEnvironmentRaycastHitGetInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrVector3f origin; + XrVector3f direction; + uint32_t filterCount; + const XrEnvironmentRaycastFilterBaseHeaderMETA* const * filters; +} XrEnvironmentRaycastHitGetInfoMETA; + +typedef struct XrEnvironmentRaycastHitMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrEnvironmentRaycastHitStatusMETA status; + XrPosef pose; +} XrEnvironmentRaycastHitMETA; + +typedef struct XrEnvironmentRaycastFilterDistanceMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float maxDistance; +} XrEnvironmentRaycastFilterDistanceMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateEnvironmentRaycasterAsyncMETA)(XrSession session, const XrEnvironmentRaycasterCreateInfoMETA* info, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateEnvironmentRaycasterCompleteMETA)(XrSession session, XrFutureEXT future, XrEnvironmentRaycasterCreateCompletionMETA* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyEnvironmentRaycasterMETA)(XrEnvironmentRaycasterMETA environmentRaycaster); +typedef XrResult (XRAPI_PTR *PFN_xrPerformEnvironmentRaycastMETA)(XrEnvironmentRaycasterMETA environmentRaycaster, const XrEnvironmentRaycastHitGetInfoMETA* info, XrEnvironmentRaycastHitMETA* hitPoint); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateEnvironmentRaycasterAsyncMETA( + XrSession session, + const XrEnvironmentRaycasterCreateInfoMETA* info, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateEnvironmentRaycasterCompleteMETA( + XrSession session, + XrFutureEXT future, + XrEnvironmentRaycasterCreateCompletionMETA* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyEnvironmentRaycasterMETA( + XrEnvironmentRaycasterMETA environmentRaycaster); + +XRAPI_ATTR XrResult XRAPI_CALL xrPerformEnvironmentRaycastMETA( + XrEnvironmentRaycasterMETA environmentRaycaster, + const XrEnvironmentRaycastHitGetInfoMETA* info, + XrEnvironmentRaycastHitMETA* hitPoint); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_META_tile_properties_hint is a preprocessor guard. Do not pass it to API calls. +#define XR_META_tile_properties_hint 1 +#define XR_META_tile_properties_hint_SPEC_VERSION 1 +#define XR_META_TILE_PROPERTIES_HINT_EXTENSION_NAME "XR_META_tile_properties_hint" +typedef struct XrExtent3DiMETA { + int32_t width; + int32_t height; + int32_t depth; +} XrExtent3DiMETA; + +typedef struct XrTilePropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrExtent3DiMETA tileDimensions; + XrExtent2Di apronDimensions; + XrOffset2Di origin; +} XrTilePropertiesMETA; + +typedef struct XrTilePropertiesHintMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t propertiesCount; + const XrTilePropertiesMETA* properties; +} XrTilePropertiesHintMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrSetTilePropertiesHintMETA)(XrSession session, const XrTilePropertiesHintMETA* properties); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetTilePropertiesHintMETA( + XrSession session, + const XrTilePropertiesHintMETA* properties); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_light_estimation is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_light_estimation 1 +XR_DEFINE_HANDLE(XrLightEstimatorANDROID) +#define XR_ANDROID_light_estimation_SPEC_VERSION 1 +#define XR_ANDROID_LIGHT_ESTIMATION_EXTENSION_NAME "XR_ANDROID_light_estimation" + +typedef enum XrLightEstimateStateANDROID { + XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID = 0, + XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID = 1, + XR_LIGHT_ESTIMATE_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrLightEstimateStateANDROID; + +typedef enum XrSphericalHarmonicsKindANDROID { + XR_SPHERICAL_HARMONICS_KIND_TOTAL_ANDROID = 0, + XR_SPHERICAL_HARMONICS_KIND_AMBIENT_ANDROID = 1, + XR_SPHERICAL_HARMONICS_KIND_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrSphericalHarmonicsKindANDROID; +// XrSystemLightEstimationPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemLightEstimationPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsLightEstimation; +} XrSystemLightEstimationPropertiesANDROID; + +typedef struct XrLightEstimatorCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrLightEstimatorCreateInfoANDROID; + +typedef struct XrLightEstimateGetInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrTime time; +} XrLightEstimateGetInfoANDROID; + +typedef struct XrLightEstimateANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrLightEstimateStateANDROID state; + XrTime lastUpdatedTime; +} XrLightEstimateANDROID; + +// XrDirectionalLightANDROID extends XrLightEstimateANDROID +typedef struct XrDirectionalLightANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrLightEstimateStateANDROID state; + XrVector3f intensity; + XrVector3f direction; +} XrDirectionalLightANDROID; + +// XrAmbientLightANDROID extends XrLightEstimateANDROID +typedef struct XrAmbientLightANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrLightEstimateStateANDROID state; + XrVector3f intensity; + XrVector3f colorCorrection; +} XrAmbientLightANDROID; + +// XrSphericalHarmonicsANDROID extends XrLightEstimateANDROID +typedef struct XrSphericalHarmonicsANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrLightEstimateStateANDROID state; + XrSphericalHarmonicsKindANDROID kind; + float coefficients[9][3]; +} XrSphericalHarmonicsANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateLightEstimatorANDROID)(XrSession session, XrLightEstimatorCreateInfoANDROID* createInfo, XrLightEstimatorANDROID* outHandle); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyLightEstimatorANDROID)(XrLightEstimatorANDROID estimator); +typedef XrResult (XRAPI_PTR *PFN_xrGetLightEstimateANDROID)(XrLightEstimatorANDROID estimator, const XrLightEstimateGetInfoANDROID* input, XrLightEstimateANDROID* output); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateLightEstimatorANDROID( + XrSession session, + XrLightEstimatorCreateInfoANDROID* createInfo, + XrLightEstimatorANDROID* outHandle); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyLightEstimatorANDROID( + XrLightEstimatorANDROID estimator); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetLightEstimateANDROID( + XrLightEstimatorANDROID estimator, + const XrLightEstimateGetInfoANDROID* input, + XrLightEstimateANDROID* output); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_mouse_interaction is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_mouse_interaction 1 +#define XR_ANDROID_mouse_interaction_SPEC_VERSION 1 +#define XR_ANDROID_MOUSE_INTERACTION_EXTENSION_NAME "XR_ANDROID_mouse_interaction" + + +// XR_ANDROID_trackables_marker is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_trackables_marker 1 +#define XR_ANDROID_trackables_marker_SPEC_VERSION 1 +#define XR_ANDROID_TRACKABLES_MARKER_EXTENSION_NAME "XR_ANDROID_trackables_marker" + +typedef enum XrTrackableMarkerTrackingModeANDROID { + XR_TRACKABLE_MARKER_TRACKING_MODE_DYNAMIC_ANDROID = 0, + XR_TRACKABLE_MARKER_TRACKING_MODE_STATIC_ANDROID = 1, + XR_TRACKABLE_MARKER_TRACKING_MODE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackableMarkerTrackingModeANDROID; + +typedef enum XrTrackableMarkerDictionaryANDROID { + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_50_ANDROID = 0, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_100_ANDROID = 1, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_250_ANDROID = 2, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_1000_ANDROID = 3, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_50_ANDROID = 4, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_100_ANDROID = 5, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_250_ANDROID = 6, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_1000_ANDROID = 7, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_50_ANDROID = 8, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_100_ANDROID = 9, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_250_ANDROID = 10, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_1000_ANDROID = 11, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_50_ANDROID = 12, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_100_ANDROID = 13, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_250_ANDROID = 14, + XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_1000_ANDROID = 15, + XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_16H5_ANDROID = 16, + XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_25H9_ANDROID = 17, + XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_36H10_ANDROID = 18, + XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_36H11_ANDROID = 19, + XR_TRACKABLE_MARKER_DICTIONARY_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackableMarkerDictionaryANDROID; +// XrSystemMarkerTrackingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemMarkerTrackingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsMarkerTracking; + XrBool32 supportsMarkerSizeEstimation; + uint16_t maxMarkerCount; +} XrSystemMarkerTrackingPropertiesANDROID; + +typedef struct XrTrackableMarkerDatabaseEntryANDROID { + int32_t id; + float edgeSize; +} XrTrackableMarkerDatabaseEntryANDROID; + +typedef struct XrTrackableMarkerDatabaseANDROID { + XrTrackableMarkerDictionaryANDROID dictionary; + uint32_t entryCount; + const XrTrackableMarkerDatabaseEntryANDROID* entries; +} XrTrackableMarkerDatabaseANDROID; + +// XrTrackableMarkerConfigurationANDROID extends XrTrackableTrackerCreateInfoANDROID +typedef struct XrTrackableMarkerConfigurationANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTrackableMarkerTrackingModeANDROID trackingMode; + uint32_t databaseCount; + const XrTrackableMarkerDatabaseANDROID* databases; +} XrTrackableMarkerConfigurationANDROID; + +typedef struct XrTrackableMarkerANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTrackingStateANDROID trackingState; + XrTime lastUpdatedTime; + XrTrackableMarkerDictionaryANDROID dictionary; + int32_t markerId; + XrPosef centerPose; + XrExtent2Df extents; +} XrTrackableMarkerANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrGetTrackableMarkerANDROID)(XrTrackableTrackerANDROID tracker, const XrTrackableGetInfoANDROID* getInfo, XrTrackableMarkerANDROID* markerOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetTrackableMarkerANDROID( + XrTrackableTrackerANDROID tracker, + const XrTrackableGetInfoANDROID* getInfo, + XrTrackableMarkerANDROID* markerOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_trackables_qr_code is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_trackables_qr_code 1 +#define XR_ANDROID_trackables_qr_code_SPEC_VERSION 1 +#define XR_ANDROID_TRACKABLES_QR_CODE_EXTENSION_NAME "XR_ANDROID_trackables_qr_code" + +typedef enum XrQrCodeTrackingModeANDROID { + XR_QR_CODE_TRACKING_MODE_DYNAMIC_ANDROID = 0, + XR_QR_CODE_TRACKING_MODE_STATIC_ANDROID = 1, + XR_QR_CODE_TRACKING_MODE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrQrCodeTrackingModeANDROID; +// XrSystemQrCodeTrackingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemQrCodeTrackingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsQrCodeTracking; + XrBool32 supportsQrCodeSizeEstimation; + uint16_t maxQrCodeCount; +} XrSystemQrCodeTrackingPropertiesANDROID; + +// XrTrackableQrCodeConfigurationANDROID extends XrTrackableTrackerCreateInfoANDROID +typedef struct XrTrackableQrCodeConfigurationANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrQrCodeTrackingModeANDROID trackingMode; + float qrCodeEdgeSize; +} XrTrackableQrCodeConfigurationANDROID; + +typedef struct XrTrackableQrCodeANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTrackingStateANDROID trackingState; + XrTime lastUpdatedTime; + XrPosef centerPose; + XrExtent2Df extents; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + char* buffer; +} XrTrackableQrCodeANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrGetTrackableQrCodeANDROID)(XrTrackableTrackerANDROID tracker, const XrTrackableGetInfoANDROID* getInfo, XrTrackableQrCodeANDROID* qrCodeOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetTrackableQrCodeANDROID( + XrTrackableTrackerANDROID tracker, + const XrTrackableGetInfoANDROID* getInfo, + XrTrackableQrCodeANDROID* qrCodeOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_trackables_image is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_trackables_image 1 +XR_DEFINE_HANDLE(XrTrackableImageDatabaseANDROID) +#define XR_ANDROID_trackables_image_SPEC_VERSION 1 +#define XR_ANDROID_TRACKABLES_IMAGE_EXTENSION_NAME "XR_ANDROID_trackables_image" + +typedef enum XrTrackableImageTrackingModeANDROID { + XR_TRACKABLE_IMAGE_TRACKING_MODE_DYNAMIC_ANDROID = 1, + XR_TRACKABLE_IMAGE_TRACKING_MODE_STATIC_ANDROID = 2, + XR_TRACKABLE_IMAGE_TRACKING_MODE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackableImageTrackingModeANDROID; + +typedef enum XrTrackableImageFormatANDROID { + XR_TRACKABLE_IMAGE_FORMAT_R8G8B8A8_ANDROID = 1, + XR_TRACKABLE_IMAGE_FORMAT_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrTrackableImageFormatANDROID; +// XrSystemImageTrackingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemImageTrackingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsImageTracking; + XrBool32 supportsPhysicalSizeEstimation; + uint32_t maxTrackedImageCount; + uint32_t maxLoadedImageCount; +} XrSystemImageTrackingPropertiesANDROID; + +typedef struct XrTrackableImageDatabaseEntryANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTrackableImageTrackingModeANDROID trackingMode; + float physicalWidth; + uint32_t imageWidth; + uint32_t imageHeight; + XrTrackableImageFormatANDROID format; + uint32_t bufferSize; + const uint8_t* buffer; +} XrTrackableImageDatabaseEntryANDROID; + +typedef struct XrTrackableImageDatabaseCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t entryCount; + const XrTrackableImageDatabaseEntryANDROID* entries; +} XrTrackableImageDatabaseCreateInfoANDROID; + +typedef struct XrCreateTrackableImageDatabaseCompletionANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrTrackableImageDatabaseANDROID database; +} XrCreateTrackableImageDatabaseCompletionANDROID; + +typedef struct XrTrackableImageConfigurationANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t databaseCount; + const XrTrackableImageDatabaseANDROID* databases; +} XrTrackableImageConfigurationANDROID; + +typedef struct XrTrackableImageANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTrackingStateANDROID trackingState; + XrTime lastUpdatedTime; + XrTrackableImageDatabaseANDROID database; + uint32_t databaseEntryIndex; + XrPosef centerPose; + XrExtent2Df extents; +} XrTrackableImageANDROID; + +typedef struct XrEventDataImageTrackingLostANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; +} XrEventDataImageTrackingLostANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateTrackableImageDatabaseAsyncANDROID)(XrSession session, const XrTrackableImageDatabaseCreateInfoANDROID* createInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateTrackableImageDatabaseCompleteANDROID)(XrSession session, XrFutureEXT future, XrCreateTrackableImageDatabaseCompletionANDROID* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyTrackableImageDatabaseANDROID)(XrTrackableImageDatabaseANDROID database); +typedef XrResult (XRAPI_PTR *PFN_xrAddTrackableImageDatabaseANDROID)(XrTrackableTrackerANDROID tracker, XrTrackableImageDatabaseANDROID database); +typedef XrResult (XRAPI_PTR *PFN_xrRemoveTrackableImageDatabaseANDROID)(XrTrackableTrackerANDROID tracker, XrTrackableImageDatabaseANDROID database); +typedef XrResult (XRAPI_PTR *PFN_xrGetTrackableImageANDROID)(XrTrackableTrackerANDROID tracker, const XrTrackableGetInfoANDROID* getInfo, XrTrackableImageANDROID* trackable); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateTrackableImageDatabaseAsyncANDROID( + XrSession session, + const XrTrackableImageDatabaseCreateInfoANDROID* createInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateTrackableImageDatabaseCompleteANDROID( + XrSession session, + XrFutureEXT future, + XrCreateTrackableImageDatabaseCompletionANDROID* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyTrackableImageDatabaseANDROID( + XrTrackableImageDatabaseANDROID database); + +XRAPI_ATTR XrResult XRAPI_CALL xrAddTrackableImageDatabaseANDROID( + XrTrackableTrackerANDROID tracker, + XrTrackableImageDatabaseANDROID database); + +XRAPI_ATTR XrResult XRAPI_CALL xrRemoveTrackableImageDatabaseANDROID( + XrTrackableTrackerANDROID tracker, + XrTrackableImageDatabaseANDROID database); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetTrackableImageANDROID( + XrTrackableTrackerANDROID tracker, + const XrTrackableGetInfoANDROID* getInfo, + XrTrackableImageANDROID* trackable); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_scene_meshing is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_scene_meshing 1 +XR_DEFINE_HANDLE(XrSceneMeshingTrackerANDROID) +XR_DEFINE_HANDLE(XrSceneMeshSnapshotANDROID) +#define XR_ANDROID_scene_meshing_SPEC_VERSION 3 +#define XR_ANDROID_SCENE_MESHING_EXTENSION_NAME "XR_ANDROID_scene_meshing" + +typedef enum XrSceneMeshSemanticLabelSetANDROID { + XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID = 0, + XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID = 1, + XR_SCENE_MESH_SEMANTIC_LABEL_SET_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrSceneMeshSemanticLabelSetANDROID; + +typedef enum XrSceneMeshTrackingStateANDROID { + XR_SCENE_MESH_TRACKING_STATE_INITIALIZING_ANDROID = 0, + XR_SCENE_MESH_TRACKING_STATE_TRACKING_ANDROID = 1, + XR_SCENE_MESH_TRACKING_STATE_WAITING_ANDROID = 2, + XR_SCENE_MESH_TRACKING_STATE_ERROR_ANDROID = 3, + XR_SCENE_MESH_TRACKING_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrSceneMeshTrackingStateANDROID; + +typedef enum XrSceneMeshSemanticLabelANDROID { + XR_SCENE_MESH_SEMANTIC_LABEL_OTHER_ANDROID = 0, + XR_SCENE_MESH_SEMANTIC_LABEL_FLOOR_ANDROID = 1, + XR_SCENE_MESH_SEMANTIC_LABEL_CEILING_ANDROID = 2, + XR_SCENE_MESH_SEMANTIC_LABEL_WALL_ANDROID = 3, + XR_SCENE_MESH_SEMANTIC_LABEL_TABLE_ANDROID = 4, + XR_SCENE_MESH_SEMANTIC_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrSceneMeshSemanticLabelANDROID; +// XrSystemSceneMeshingPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemSceneMeshingPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsSceneMeshing; +} XrSystemSceneMeshingPropertiesANDROID; + +typedef struct XrSceneMeshingTrackerCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSceneMeshSemanticLabelSetANDROID semanticLabelSet; + XrBool32 enableNormals; +} XrSceneMeshingTrackerCreateInfoANDROID; + +typedef struct XrSceneMeshSnapshotCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrBoxf boundingBox; +} XrSceneMeshSnapshotCreateInfoANDROID; + +typedef struct XrSceneMeshSnapshotCreationResultANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSceneMeshSnapshotANDROID snapshot; + XrSceneMeshTrackingStateANDROID trackingState; +} XrSceneMeshSnapshotCreationResultANDROID; + +typedef struct XrSceneSubmeshStateANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuid submeshId; + XrTime lastUpdatedTime; + XrPosef submeshPoseInBaseSpace; + XrExtent3Df bounds; +} XrSceneSubmeshStateANDROID; + +typedef struct XrSceneSubmeshDataANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuid submeshId; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector3f* vertexPositions; + XrVector3f* vertexNormals; + uint8_t* vertexSemantics; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint32_t* indices; +} XrSceneSubmeshDataANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSupportedSemanticLabelSetsANDROID)(XrInstance instance, XrSystemId systemId, uint32_t supportedSemanticLabelSetsInputCapacity, uint32_t* supportedSemanticLabelSetsOutputCount, XrSceneMeshSemanticLabelSetANDROID* supportedSemanticLabelSets); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSceneMeshingTrackerANDROID)(XrSession session, const XrSceneMeshingTrackerCreateInfoANDROID* createInfo, XrSceneMeshingTrackerANDROID* tracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySceneMeshingTrackerANDROID)(XrSceneMeshingTrackerANDROID tracker); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSceneMeshSnapshotANDROID)(XrSceneMeshingTrackerANDROID tracker, const XrSceneMeshSnapshotCreateInfoANDROID* createInfo, XrSceneMeshSnapshotCreationResultANDROID* outSnapshotCreationResult); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySceneMeshSnapshotANDROID)(XrSceneMeshSnapshotANDROID snapshot); +typedef XrResult (XRAPI_PTR *PFN_xrGetAllSubmeshStatesANDROID)(XrSceneMeshSnapshotANDROID snapshot, uint32_t submeshStateCapacityInput, uint32_t* submeshStateCountOutput, XrSceneSubmeshStateANDROID* submeshStates); +typedef XrResult (XRAPI_PTR *PFN_xrGetSubmeshDataANDROID)(XrSceneMeshSnapshotANDROID snapshot, uint32_t submeshDataCount, XrSceneSubmeshDataANDROID* inoutSubmeshData); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSupportedSemanticLabelSetsANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t supportedSemanticLabelSetsInputCapacity, + uint32_t* supportedSemanticLabelSetsOutputCount, + XrSceneMeshSemanticLabelSetANDROID* supportedSemanticLabelSets); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSceneMeshingTrackerANDROID( + XrSession session, + const XrSceneMeshingTrackerCreateInfoANDROID* createInfo, + XrSceneMeshingTrackerANDROID* tracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySceneMeshingTrackerANDROID( + XrSceneMeshingTrackerANDROID tracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSceneMeshSnapshotANDROID( + XrSceneMeshingTrackerANDROID tracker, + const XrSceneMeshSnapshotCreateInfoANDROID* createInfo, + XrSceneMeshSnapshotCreationResultANDROID* outSnapshotCreationResult); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySceneMeshSnapshotANDROID( + XrSceneMeshSnapshotANDROID snapshot); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetAllSubmeshStatesANDROID( + XrSceneMeshSnapshotANDROID snapshot, + uint32_t submeshStateCapacityInput, + uint32_t* submeshStateCountOutput, + XrSceneSubmeshStateANDROID* submeshStates); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSubmeshDataANDROID( + XrSceneMeshSnapshotANDROID snapshot, + uint32_t submeshDataCount, + XrSceneSubmeshDataANDROID* inoutSubmeshData); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_spatial_entity is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_entity 1 + +#define XR_NULL_SPATIAL_ENTITY_ID_EXT 0 + + +#define XR_NULL_SPATIAL_BUFFER_ID_EXT 0 + +XR_DEFINE_ATOM(XrSpatialEntityIdEXT) +XR_DEFINE_ATOM(XrSpatialBufferIdEXT) +XR_DEFINE_HANDLE(XrSpatialEntityEXT) +XR_DEFINE_HANDLE(XrSpatialContextEXT) +XR_DEFINE_HANDLE(XrSpatialSnapshotEXT) +#define XR_EXT_spatial_entity_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_ENTITY_EXTENSION_NAME "XR_EXT_spatial_entity" + +typedef enum XrSpatialCapabilityEXT { + XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT = 1000741000, + XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT = 1000743000, + XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT = 1000743001, + XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT = 1000743002, + XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT = 1000743003, + XR_SPATIAL_CAPABILITY_ANCHOR_EXT = 1000762000, + XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID = 1000785000, + XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID = 1000786000, + XR_SPATIAL_CAPABILITY_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialCapabilityEXT; + +typedef enum XrSpatialCapabilityFeatureEXT { + XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT = 1000743000, + XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT = 1000743001, + XR_SPATIAL_CAPABILITY_FEATURE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialCapabilityFeatureEXT; + +typedef enum XrSpatialComponentTypeEXT { + XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT = 1, + XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT = 2, + XR_SPATIAL_COMPONENT_TYPE_PARENT_EXT = 3, + XR_SPATIAL_COMPONENT_TYPE_MESH_3D_EXT = 4, + XR_SPATIAL_COMPONENT_TYPE_PLANE_ALIGNMENT_EXT = 1000741000, + XR_SPATIAL_COMPONENT_TYPE_MESH_2D_EXT = 1000741001, + XR_SPATIAL_COMPONENT_TYPE_POLYGON_2D_EXT = 1000741002, + XR_SPATIAL_COMPONENT_TYPE_PLANE_SEMANTIC_LABEL_EXT = 1000741003, + XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT = 1000743000, + XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT = 1000762000, + XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT = 1000763000, + XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID = 1000785000, + XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID = 1000786000, + XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID = 1000791000, + XR_SPATIAL_COMPONENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialComponentTypeEXT; + +typedef enum XrSpatialEntityTrackingStateEXT { + XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT = 1, + XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT = 2, + XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT = 3, + XR_SPATIAL_ENTITY_TRACKING_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialEntityTrackingStateEXT; + +typedef enum XrSpatialBufferTypeEXT { + XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT = 0, + XR_SPATIAL_BUFFER_TYPE_STRING_EXT = 1, + XR_SPATIAL_BUFFER_TYPE_UINT8_EXT = 2, + XR_SPATIAL_BUFFER_TYPE_UINT16_EXT = 3, + XR_SPATIAL_BUFFER_TYPE_UINT32_EXT = 4, + XR_SPATIAL_BUFFER_TYPE_FLOAT_EXT = 5, + XR_SPATIAL_BUFFER_TYPE_VECTOR2F_EXT = 6, + XR_SPATIAL_BUFFER_TYPE_VECTOR3F_EXT = 7, + XR_SPATIAL_BUFFER_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialBufferTypeEXT; +typedef struct XrSpatialCapabilityComponentTypesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t componentTypeCapacityInput; + uint32_t componentTypeCountOutput; + XrSpatialComponentTypeEXT* componentTypes; +} XrSpatialCapabilityComponentTypesEXT; + +typedef struct XR_MAY_ALIAS XrSpatialCapabilityConfigurationBaseHeaderEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationBaseHeaderEXT; + +typedef struct XrSpatialContextCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t capabilityConfigCount; + const XrSpatialCapabilityConfigurationBaseHeaderEXT* const* capabilityConfigs; +} XrSpatialContextCreateInfoEXT; + +typedef struct XrCreateSpatialContextCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSpatialContextEXT spatialContext; +} XrCreateSpatialContextCompletionEXT; + +typedef struct XrSpatialDiscoverySnapshotCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t componentTypeCount; + const XrSpatialComponentTypeEXT* componentTypes; +} XrSpatialDiscoverySnapshotCreateInfoEXT; + +typedef struct XrCreateSpatialDiscoverySnapshotCompletionInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrFutureEXT future; +} XrCreateSpatialDiscoverySnapshotCompletionInfoEXT; + +typedef struct XrCreateSpatialDiscoverySnapshotCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSpatialSnapshotEXT snapshot; +} XrCreateSpatialDiscoverySnapshotCompletionEXT; + +typedef struct XrSpatialComponentDataQueryConditionEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t componentTypeCount; + const XrSpatialComponentTypeEXT* componentTypes; +} XrSpatialComponentDataQueryConditionEXT; + +typedef struct XrSpatialComponentDataQueryResultEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t entityIdCapacityInput; + uint32_t entityIdCountOutput; + XrSpatialEntityIdEXT* entityIds; + uint32_t entityStateCapacityInput; + uint32_t entityStateCountOutput; + XrSpatialEntityTrackingStateEXT* entityStates; +} XrSpatialComponentDataQueryResultEXT; + +typedef struct XrSpatialBufferEXT { + XrSpatialBufferIdEXT bufferId; + XrSpatialBufferTypeEXT bufferType; +} XrSpatialBufferEXT; + +typedef struct XrSpatialBufferGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialBufferIdEXT bufferId; +} XrSpatialBufferGetInfoEXT; + +typedef struct XrSpatialBounded2DDataEXT { + XrPosef center; + XrExtent2Df extents; +} XrSpatialBounded2DDataEXT; + +// XrSpatialComponentBounded2DListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentBounded2DListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t boundCount; + XrSpatialBounded2DDataEXT* bounds; +} XrSpatialComponentBounded2DListEXT; + +// XrSpatialComponentBounded3DListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentBounded3DListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t boundCount; + XrBoxf* bounds; +} XrSpatialComponentBounded3DListEXT; + +// XrSpatialComponentParentListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentParentListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t parentCount; + XrSpatialEntityIdEXT* parents; +} XrSpatialComponentParentListEXT; + +typedef struct XrSpatialMeshDataEXT { + XrPosef origin; + XrSpatialBufferEXT vertexBuffer; + XrSpatialBufferEXT indexBuffer; +} XrSpatialMeshDataEXT; + +// XrSpatialComponentMesh3DListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentMesh3DListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t meshCount; + XrSpatialMeshDataEXT* meshes; +} XrSpatialComponentMesh3DListEXT; + +typedef struct XrSpatialEntityFromIdCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialEntityIdEXT entityId; +} XrSpatialEntityFromIdCreateInfoEXT; + +typedef struct XrSpatialUpdateSnapshotCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t entityCount; + const XrSpatialEntityEXT* entities; + uint32_t componentTypeCount; + const XrSpatialComponentTypeEXT* componentTypes; + XrSpace baseSpace; + XrTime time; +} XrSpatialUpdateSnapshotCreateInfoEXT; + +typedef struct XrEventDataSpatialDiscoveryRecommendedEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialContextEXT spatialContext; +} XrEventDataSpatialDiscoveryRecommendedEXT; + +// XrSpatialFilterTrackingStateEXT extends XrSpatialDiscoverySnapshotCreateInfoEXT,XrSpatialComponentDataQueryConditionEXT +typedef struct XrSpatialFilterTrackingStateEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialEntityTrackingStateEXT trackingState; +} XrSpatialFilterTrackingStateEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialCapabilitiesEXT)(XrInstance instance, XrSystemId systemId, uint32_t capabilityCapacityInput, uint32_t* capabilityCountOutput, XrSpatialCapabilityEXT* capabilities); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialCapabilityComponentTypesEXT)(XrInstance instance, XrSystemId systemId, XrSpatialCapabilityEXT capability, XrSpatialCapabilityComponentTypesEXT* capabilityComponents); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialCapabilityFeaturesEXT)(XrInstance instance, XrSystemId systemId, XrSpatialCapabilityEXT capability, uint32_t capabilityFeatureCapacityInput, uint32_t* capabilityFeatureCountOutput, XrSpatialCapabilityFeatureEXT* capabilityFeatures); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialContextAsyncEXT)(XrSession session, const XrSpatialContextCreateInfoEXT* createInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialContextCompleteEXT)(XrSession session, XrFutureEXT future, XrCreateSpatialContextCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialContextEXT)(XrSpatialContextEXT spatialContext); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialDiscoverySnapshotAsyncEXT)(XrSpatialContextEXT spatialContext, const XrSpatialDiscoverySnapshotCreateInfoEXT* createInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialDiscoverySnapshotCompleteEXT)(XrSpatialContextEXT spatialContext, const XrCreateSpatialDiscoverySnapshotCompletionInfoEXT* createSnapshotCompletionInfo, XrCreateSpatialDiscoverySnapshotCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrQuerySpatialComponentDataEXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialComponentDataQueryConditionEXT* queryCondition, XrSpatialComponentDataQueryResultEXT* queryResult); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialSnapshotEXT)(XrSpatialSnapshotEXT snapshot); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialEntityFromIdEXT)(XrSpatialContextEXT spatialContext, const XrSpatialEntityFromIdCreateInfoEXT* createInfo, XrSpatialEntityEXT* spatialEntity); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialEntityEXT)(XrSpatialEntityEXT spatialEntity); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialUpdateSnapshotEXT)(XrSpatialContextEXT spatialContext, const XrSpatialUpdateSnapshotCreateInfoEXT* createInfo, XrSpatialSnapshotEXT* snapshot); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferStringEXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferUint8EXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, uint8_t* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferUint16EXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, uint16_t* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferUint32EXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, uint32_t* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferFloatEXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, float* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferVector2fEXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, XrVector2f* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialBufferVector3fEXT)(XrSpatialSnapshotEXT snapshot, const XrSpatialBufferGetInfoEXT* info, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, XrVector3f* buffer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialCapabilitiesEXT( + XrInstance instance, + XrSystemId systemId, + uint32_t capabilityCapacityInput, + uint32_t* capabilityCountOutput, + XrSpatialCapabilityEXT* capabilities); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialCapabilityComponentTypesEXT( + XrInstance instance, + XrSystemId systemId, + XrSpatialCapabilityEXT capability, + XrSpatialCapabilityComponentTypesEXT* capabilityComponents); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialCapabilityFeaturesEXT( + XrInstance instance, + XrSystemId systemId, + XrSpatialCapabilityEXT capability, + uint32_t capabilityFeatureCapacityInput, + uint32_t* capabilityFeatureCountOutput, + XrSpatialCapabilityFeatureEXT* capabilityFeatures); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialContextAsyncEXT( + XrSession session, + const XrSpatialContextCreateInfoEXT* createInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialContextCompleteEXT( + XrSession session, + XrFutureEXT future, + XrCreateSpatialContextCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialContextEXT( + XrSpatialContextEXT spatialContext); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialDiscoverySnapshotAsyncEXT( + XrSpatialContextEXT spatialContext, + const XrSpatialDiscoverySnapshotCreateInfoEXT* createInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialDiscoverySnapshotCompleteEXT( + XrSpatialContextEXT spatialContext, + const XrCreateSpatialDiscoverySnapshotCompletionInfoEXT* createSnapshotCompletionInfo, + XrCreateSpatialDiscoverySnapshotCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpatialComponentDataEXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialComponentDataQueryConditionEXT* queryCondition, + XrSpatialComponentDataQueryResultEXT* queryResult); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialSnapshotEXT( + XrSpatialSnapshotEXT snapshot); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialEntityFromIdEXT( + XrSpatialContextEXT spatialContext, + const XrSpatialEntityFromIdCreateInfoEXT* createInfo, + XrSpatialEntityEXT* spatialEntity); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialEntityEXT( + XrSpatialEntityEXT spatialEntity); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialUpdateSnapshotEXT( + XrSpatialContextEXT spatialContext, + const XrSpatialUpdateSnapshotCreateInfoEXT* createInfo, + XrSpatialSnapshotEXT* snapshot); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferStringEXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferUint8EXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + uint8_t* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferUint16EXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + uint16_t* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferUint32EXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + uint32_t* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferFloatEXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + float* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferVector2fEXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + XrVector2f* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialBufferVector3fEXT( + XrSpatialSnapshotEXT snapshot, + const XrSpatialBufferGetInfoEXT* info, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + XrVector3f* buffer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_spatial_plane_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_plane_tracking 1 +#define XR_EXT_spatial_plane_tracking_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_PLANE_TRACKING_EXTENSION_NAME "XR_EXT_spatial_plane_tracking" + +typedef enum XrSpatialPlaneAlignmentEXT { + XR_SPATIAL_PLANE_ALIGNMENT_HORIZONTAL_UPWARD_EXT = 0, + XR_SPATIAL_PLANE_ALIGNMENT_HORIZONTAL_DOWNWARD_EXT = 1, + XR_SPATIAL_PLANE_ALIGNMENT_VERTICAL_EXT = 2, + XR_SPATIAL_PLANE_ALIGNMENT_ARBITRARY_EXT = 3, + XR_SPATIAL_PLANE_ALIGNMENT_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialPlaneAlignmentEXT; + +typedef enum XrSpatialPlaneSemanticLabelEXT { + XR_SPATIAL_PLANE_SEMANTIC_LABEL_UNCATEGORIZED_EXT = 1, + XR_SPATIAL_PLANE_SEMANTIC_LABEL_FLOOR_EXT = 2, + XR_SPATIAL_PLANE_SEMANTIC_LABEL_WALL_EXT = 3, + XR_SPATIAL_PLANE_SEMANTIC_LABEL_CEILING_EXT = 4, + XR_SPATIAL_PLANE_SEMANTIC_LABEL_TABLE_EXT = 5, + XR_SPATIAL_PLANE_SEMANTIC_LABEL_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialPlaneSemanticLabelEXT; +typedef struct XrSpatialCapabilityConfigurationPlaneTrackingEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationPlaneTrackingEXT; + +// XrSpatialComponentPlaneAlignmentListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentPlaneAlignmentListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t planeAlignmentCount; + XrSpatialPlaneAlignmentEXT* planeAlignments; +} XrSpatialComponentPlaneAlignmentListEXT; + +// XrSpatialComponentMesh2DListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentMesh2DListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t meshCount; + XrSpatialMeshDataEXT* meshes; +} XrSpatialComponentMesh2DListEXT; + +typedef struct XrSpatialPolygon2DDataEXT { + XrPosef origin; + XrSpatialBufferEXT vertexBuffer; +} XrSpatialPolygon2DDataEXT; + +// XrSpatialComponentPolygon2DListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentPolygon2DListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t polygonCount; + XrSpatialPolygon2DDataEXT* polygons; +} XrSpatialComponentPolygon2DListEXT; + +// XrSpatialComponentPlaneSemanticLabelListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentPlaneSemanticLabelListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t semanticLabelCount; + XrSpatialPlaneSemanticLabelEXT* semanticLabels; +} XrSpatialComponentPlaneSemanticLabelListEXT; + + + +// XR_EXT_stationary_reference_space is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_stationary_reference_space 1 +#define XR_EXT_stationary_reference_space_SPEC_VERSION 1 +#define XR_EXT_STATIONARY_REFERENCE_SPACE_EXTENSION_NAME "XR_EXT_stationary_reference_space" +typedef struct XrStationaryReferenceSpaceGenerationIdGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrStationaryReferenceSpaceGenerationIdGetInfoEXT; + +typedef struct XrStationaryReferenceSpaceGenerationIdResultEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuid generationId; +} XrStationaryReferenceSpaceGenerationIdResultEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrGetStationaryReferenceSpaceGenerationIdEXT)(XrSession session, const XrStationaryReferenceSpaceGenerationIdGetInfoEXT* getInfo, XrStationaryReferenceSpaceGenerationIdResultEXT* generationIdResult); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetStationaryReferenceSpaceGenerationIdEXT( + XrSession session, + const XrStationaryReferenceSpaceGenerationIdGetInfoEXT* getInfo, + XrStationaryReferenceSpaceGenerationIdResultEXT* generationIdResult); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_spatial_marker_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_marker_tracking 1 +#define XR_EXT_spatial_marker_tracking_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAME "XR_EXT_spatial_marker_tracking" + +typedef enum XrSpatialMarkerArucoDictEXT { + XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT = 1, + XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT = 2, + XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT = 3, + XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT = 4, + XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT = 5, + XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT = 6, + XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT = 7, + XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT = 8, + XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT = 9, + XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT = 10, + XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT = 11, + XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT = 12, + XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT = 13, + XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT = 14, + XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT = 15, + XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT = 16, + XR_SPATIAL_MARKER_ARUCO_DICT_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialMarkerArucoDictEXT; + +typedef enum XrSpatialMarkerAprilTagDictEXT { + XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT = 1, + XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT = 2, + XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT = 3, + XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT = 4, + XR_SPATIAL_MARKER_APRIL_TAG_DICT_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialMarkerAprilTagDictEXT; +typedef struct XrSpatialCapabilityConfigurationQrCodeEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationQrCodeEXT; + +typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationMicroQrCodeEXT; + +typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; + XrSpatialMarkerArucoDictEXT arUcoDict; +} XrSpatialCapabilityConfigurationArucoMarkerEXT; + +typedef struct XrSpatialCapabilityConfigurationAprilTagEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; + XrSpatialMarkerAprilTagDictEXT aprilDict; +} XrSpatialCapabilityConfigurationAprilTagEXT; + +// XrSpatialMarkerSizeEXT extends XrSpatialCapabilityConfigurationArucoMarkerEXT,XrSpatialCapabilityConfigurationAprilTagEXT,XrSpatialCapabilityConfigurationQrCodeEXT,XrSpatialCapabilityConfigurationMicroQrCodeEXT +typedef struct XrSpatialMarkerSizeEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float markerSideLength; +} XrSpatialMarkerSizeEXT; + +// XrSpatialMarkerStaticOptimizationEXT extends XrSpatialCapabilityConfigurationArucoMarkerEXT,XrSpatialCapabilityConfigurationAprilTagEXT,XrSpatialCapabilityConfigurationQrCodeEXT,XrSpatialCapabilityConfigurationMicroQrCodeEXT +typedef struct XrSpatialMarkerStaticOptimizationEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 optimizeForStaticMarker; +} XrSpatialMarkerStaticOptimizationEXT; + +typedef struct XrSpatialMarkerDataEXT { + XrSpatialCapabilityEXT capability; + uint32_t markerId; + XrSpatialBufferEXT data; +} XrSpatialMarkerDataEXT; + +// XrSpatialComponentMarkerListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentMarkerListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t markerCount; + XrSpatialMarkerDataEXT* markers; +} XrSpatialComponentMarkerListEXT; + + + +// XR_LOGITECH_mx_ink_stylus_interaction is a preprocessor guard. Do not pass it to API calls. +#define XR_LOGITECH_mx_ink_stylus_interaction 1 +#define XR_LOGITECH_mx_ink_stylus_interaction_SPEC_VERSION 1 +#define XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME "XR_LOGITECH_mx_ink_stylus_interaction" + + +// XR_EXT_spatial_anchor is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_anchor 1 +#define XR_EXT_spatial_anchor_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME "XR_EXT_spatial_anchor" +typedef struct XrSpatialCapabilityConfigurationAnchorEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationAnchorEXT; + +// XrSpatialComponentAnchorListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentAnchorListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t locationCount; + XrPosef* locations; +} XrSpatialComponentAnchorListEXT; + +typedef struct XrSpatialAnchorCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrPosef pose; +} XrSpatialAnchorCreateInfoEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorEXT)(XrSpatialContextEXT spatialContext, const XrSpatialAnchorCreateInfoEXT* createInfo, XrSpatialEntityIdEXT* anchorEntityId, XrSpatialEntityEXT* anchorEntity); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorEXT( + XrSpatialContextEXT spatialContext, + const XrSpatialAnchorCreateInfoEXT* createInfo, + XrSpatialEntityIdEXT* anchorEntityId, + XrSpatialEntityEXT* anchorEntity); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_spatial_persistence is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_persistence 1 +XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT) +#define XR_EXT_spatial_persistence_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME "XR_EXT_spatial_persistence" + +typedef enum XrSpatialPersistenceScopeEXT { + XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT = 1, + XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT = 1000781000, + XR_SPATIAL_PERSISTENCE_SCOPE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialPersistenceScopeEXT; + +typedef enum XrSpatialPersistenceContextResultEXT { + XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT = 0, + XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT = -1000781001, + XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT = -1000781002, + XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialPersistenceContextResultEXT; + +typedef enum XrSpatialPersistenceStateEXT { + XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT = 1, + XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT = 2, + XR_SPATIAL_PERSISTENCE_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrSpatialPersistenceStateEXT; +typedef struct XrSpatialPersistenceContextCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialPersistenceScopeEXT scope; +} XrSpatialPersistenceContextCreateInfoEXT; + +typedef struct XrCreateSpatialPersistenceContextCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSpatialPersistenceContextResultEXT createResult; + XrSpatialPersistenceContextEXT persistenceContext; +} XrCreateSpatialPersistenceContextCompletionEXT; + +// XrSpatialContextPersistenceConfigEXT extends XrSpatialContextCreateInfoEXT +typedef struct XrSpatialContextPersistenceConfigEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t persistenceContextCount; + const XrSpatialPersistenceContextEXT* persistenceContexts; +} XrSpatialContextPersistenceConfigEXT; + +// XrSpatialDiscoveryPersistenceUuidFilterEXT extends XrSpatialDiscoverySnapshotCreateInfoEXT,XrSpatialComponentDataQueryConditionEXT +typedef struct XrSpatialDiscoveryPersistenceUuidFilterEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t persistedUuidCount; + const XrUuid* persistedUuids; +} XrSpatialDiscoveryPersistenceUuidFilterEXT; + +typedef struct XrSpatialPersistenceDataEXT { + XrUuid persistUuid; + XrSpatialPersistenceStateEXT persistState; +} XrSpatialPersistenceDataEXT; + +// XrSpatialComponentPersistenceListEXT extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentPersistenceListEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t persistDataCount; + XrSpatialPersistenceDataEXT* persistData; +} XrSpatialComponentPersistenceListEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialPersistenceScopesEXT)(XrInstance instance, XrSystemId systemId, uint32_t persistenceScopeCapacityInput, uint32_t* persistenceScopeCountOutput, XrSpatialPersistenceScopeEXT* persistenceScopes); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialPersistenceContextAsyncEXT)(XrSession session, const XrSpatialPersistenceContextCreateInfoEXT* createInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialPersistenceContextCompleteEXT)(XrSession session, XrFutureEXT future, XrCreateSpatialPersistenceContextCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialPersistenceContextEXT)(XrSpatialPersistenceContextEXT persistenceContext); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialPersistenceScopesEXT( + XrInstance instance, + XrSystemId systemId, + uint32_t persistenceScopeCapacityInput, + uint32_t* persistenceScopeCountOutput, + XrSpatialPersistenceScopeEXT* persistenceScopes); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialPersistenceContextAsyncEXT( + XrSession session, + const XrSpatialPersistenceContextCreateInfoEXT* createInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialPersistenceContextCompleteEXT( + XrSession session, + XrFutureEXT future, + XrCreateSpatialPersistenceContextCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialPersistenceContextEXT( + XrSpatialPersistenceContextEXT persistenceContext); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_spatial_persistence_operations is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_spatial_persistence_operations 1 +#define XR_EXT_spatial_persistence_operations_SPEC_VERSION 1 +#define XR_EXT_SPATIAL_PERSISTENCE_OPERATIONS_EXTENSION_NAME "XR_EXT_spatial_persistence_operations" +typedef struct XrSpatialEntityPersistInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialContextEXT spatialContext; + XrSpatialEntityIdEXT spatialEntityId; +} XrSpatialEntityPersistInfoEXT; + +typedef struct XrPersistSpatialEntityCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSpatialPersistenceContextResultEXT persistResult; + XrUuid persistUuid; +} XrPersistSpatialEntityCompletionEXT; + +typedef struct XrSpatialEntityUnpersistInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuid persistUuid; +} XrSpatialEntityUnpersistInfoEXT; + +typedef struct XrUnpersistSpatialEntityCompletionEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrResult futureResult; + XrSpatialPersistenceContextResultEXT unpersistResult; +} XrUnpersistSpatialEntityCompletionEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrPersistSpatialEntityAsyncEXT)(XrSpatialPersistenceContextEXT persistenceContext, const XrSpatialEntityPersistInfoEXT* persistInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrPersistSpatialEntityCompleteEXT)(XrSpatialPersistenceContextEXT persistenceContext, XrFutureEXT future, XrPersistSpatialEntityCompletionEXT* completion); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistSpatialEntityAsyncEXT)(XrSpatialPersistenceContextEXT persistenceContext, const XrSpatialEntityUnpersistInfoEXT* unpersistInfo, XrFutureEXT* future); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistSpatialEntityCompleteEXT)(XrSpatialPersistenceContextEXT persistenceContext, XrFutureEXT future, XrUnpersistSpatialEntityCompletionEXT* completion); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrPersistSpatialEntityAsyncEXT( + XrSpatialPersistenceContextEXT persistenceContext, + const XrSpatialEntityPersistInfoEXT* persistInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrPersistSpatialEntityCompleteEXT( + XrSpatialPersistenceContextEXT persistenceContext, + XrFutureEXT future, + XrPersistSpatialEntityCompletionEXT* completion); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistSpatialEntityAsyncEXT( + XrSpatialPersistenceContextEXT persistenceContext, + const XrSpatialEntityUnpersistInfoEXT* unpersistInfo, + XrFutureEXT* future); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistSpatialEntityCompleteEXT( + XrSpatialPersistenceContextEXT persistenceContext, + XrFutureEXT future, + XrUnpersistSpatialEntityCompletionEXT* completion); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_spatial_object_tracking is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_spatial_object_tracking 1 +#define XR_ANDROID_spatial_object_tracking_SPEC_VERSION 2 +#define XR_ANDROID_SPATIAL_OBJECT_TRACKING_EXTENSION_NAME "XR_ANDROID_spatial_object_tracking" + +typedef enum XrSpatialObjectSemanticLabelANDROID { + XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_ANDROID = 0, + XR_SPATIAL_OBJECT_SEMANTIC_LABEL_KEYBOARD_ANDROID = 1, + XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MOUSE_ANDROID = 2, + XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAPTOP_BASE_ANDROID = 3, + XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF +} XrSpatialObjectSemanticLabelANDROID; +typedef struct XrSpatialCapabilityConfigurationObjectTrackingANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; + uint32_t activeSemanticLabelCount; + const XrSpatialObjectSemanticLabelANDROID* activeSemanticLabels; +} XrSpatialCapabilityConfigurationObjectTrackingANDROID; + +// XrSpatialComponentObjectSemanticLabelListANDROID extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentObjectSemanticLabelListANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t semanticLabelCount; + XrSpatialObjectSemanticLabelANDROID* semanticLabels; +} XrSpatialComponentObjectSemanticLabelListANDROID; + + + +// XR_ANDROID_spatial_discovery_raycast is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_spatial_discovery_raycast 1 +#define XR_ANDROID_spatial_discovery_raycast_SPEC_VERSION 1 +#define XR_ANDROID_SPATIAL_DISCOVERY_RAYCAST_EXTENSION_NAME "XR_ANDROID_spatial_discovery_raycast" +typedef struct XrSpatialRaycastResultDataANDROID { + XrPosef hitPose; + float distanceSquared; +} XrSpatialRaycastResultDataANDROID; + +typedef struct XrSpatialCapabilityConfigurationDepthRaycastANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialCapabilityEXT capability; + uint32_t enabledComponentCount; + const XrSpatialComponentTypeEXT* enabledComponents; +} XrSpatialCapabilityConfigurationDepthRaycastANDROID; + +// XrSpatialRaycastInfoANDROID extends XrSpatialDiscoverySnapshotCreateInfoEXT +typedef struct XrSpatialRaycastInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrTime time; + XrVector3f origin; + XrVector3f direction; + float maxDistance; +} XrSpatialRaycastInfoANDROID; + +// XrSpatialComponentRaycastResultListANDROID extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentRaycastResultListANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t raycastResultCount; + XrSpatialRaycastResultDataANDROID* raycastResults; +} XrSpatialComponentRaycastResultListANDROID; + +typedef struct XrSpatialRaycastSnapshotCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t componentTypeCount; + const XrSpatialComponentTypeEXT* componentTypes; + const XrSpatialRaycastInfoANDROID* raycastInfo; +} XrSpatialRaycastSnapshotCreateInfoANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialRaycastSnapshotANDROID)(XrSpatialContextEXT spatialContext, const XrSpatialRaycastSnapshotCreateInfoANDROID* createInfo, XrSpatialSnapshotEXT* snapshot); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialRaycastSnapshotANDROID( + XrSpatialContextEXT spatialContext, + const XrSpatialRaycastSnapshotCreateInfoANDROID* createInfo, + XrSpatialSnapshotEXT* snapshot); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_spatial_entity_bound_anchor is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_spatial_entity_bound_anchor 1 +#define XR_ANDROID_spatial_entity_bound_anchor_SPEC_VERSION 2 +#define XR_ANDROID_SPATIAL_ENTITY_BOUND_ANCHOR_EXTENSION_NAME "XR_ANDROID_spatial_entity_bound_anchor" +// XrSpatialAnchorParentANDROID extends XrSpatialAnchorCreateInfoEXT +typedef struct XrSpatialAnchorParentANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialEntityIdEXT parentId; +} XrSpatialAnchorParentANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpatialAnchorAttachableComponentsANDROID)(XrInstance instance, XrSystemId systemId, uint32_t attachableComponentCapacityInput, uint32_t* attachableComponentCountOutput, XrSpatialComponentTypeEXT* attachableComponents); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpatialAnchorAttachableComponentsANDROID( + XrInstance instance, + XrSystemId systemId, + uint32_t attachableComponentCapacityInput, + uint32_t* attachableComponentCountOutput, + XrSpatialComponentTypeEXT* attachableComponents); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_ANDROID_spatial_component_subsumed_by is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_spatial_component_subsumed_by 1 +#define XR_ANDROID_spatial_component_subsumed_by_SPEC_VERSION 1 +#define XR_ANDROID_SPATIAL_COMPONENT_SUBSUMED_BY_EXTENSION_NAME "XR_ANDROID_spatial_component_subsumed_by" +// XrSpatialDiscoveryUniqueEntitiesFilterANDROID extends XrSpatialDiscoverySnapshotCreateInfoEXT +typedef struct XrSpatialDiscoveryUniqueEntitiesFilterANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpatialDiscoveryUniqueEntitiesFilterANDROID; + +// XrSpatialComponentSubsumedByListANDROID extends XrSpatialComponentDataQueryResultEXT +typedef struct XrSpatialComponentSubsumedByListANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t subsumedUniqueIdCount; + XrSpatialEntityIdEXT* subsumedUniqueIds; +} XrSpatialComponentSubsumedByListANDROID; + + + +// XR_ANDROID_spatial_anchor_space is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_spatial_anchor_space 1 +#define XR_ANDROID_spatial_anchor_space_SPEC_VERSION 1 +#define XR_ANDROID_SPATIAL_ANCHOR_SPACE_EXTENSION_NAME "XR_ANDROID_spatial_anchor_space" +typedef struct XrSpatialAnchorSpaceFromIdCreateInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialEntityIdEXT anchorEntityId; +} XrSpatialAnchorSpaceFromIdCreateInfoANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorSpaceANDROID)(XrSession session, XrSpatialContextEXT spatialContext, const XrSpatialAnchorCreateInfoEXT* createInfo, XrSpatialEntityIdEXT* anchorEntityId, XrSpace* anchorSpace); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorSpaceFromIdANDROID)(XrSession session, XrSpatialContextEXT spatialContext, const XrSpatialAnchorSpaceFromIdCreateInfoANDROID* createInfo, XrSpace* anchorSpace); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorSpaceANDROID( + XrSession session, + XrSpatialContextEXT spatialContext, + const XrSpatialAnchorCreateInfoEXT* createInfo, + XrSpatialEntityIdEXT* anchorEntityId, + XrSpace* anchorSpace); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorSpaceFromIdANDROID( + XrSession session, + XrSpatialContextEXT spatialContext, + const XrSpatialAnchorSpaceFromIdCreateInfoANDROID* createInfo, + XrSpace* anchorSpace); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +// XR_EXT_interaction_profile_battery_state_display is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_interaction_profile_battery_state_display 1 +#define XR_EXT_interaction_profile_battery_state_display_SPEC_VERSION 1 +#define XR_EXT_INTERACTION_PROFILE_BATTERY_STATE_DISPLAY_EXTENSION_NAME "XR_EXT_interaction_profile_battery_state_display" +typedef XrFlags64 XrBatteryStateDisplayStateFlagsEXT; + +// Flag bits for XrBatteryStateDisplayStateFlagsEXT +static const XrBatteryStateDisplayStateFlagsEXT XR_BATTERY_STATE_DISPLAY_STATE_VALID_BIT_EXT = 0x00000001; +static const XrBatteryStateDisplayStateFlagsEXT XR_BATTERY_STATE_DISPLAY_STATE_CHARGING_BIT_EXT = 0x00000002; +static const XrBatteryStateDisplayStateFlagsEXT XR_BATTERY_STATE_DISPLAY_STATE_PLUGGED_IN_BIT_EXT = 0x00000004; +static const XrBatteryStateDisplayStateFlagsEXT XR_BATTERY_STATE_DISPLAY_STATE_NO_BATTERY_BIT_EXT = 0x00000008; + +// XrBatteryStateDisplayEXT extends XrInteractionProfileState +typedef struct XrBatteryStateDisplayEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBatteryStateDisplayStateFlagsEXT stateFlags; + float batteryLevel; +} XrBatteryStateDisplayEXT; + + + +// XR_EXT_loader_init_properties is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_loader_init_properties 1 +#define XR_EXT_loader_init_properties_SPEC_VERSION 1 +#define XR_EXT_LOADER_INIT_PROPERTIES_EXTENSION_NAME "XR_EXT_loader_init_properties" +typedef struct XrLoaderInitPropertyValueEXT { + const char* name; + const char* value; +} XrLoaderInitPropertyValueEXT; + +// XrLoaderInitInfoPropertiesEXT extends XrLoaderInitInfoBaseHeaderKHR +typedef struct XrLoaderInitInfoPropertiesEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t propertyValueCount; + const XrLoaderInitPropertyValueEXT* propertyValues; +} XrLoaderInitInfoPropertiesEXT; + + + +// XR_EXT_view_configuration_views_change is a preprocessor guard. Do not pass it to API calls. +#define XR_EXT_view_configuration_views_change 1 +#define XR_EXT_view_configuration_views_change_SPEC_VERSION 1 +#define XR_EXT_VIEW_CONFIGURATION_VIEWS_CHANGE_EXTENSION_NAME "XR_EXT_view_configuration_views_change" +typedef struct XrEventDataViewConfigurationViewsChangedEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSystemId systemId; + XrViewConfigurationType viewConfigurationType; +} XrEventDataViewConfigurationViewsChangedEXT; + + #ifdef __cplusplus } #endif diff --git a/src/video/khronos/openxr/openxr_loader_negotiation.h b/src/video/khronos/openxr/openxr_loader_negotiation.h index 2b58ecc82a..e79e74b0a9 100644 --- a/src/video/khronos/openxr/openxr_loader_negotiation.h +++ b/src/video/khronos/openxr/openxr_loader_negotiation.h @@ -2,7 +2,7 @@ #define OPENXR_LOADER_NEGOTIATION_H_ 1 /* -** Copyright 2017-2025 The Khronos Group Inc. +** Copyright 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ diff --git a/src/video/khronos/openxr/openxr_platform.h b/src/video/khronos/openxr/openxr_platform.h index 4e9048f775..9de27ad14a 100644 --- a/src/video/khronos/openxr/openxr_platform.h +++ b/src/video/khronos/openxr/openxr_platform.h @@ -2,7 +2,7 @@ #define OPENXR_PLATFORM_H_ 1 /* -** Copyright 2017-2025 The Khronos Group Inc. +** Copyright 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -86,6 +86,7 @@ typedef struct XrInstanceCreateInfoAndroidKHR { #define XR_KHR_vulkan_swapchain_format_list 1 #define XR_KHR_vulkan_swapchain_format_list_SPEC_VERSION 5 #define XR_KHR_VULKAN_SWAPCHAIN_FORMAT_LIST_EXTENSION_NAME "XR_KHR_vulkan_swapchain_format_list" +// XrVulkanSwapchainFormatListCreateInfoKHR extends XrSwapchainCreateInfo typedef struct XrVulkanSwapchainFormatListCreateInfoKHR { XrStructureType type; const void* XR_MAY_ALIAS next; @@ -99,7 +100,7 @@ typedef struct XrVulkanSwapchainFormatListCreateInfoKHR { // XR_KHR_opengl_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_opengl_enable 1 -#define XR_KHR_opengl_enable_SPEC_VERSION 10 +#define XR_KHR_opengl_enable_SPEC_VERSION 12 #define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable" #ifdef XR_USE_PLATFORM_WIN32 // XrGraphicsBindingOpenGLWin32KHR extends XrSessionCreateInfo @@ -176,7 +177,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLGraphicsRequirementsKHR( // XR_KHR_opengl_es_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_opengl_es_enable 1 -#define XR_KHR_opengl_es_enable_SPEC_VERSION 8 +#define XR_KHR_opengl_es_enable_SPEC_VERSION 10 #define XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME "XR_KHR_opengl_es_enable" #ifdef XR_USE_PLATFORM_ANDROID // XrGraphicsBindingOpenGLESAndroidKHR extends XrSessionCreateInfo @@ -218,7 +219,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLESGraphicsRequirementsKHR( // XR_KHR_vulkan_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_vulkan_enable 1 -#define XR_KHR_vulkan_enable_SPEC_VERSION 8 +#define XR_KHR_vulkan_enable_SPEC_VERSION 10 #define XR_KHR_VULKAN_ENABLE_EXTENSION_NAME "XR_KHR_vulkan_enable" // XrGraphicsBindingVulkanKHR extends XrSessionCreateInfo typedef struct XrGraphicsBindingVulkanKHR { @@ -283,7 +284,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirementsKHR( // XR_KHR_D3D11_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_D3D11_enable 1 -#define XR_KHR_D3D11_enable_SPEC_VERSION 9 +#define XR_KHR_D3D11_enable_SPEC_VERSION 11 #define XR_KHR_D3D11_ENABLE_EXTENSION_NAME "XR_KHR_D3D11_enable" // XrGraphicsBindingD3D11KHR extends XrSessionCreateInfo typedef struct XrGraphicsBindingD3D11KHR { @@ -321,7 +322,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D11GraphicsRequirementsKHR( // XR_KHR_D3D12_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_D3D12_enable 1 -#define XR_KHR_D3D12_enable_SPEC_VERSION 9 +#define XR_KHR_D3D12_enable_SPEC_VERSION 11 #define XR_KHR_D3D12_ENABLE_EXTENSION_NAME "XR_KHR_D3D12_enable" // XrGraphicsBindingD3D12KHR extends XrSessionCreateInfo typedef struct XrGraphicsBindingD3D12KHR { @@ -360,7 +361,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR( // XR_KHR_metal_enable is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_metal_enable 1 -#define XR_KHR_metal_enable_SPEC_VERSION 1 +#define XR_KHR_metal_enable_SPEC_VERSION 3 #define XR_KHR_METAL_ENABLE_EXTENSION_NAME "XR_KHR_metal_enable" // XrGraphicsBindingMetalKHR extends XrSessionCreateInfo typedef struct XrGraphicsBindingMetalKHR { @@ -370,9 +371,9 @@ typedef struct XrGraphicsBindingMetalKHR { } XrGraphicsBindingMetalKHR; typedef struct XrSwapchainImageMetalKHR { - XrStructureType type; - const void* XR_MAY_ALIAS next; - void* XR_MAY_ALIAS texture; + XrStructureType type; + void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS texture; } XrSwapchainImageMetalKHR; typedef struct XrGraphicsRequirementsMetalKHR { @@ -460,7 +461,7 @@ typedef struct XrLoaderInitInfoAndroidKHR { // XR_KHR_vulkan_enable2 is a preprocessor guard. Do not pass it to API calls. #define XR_KHR_vulkan_enable2 1 -#define XR_KHR_vulkan_enable2_SPEC_VERSION 2 +#define XR_KHR_vulkan_enable2_SPEC_VERSION 4 #define XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME "XR_KHR_vulkan_enable2" typedef XrFlags64 XrVulkanInstanceCreateFlagsKHR; @@ -769,6 +770,48 @@ typedef struct XrVulkanSwapchainCreateInfoMETA { #endif /* XR_USE_GRAPHICS_API_VULKAN */ +#ifdef XR_USE_PLATFORM_ANDROID + +// XR_ANDROID_anchor_sharing_export is a preprocessor guard. Do not pass it to API calls. +#define XR_ANDROID_anchor_sharing_export 1 +#define XR_ANDROID_anchor_sharing_export_SPEC_VERSION 1 +#define XR_ANDROID_ANCHOR_SHARING_EXPORT_EXTENSION_NAME "XR_ANDROID_anchor_sharing_export" +typedef struct XrAnchorSharingInfoANDROID { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace anchor; +} XrAnchorSharingInfoANDROID; + +typedef struct XrAnchorSharingTokenANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + struct AIBinder* token; +} XrAnchorSharingTokenANDROID; + +// XrSystemAnchorSharingExportPropertiesANDROID extends XrSystemProperties +typedef struct XrSystemAnchorSharingExportPropertiesANDROID { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsAnchorSharingExport; +} XrSystemAnchorSharingExportPropertiesANDROID; + +typedef XrResult (XRAPI_PTR *PFN_xrShareAnchorANDROID)(XrSession session, const XrAnchorSharingInfoANDROID* sharingInfo, XrAnchorSharingTokenANDROID* anchorToken); +typedef XrResult (XRAPI_PTR *PFN_xrUnshareAnchorANDROID)(XrSession session, XrSpace anchor); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrShareAnchorANDROID( + XrSession session, + const XrAnchorSharingInfoANDROID* sharingInfo, + XrAnchorSharingTokenANDROID* anchorToken); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnshareAnchorANDROID( + XrSession session, + XrSpace anchor); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_ANDROID */ + #ifdef __cplusplus } #endif diff --git a/src/video/khronos/openxr/openxr_platform_defines.h b/src/video/khronos/openxr/openxr_platform_defines.h index a8f7e5e06e..79c5b2cfc2 100644 --- a/src/video/khronos/openxr/openxr_platform_defines.h +++ b/src/video/khronos/openxr/openxr_platform_defines.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2017-2025 The Khronos Group Inc. +** Copyright (c) 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ diff --git a/src/video/khronos/openxr/openxr_reflection.h b/src/video/khronos/openxr/openxr_reflection.h index 8b49a58cdd..f8752f063c 100644 --- a/src/video/khronos/openxr/openxr_reflection.h +++ b/src/video/khronos/openxr/openxr_reflection.h @@ -2,7 +2,7 @@ #define OPENXR_REFLECTION_H_ 1 /* -** Copyright (c) 2017-2025 The Khronos Group Inc. +** Copyright (c) 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -141,12 +141,41 @@ XR_ENUM_STR(XrResult); _(XR_ERROR_SPACE_NETWORK_TIMEOUT_FB, -1000169002) \ _(XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB, -1000169003) \ _(XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB, -1000169004) \ + _(XR_ERROR_SPACE_INSUFFICIENT_RESOURCES_META, -1000259000) \ + _(XR_ERROR_SPACE_STORAGE_AT_CAPACITY_META, -1000259001) \ + _(XR_ERROR_SPACE_INSUFFICIENT_VIEW_META, -1000259002) \ + _(XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META, -1000259003) \ + _(XR_ERROR_SPACE_RATE_LIMITED_META, -1000259004) \ + _(XR_ERROR_SPACE_TOO_DARK_META, -1000259005) \ + _(XR_ERROR_SPACE_TOO_BRIGHT_META, -1000259006) \ _(XR_ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META, -1000266000) \ _(XR_ENVIRONMENT_DEPTH_NOT_AVAILABLE_META, 1000291000) \ + _(XR_ERROR_RENDER_MODEL_ID_INVALID_EXT, -1000300000) \ + _(XR_ERROR_RENDER_MODEL_ASSET_UNAVAILABLE_EXT, -1000300001) \ + _(XR_ERROR_RENDER_MODEL_GLTF_EXTENSION_REQUIRED_EXT, -1000300002) \ + _(XR_ERROR_NOT_INTERACTION_RENDER_MODEL_EXT, -1000301000) \ _(XR_ERROR_HINT_ALREADY_SET_QCOM, -1000306000) \ _(XR_ERROR_NOT_AN_ANCHOR_HTC, -1000319000) \ + _(XR_ERROR_SPATIAL_ENTITY_ID_INVALID_BD, -1000389000) \ + _(XR_ERROR_SPATIAL_SENSING_SERVICE_UNAVAILABLE_BD, -1000389001) \ + _(XR_ERROR_ANCHOR_NOT_SUPPORTED_FOR_ENTITY_BD, -1000389002) \ + _(XR_ERROR_SPATIAL_ANCHOR_NOT_FOUND_BD, -1000390000) \ + _(XR_ERROR_SPATIAL_ANCHOR_SHARING_NETWORK_TIMEOUT_BD, -1000391000) \ + _(XR_ERROR_SPATIAL_ANCHOR_SHARING_AUTHENTICATION_FAILURE_BD, -1000391001) \ + _(XR_ERROR_SPATIAL_ANCHOR_SHARING_NETWORK_FAILURE_BD, -1000391002) \ + _(XR_ERROR_SPATIAL_ANCHOR_SHARING_LOCALIZATION_FAIL_BD, -1000391003) \ + _(XR_ERROR_SPATIAL_ANCHOR_SHARING_MAP_INSUFFICIENT_BD, -1000391004) \ + _(XR_ERROR_SCENE_CAPTURE_FAILURE_BD, -1000392000) \ _(XR_ERROR_SPACE_NOT_LOCATABLE_EXT, -1000429000) \ _(XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT, -1000429001) \ + _(XR_ERROR_MISMATCHING_TRACKABLE_TYPE_ANDROID, -1000455000) \ + _(XR_ERROR_TRACKABLE_TYPE_NOT_SUPPORTED_ANDROID, -1000455001) \ + _(XR_ERROR_ANCHOR_ID_NOT_FOUND_ANDROID, -1000457000) \ + _(XR_ERROR_ANCHOR_ALREADY_PERSISTED_ANDROID, -1000457001) \ + _(XR_ERROR_ANCHOR_NOT_TRACKING_ANDROID, -1000457002) \ + _(XR_ERROR_PERSISTED_DATA_NOT_READY_ANDROID, -1000457003) \ + _(XR_ERROR_SERVICE_NOT_READY_ANDROID, -1000458000) \ + _(XR_ERROR_MESH_DATA_LIMIT_EXCEEDED_ANDROID, -1000462000) \ _(XR_ERROR_FUTURE_PENDING_EXT, -1000469001) \ _(XR_ERROR_FUTURE_INVALID_EXT, -1000469002) \ _(XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML, -1000473000) \ @@ -154,11 +183,24 @@ XR_ENUM_STR(XrResult); _(XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML, -1000474000) \ _(XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML, -1000474001) \ _(XR_ERROR_FACIAL_EXPRESSION_PERMISSION_DENIED_ML, 1000482000) \ + _(XR_BOUNDARY_VISIBILITY_SUPPRESSION_NOT_ALLOWED_META, 1000528000) \ _(XR_ERROR_COLOCATION_DISCOVERY_NETWORK_FAILED_META, -1000571001) \ _(XR_ERROR_COLOCATION_DISCOVERY_NO_DISCOVERY_METHOD_META, -1000571002) \ _(XR_COLOCATION_DISCOVERY_ALREADY_ADVERTISING_META, 1000571003) \ _(XR_COLOCATION_DISCOVERY_ALREADY_DISCOVERING_META, 1000571004) \ _(XR_ERROR_SPACE_GROUP_NOT_FOUND_META, -1000572002) \ + _(XR_ERROR_ANCHOR_NOT_OWNED_BY_CALLER_ANDROID, -1000701000) \ + _(XR_ERROR_IMAGE_FORMAT_UNSUPPORTED_ANDROID, -1000709000) \ + _(XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT, -1000740001) \ + _(XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT, -1000740002) \ + _(XR_ERROR_SPATIAL_BUFFER_ID_INVALID_EXT, -1000740003) \ + _(XR_ERROR_SPATIAL_COMPONENT_UNSUPPORTED_FOR_CAPABILITY_EXT, -1000740004) \ + _(XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT, -1000740005) \ + _(XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT, -1000740006) \ + _(XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT, -1000763001) \ + _(XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_INCOMPATIBLE_EXT, -1000781001) \ + _(XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID, -1000790001) \ + _(XR_ERROR_SPATIAL_ANCHOR_ENTITY_ID_INVALID_ANDROID, -1000795001) \ _(XR_RESULT_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrStructureType(_) \ @@ -488,8 +530,21 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB, 1000238001) \ _(XR_TYPE_SPACE_USER_CREATE_INFO_FB, 1000241001) \ _(XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META, 1000245000) \ + _(XR_TYPE_SYSTEM_SPACE_DISCOVERY_PROPERTIES_META, 1000247000) \ + _(XR_TYPE_SPACE_DISCOVERY_INFO_META, 1000247001) \ + _(XR_TYPE_SPACE_FILTER_UUID_META, 1000247003) \ + _(XR_TYPE_SPACE_FILTER_COMPONENT_META, 1000247004) \ + _(XR_TYPE_SPACE_DISCOVERY_RESULT_META, 1000247005) \ + _(XR_TYPE_SPACE_DISCOVERY_RESULTS_META, 1000247006) \ + _(XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META, 1000247007) \ + _(XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META, 1000247008) \ _(XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_META, 1000254000) \ _(XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_GET_INFO_META, 1000254001) \ + _(XR_TYPE_SYSTEM_SPACE_PERSISTENCE_PROPERTIES_META, 1000259000) \ + _(XR_TYPE_SPACES_SAVE_INFO_META, 1000259001) \ + _(XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META, 1000259002) \ + _(XR_TYPE_SPACES_ERASE_INFO_META, 1000259003) \ + _(XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META, 1000259004) \ _(XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META, 1000266000) \ _(XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META, 1000266001) \ _(XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META, 1000266002) \ @@ -497,7 +552,13 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META, 1000266101) \ _(XR_TYPE_SPACE_TRIANGLE_MESH_GET_INFO_META, 1000269001) \ _(XR_TYPE_SPACE_TRIANGLE_MESH_META, 1000269002) \ + _(XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FULL_BODY_META, 1000274000) \ _(XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META, 1000282000) \ + _(XR_TYPE_BODY_TRACKING_CALIBRATION_INFO_META, 1000283002) \ + _(XR_TYPE_BODY_TRACKING_CALIBRATION_STATUS_META, 1000283003) \ + _(XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_CALIBRATION_META, 1000283004) \ + _(XR_TYPE_BODY_TRACKING_FIDELITY_STATUS_META, 1000284000) \ + _(XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FIDELITY_META, 1000284001) \ _(XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES2_FB, 1000287013) \ _(XR_TYPE_FACE_TRACKER_CREATE_INFO2_FB, 1000287014) \ _(XR_TYPE_FACE_EXPRESSION_INFO2_FB, 1000287015) \ @@ -513,6 +574,22 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_META, 1000291005) \ _(XR_TYPE_ENVIRONMENT_DEPTH_HAND_REMOVAL_SET_INFO_META, 1000291006) \ _(XR_TYPE_SYSTEM_ENVIRONMENT_DEPTH_PROPERTIES_META, 1000291007) \ + _(XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_TIMESTAMP_META, 1000291008) \ + _(XR_TYPE_RENDER_MODEL_CREATE_INFO_EXT, 1000300000) \ + _(XR_TYPE_RENDER_MODEL_PROPERTIES_GET_INFO_EXT, 1000300001) \ + _(XR_TYPE_RENDER_MODEL_PROPERTIES_EXT, 1000300002) \ + _(XR_TYPE_RENDER_MODEL_SPACE_CREATE_INFO_EXT, 1000300003) \ + _(XR_TYPE_RENDER_MODEL_STATE_GET_INFO_EXT, 1000300004) \ + _(XR_TYPE_RENDER_MODEL_STATE_EXT, 1000300005) \ + _(XR_TYPE_RENDER_MODEL_ASSET_CREATE_INFO_EXT, 1000300006) \ + _(XR_TYPE_RENDER_MODEL_ASSET_DATA_GET_INFO_EXT, 1000300007) \ + _(XR_TYPE_RENDER_MODEL_ASSET_DATA_EXT, 1000300008) \ + _(XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_GET_INFO_EXT, 1000300009) \ + _(XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_EXT, 1000300010) \ + _(XR_TYPE_INTERACTION_RENDER_MODEL_IDS_ENUMERATE_INFO_EXT, 1000301000) \ + _(XR_TYPE_INTERACTION_RENDER_MODEL_SUBACTION_PATH_INFO_EXT, 1000301001) \ + _(XR_TYPE_EVENT_DATA_INTERACTION_RENDER_MODELS_CHANGED_EXT, 1000301002) \ + _(XR_TYPE_INTERACTION_RENDER_MODEL_TOP_LEVEL_USER_PATH_GET_INFO_EXT, 1000301003) \ _(XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC, 1000317001) \ _(XR_TYPE_PASSTHROUGH_COLOR_HTC, 1000317002) \ _(XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC, 1000317003) \ @@ -534,6 +611,63 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_BODY_JOINTS_LOCATE_INFO_BD, 1000385002) \ _(XR_TYPE_BODY_JOINT_LOCATIONS_BD, 1000385003) \ _(XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_BD, 1000385004) \ + _(XR_TYPE_SYSTEM_FACIAL_SIMULATION_PROPERTIES_BD, 1000386001) \ + _(XR_TYPE_FACE_TRACKER_CREATE_INFO_BD, 1000386002) \ + _(XR_TYPE_FACIAL_SIMULATION_DATA_GET_INFO_BD, 1000386003) \ + _(XR_TYPE_FACIAL_SIMULATION_DATA_BD, 1000386004) \ + _(XR_TYPE_LIP_EXPRESSION_DATA_BD, 1000386005) \ + _(XR_TYPE_SYSTEM_SPATIAL_SENSING_PROPERTIES_BD, 1000389000) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_GET_INFO_BD, 1000389001) \ + _(XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO_BD, 1000389002) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_LOCATION_BD, 1000389003) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_SEMANTIC_BD, 1000389004) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_2D_BD, 1000389005) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_POLYGON_BD, 1000389006) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_3D_BD, 1000389007) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_TRIANGLE_MESH_BD, 1000389008) \ + _(XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_BD, 1000389009) \ + _(XR_TYPE_SENSE_DATA_PROVIDER_START_INFO_BD, 1000389010) \ + _(XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED_BD, 1000389011) \ + _(XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED_BD, 1000389012) \ + _(XR_TYPE_SENSE_DATA_QUERY_INFO_BD, 1000389013) \ + _(XR_TYPE_SENSE_DATA_QUERY_COMPLETION_BD, 1000389014) \ + _(XR_TYPE_SENSE_DATA_FILTER_UUID_BD, 1000389015) \ + _(XR_TYPE_SENSE_DATA_FILTER_SEMANTIC_BD, 1000389016) \ + _(XR_TYPE_QUERIED_SENSE_DATA_GET_INFO_BD, 1000389017) \ + _(XR_TYPE_QUERIED_SENSE_DATA_BD, 1000389018) \ + _(XR_TYPE_SPATIAL_ENTITY_STATE_BD, 1000389019) \ + _(XR_TYPE_SPATIAL_ENTITY_ANCHOR_CREATE_INFO_BD, 1000389020) \ + _(XR_TYPE_ANCHOR_SPACE_CREATE_INFO_BD, 1000389021) \ + _(XR_TYPE_SYSTEM_SPATIAL_ANCHOR_PROPERTIES_BD, 1000390000) \ + _(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_BD, 1000390001) \ + _(XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION_BD, 1000390002) \ + _(XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO_BD, 1000390003) \ + _(XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO_BD, 1000390004) \ + _(XR_TYPE_SYSTEM_SPATIAL_ANCHOR_SHARING_PROPERTIES_BD, 1000391000) \ + _(XR_TYPE_SPATIAL_ANCHOR_SHARE_INFO_BD, 1000391001) \ + _(XR_TYPE_SHARED_SPATIAL_ANCHOR_DOWNLOAD_INFO_BD, 1000391002) \ + _(XR_TYPE_SYSTEM_SPATIAL_SCENE_PROPERTIES_BD, 1000392000) \ + _(XR_TYPE_SCENE_CAPTURE_INFO_BD, 1000392001) \ + _(XR_TYPE_SYSTEM_SPATIAL_MESH_PROPERTIES_BD, 1000393000) \ + _(XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_MESH_BD, 1000393001) \ + _(XR_TYPE_FUTURE_POLL_RESULT_PROGRESS_BD, 1000394001) \ + _(XR_TYPE_SYSTEM_SPATIAL_PLANE_PROPERTIES_BD, 1000396000) \ + _(XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_PLANE_ORIENTATION_BD, 1000396001) \ + _(XR_TYPE_SENSE_DATA_FILTER_PLANE_ORIENTATION_BD, 1000396002) \ + _(XR_TYPE_SPATIAL_AUDIO_RENDERER_CREATE_INFO_BD, 1000409000) \ + _(XR_TYPE_AUDIO_BUFFER_BD, 1000409001) \ + _(XR_TYPE_SOUND_OBJECT_DIRECTIVITY_CARDIOID_BD, 1000409003) \ + _(XR_TYPE_SOUND_OBJECT_SHAPE_SPHERE_BD, 1000409004) \ + _(XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_BD, 1000409005) \ + _(XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_CURVE_BD, 1000409006) \ + _(XR_TYPE_SOUND_OBJECT_CONFIG_BD, 1000409007) \ + _(XR_TYPE_SOUND_FIELD_CONFIG_BD, 1000409008) \ + _(XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_SURROUND_BD, 1000409009) \ + _(XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_AMBIX_BD, 1000409010) \ + _(XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_FUMA_BD, 1000409011) \ + _(XR_TYPE_SOUND_TRIANGLE_MESH_BD, 1000409012) \ + _(XR_TYPE_SOUND_OBSTACLE_CONFIG_BD, 1000409013) \ + _(XR_TYPE_SOUND_OBSTACLE_MATERIAL_CONFIG_BD, 1000409014) \ _(XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT, 1000428000) \ _(XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT, 1000428001) \ _(XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT, 1000429001) \ @@ -543,6 +677,36 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_PLANE_DETECTOR_LOCATION_EXT, 1000429005) \ _(XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT, 1000429006) \ _(XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT, 1000429007) \ + _(XR_TYPE_TRACKABLE_GET_INFO_ANDROID, 1000455000) \ + _(XR_TYPE_ANCHOR_SPACE_CREATE_INFO_ANDROID, 1000455001) \ + _(XR_TYPE_TRACKABLE_PLANE_ANDROID, 1000455003) \ + _(XR_TYPE_TRACKABLE_TRACKER_CREATE_INFO_ANDROID, 1000455004) \ + _(XR_TYPE_SYSTEM_TRACKABLES_PROPERTIES_ANDROID, 1000455005) \ + _(XR_TYPE_EYES_ANDROID, 1000456000) \ + _(XR_TYPE_EYE_TRACKER_CREATE_INFO_ANDROID, 1000456001) \ + _(XR_TYPE_EYES_GET_INFO_ANDROID, 1000456002) \ + _(XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_ANDROID, 1000456004) \ + _(XR_TYPE_PERSISTED_ANCHOR_SPACE_CREATE_INFO_ANDROID, 1000457001) \ + _(XR_TYPE_PERSISTED_ANCHOR_SPACE_INFO_ANDROID, 1000457002) \ + _(XR_TYPE_DEVICE_ANCHOR_PERSISTENCE_CREATE_INFO_ANDROID, 1000457003) \ + _(XR_TYPE_SYSTEM_DEVICE_ANCHOR_PERSISTENCE_PROPERTIES_ANDROID, 1000457004) \ + _(XR_TYPE_FACE_TRACKER_CREATE_INFO_ANDROID, 1000458000) \ + _(XR_TYPE_FACE_STATE_GET_INFO_ANDROID, 1000458001) \ + _(XR_TYPE_FACE_STATE_ANDROID, 1000458002) \ + _(XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_ANDROID, 1000458003) \ + _(XR_TYPE_PASSTHROUGH_CAMERA_STATE_GET_INFO_ANDROID, 1000460000) \ + _(XR_TYPE_SYSTEM_PASSTHROUGH_CAMERA_STATE_PROPERTIES_ANDROID, 1000460001) \ + _(XR_TYPE_EVENT_DATA_RECOMMENDED_RESOLUTION_CHANGED_ANDROID, 1000461000) \ + _(XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_ANDROID, 1000462000) \ + _(XR_TYPE_PASSTHROUGH_LAYER_MESH_ANDROID, 1000462001) \ + _(XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_ANDROID, 1000462002) \ + _(XR_TYPE_SYSTEM_PASSTHROUGH_LAYER_PROPERTIES_ANDROID, 1000462003) \ + _(XR_TYPE_RAYCAST_INFO_ANDROID, 1000463000) \ + _(XR_TYPE_RAYCAST_HIT_RESULTS_ANDROID, 1000463001) \ + _(XR_TYPE_PERFORMANCE_METRICS_STATE_ANDROID, 1000465000) \ + _(XR_TYPE_PERFORMANCE_METRICS_COUNTER_ANDROID, 1000465001) \ + _(XR_TYPE_TRACKABLE_OBJECT_ANDROID, 1000466000) \ + _(XR_TYPE_TRACKABLE_OBJECT_CONFIGURATION_ANDROID, 1000466001) \ _(XR_TYPE_FUTURE_CANCEL_INFO_EXT, 1000469000) \ _(XR_TYPE_FUTURE_POLL_INFO_EXT, 1000469001) \ _(XR_TYPE_FUTURE_COMPLETION_EXT, 1000469002) \ @@ -566,6 +730,16 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_FACIAL_EXPRESSION_CLIENT_CREATE_INFO_ML, 1000482005) \ _(XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_GET_INFO_ML, 1000482006) \ _(XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_ML, 1000482007) \ + _(XR_TYPE_SYSTEM_BOUNDARY_VISIBILITY_PROPERTIES_META, 1000528000) \ + _(XR_TYPE_EVENT_DATA_BOUNDARY_VISIBILITY_CHANGED_META, 1000528001) \ + _(XR_TYPE_SYSTEM_SIMULTANEOUS_HANDS_AND_CONTROLLERS_PROPERTIES_META, 1000532001) \ + _(XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_RESUME_INFO_META, 1000532002) \ + _(XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_PAUSE_INFO_META, 1000532003) \ + _(XR_TYPE_FACE_TRACKING_VISEMES_META, 1000541000) \ + _(XR_TYPE_SYSTEM_FACE_TRACKING_VISEMES_PROPERTIES_META, 1000541001) \ + _(XR_TYPE_ROOM_MESH_FACE_INDICES_META, 1000553000) \ + _(XR_TYPE_SPACE_ROOM_MESH_GET_INFO_META, 1000553001) \ + _(XR_TYPE_ROOM_MESH_META, 1000553002) \ _(XR_TYPE_COLOCATION_DISCOVERY_START_INFO_META, 1000571010) \ _(XR_TYPE_COLOCATION_DISCOVERY_STOP_INFO_META, 1000571011) \ _(XR_TYPE_COLOCATION_ADVERTISEMENT_START_INFO_META, 1000571012) \ @@ -581,6 +755,99 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META, 1000572000) \ _(XR_TYPE_SPACE_GROUP_UUID_FILTER_INFO_META, 1000572001) \ _(XR_TYPE_SYSTEM_SPATIAL_ENTITY_GROUP_SHARING_PROPERTIES_META, 1000572100) \ + _(XR_TYPE_SYSTEM_ENVIRONMENT_RAYCAST_PROPERTIES_META, 1000592000) \ + _(XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_INFO_META, 1000592001) \ + _(XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_COMPLETION_META, 1000592002) \ + _(XR_TYPE_ENVIRONMENT_RAYCAST_HIT_GET_INFO_META, 1000592003) \ + _(XR_TYPE_ENVIRONMENT_RAYCAST_HIT_META, 1000592004) \ + _(XR_TYPE_ENVIRONMENT_RAYCAST_FILTER_DISTANCE_META, 1000592005) \ + _(XR_TYPE_TILE_PROPERTIES_META, 1000609000) \ + _(XR_TYPE_TILE_PROPERTIES_HINT_META, 1000609001) \ + _(XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID, 1000700000) \ + _(XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID, 1000700001) \ + _(XR_TYPE_LIGHT_ESTIMATE_ANDROID, 1000700002) \ + _(XR_TYPE_DIRECTIONAL_LIGHT_ANDROID, 1000700003) \ + _(XR_TYPE_SPHERICAL_HARMONICS_ANDROID, 1000700004) \ + _(XR_TYPE_AMBIENT_LIGHT_ANDROID, 1000700005) \ + _(XR_TYPE_SYSTEM_LIGHT_ESTIMATION_PROPERTIES_ANDROID, 1000700006) \ + _(XR_TYPE_ANCHOR_SHARING_INFO_ANDROID, 1000701000) \ + _(XR_TYPE_ANCHOR_SHARING_TOKEN_ANDROID, 1000701001) \ + _(XR_TYPE_SYSTEM_ANCHOR_SHARING_EXPORT_PROPERTIES_ANDROID, 1000701002) \ + _(XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_ANDROID, 1000707000) \ + _(XR_TYPE_TRACKABLE_MARKER_CONFIGURATION_ANDROID, 1000707001) \ + _(XR_TYPE_TRACKABLE_MARKER_ANDROID, 1000707002) \ + _(XR_TYPE_SYSTEM_QR_CODE_TRACKING_PROPERTIES_ANDROID, 1000708000) \ + _(XR_TYPE_TRACKABLE_QR_CODE_CONFIGURATION_ANDROID, 1000708001) \ + _(XR_TYPE_TRACKABLE_QR_CODE_ANDROID, 1000708002) \ + _(XR_TYPE_SYSTEM_IMAGE_TRACKING_PROPERTIES_ANDROID, 1000709000) \ + _(XR_TYPE_TRACKABLE_IMAGE_DATABASE_ENTRY_ANDROID, 1000709001) \ + _(XR_TYPE_TRACKABLE_IMAGE_DATABASE_CREATE_INFO_ANDROID, 1000709002) \ + _(XR_TYPE_CREATE_TRACKABLE_IMAGE_DATABASE_COMPLETION_ANDROID, 1000709003) \ + _(XR_TYPE_TRACKABLE_IMAGE_CONFIGURATION_ANDROID, 1000709004) \ + _(XR_TYPE_TRACKABLE_IMAGE_ANDROID, 1000709005) \ + _(XR_TYPE_EVENT_DATA_IMAGE_TRACKING_LOST_ANDROID, 1000709006) \ + _(XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID, 1000718000) \ + _(XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID, 1000718001) \ + _(XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID, 1000718002) \ + _(XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID, 1000718003) \ + _(XR_TYPE_SCENE_SUBMESH_STATE_ANDROID, 1000718004) \ + _(XR_TYPE_SCENE_SUBMESH_DATA_ANDROID, 1000718005) \ + _(XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT, 1000740000) \ + _(XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT, 1000740001) \ + _(XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT, 1000740002) \ + _(XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT, 1000740003) \ + _(XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT, 1000740004) \ + _(XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT, 1000740005) \ + _(XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT, 1000740006) \ + _(XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT, 1000740007) \ + _(XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT, 1000740008) \ + _(XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT, 1000740009) \ + _(XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT, 1000740010) \ + _(XR_TYPE_SPATIAL_COMPONENT_PARENT_LIST_EXT, 1000740011) \ + _(XR_TYPE_SPATIAL_COMPONENT_MESH_3D_LIST_EXT, 1000740012) \ + _(XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT, 1000740013) \ + _(XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT, 1000740014) \ + _(XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT, 1000740015) \ + _(XR_TYPE_SPATIAL_FILTER_TRACKING_STATE_EXT, 1000740016) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT, 1000741000) \ + _(XR_TYPE_SPATIAL_COMPONENT_PLANE_ALIGNMENT_LIST_EXT, 1000741001) \ + _(XR_TYPE_SPATIAL_COMPONENT_MESH_2D_LIST_EXT, 1000741002) \ + _(XR_TYPE_SPATIAL_COMPONENT_POLYGON_2D_LIST_EXT, 1000741003) \ + _(XR_TYPE_SPATIAL_COMPONENT_PLANE_SEMANTIC_LABEL_LIST_EXT, 1000741004) \ + _(XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_GET_INFO_EXT, 1000742001) \ + _(XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_RESULT_EXT, 1000742002) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT, 1000743000) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT, 1000743001) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT, 1000743002) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT, 1000743003) \ + _(XR_TYPE_SPATIAL_MARKER_SIZE_EXT, 1000743004) \ + _(XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT, 1000743005) \ + _(XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT, 1000743006) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT, 1000762000) \ + _(XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT, 1000762001) \ + _(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT, 1000762002) \ + _(XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT, 1000763000) \ + _(XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT, 1000763001) \ + _(XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT, 1000763002) \ + _(XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT, 1000763003) \ + _(XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT, 1000763004) \ + _(XR_TYPE_SPATIAL_ENTITY_PERSIST_INFO_EXT, 1000781000) \ + _(XR_TYPE_PERSIST_SPATIAL_ENTITY_COMPLETION_EXT, 1000781001) \ + _(XR_TYPE_SPATIAL_ENTITY_UNPERSIST_INFO_EXT, 1000781002) \ + _(XR_TYPE_UNPERSIST_SPATIAL_ENTITY_COMPLETION_EXT, 1000781003) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID, 1000785000) \ + _(XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID, 1000785001) \ + _(XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID, 1000786000) \ + _(XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID, 1000786001) \ + _(XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID, 1000786002) \ + _(XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID, 1000786003) \ + _(XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID, 1000790000) \ + _(XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID, 1000791001) \ + _(XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID, 1000791002) \ + _(XR_TYPE_SPATIAL_ANCHOR_SPACE_FROM_ID_CREATE_INFO_ANDROID, 1000795000) \ + _(XR_TYPE_BATTERY_STATE_DISPLAY_EXT, 1000836000) \ + _(XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT, 1000838000) \ + _(XR_TYPE_EVENT_DATA_VIEW_CONFIGURATION_VIEWS_CHANGED_EXT, 1000839000) \ _(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrFormFactor(_) \ @@ -609,6 +876,8 @@ XR_ENUM_STR(XrResult); _(XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT, 1000038000) \ _(XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO, 1000121000) \ _(XR_REFERENCE_SPACE_TYPE_LOCALIZATION_MAP_ML, 1000139000) \ + _(XR_REFERENCE_SPACE_TYPE_UNBOUNDED_ANDROID, 1000467000) \ + _(XR_REFERENCE_SPACE_TYPE_STATIONARY_EXT, 1000742000) \ _(XR_REFERENCE_SPACE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrActionType(_) \ @@ -670,12 +939,37 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_FACE_TRACKER2_FB, 1000287012) \ _(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META, 1000291000) \ _(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META, 1000291001) \ + _(XR_OBJECT_TYPE_RENDER_MODEL_EXT, 1000300000) \ + _(XR_OBJECT_TYPE_RENDER_MODEL_ASSET_EXT, 1000300001) \ _(XR_OBJECT_TYPE_PASSTHROUGH_HTC, 1000317000) \ _(XR_OBJECT_TYPE_BODY_TRACKER_HTC, 1000320000) \ _(XR_OBJECT_TYPE_BODY_TRACKER_BD, 1000385000) \ + _(XR_OBJECT_TYPE_FACE_TRACKER_BD, 1000386000) \ + _(XR_OBJECT_TYPE_SENSE_DATA_PROVIDER_BD, 1000389000) \ + _(XR_OBJECT_TYPE_SENSE_DATA_SNAPSHOT_BD, 1000389001) \ + _(XR_OBJECT_TYPE_ANCHOR_BD, 1000389002) \ + _(XR_OBJECT_TYPE_SPATIAL_AUDIO_RENDERER_BD, 1000409000) \ + _(XR_OBJECT_TYPE_SOUND_FIELD_BD, 1000409001) \ + _(XR_OBJECT_TYPE_SOUND_OBJECT_BD, 1000409002) \ + _(XR_OBJECT_TYPE_SOUND_OBSTACLE_BD, 1000409003) \ + _(XR_OBJECT_TYPE_SOUND_OBSTACLE_MATERIAL_BD, 1000409004) \ _(XR_OBJECT_TYPE_PLANE_DETECTOR_EXT, 1000429000) \ + _(XR_OBJECT_TYPE_TRACKABLE_TRACKER_ANDROID, 1000455001) \ + _(XR_OBJECT_TYPE_EYE_TRACKER_ANDROID, 1000456000) \ + _(XR_OBJECT_TYPE_DEVICE_ANCHOR_PERSISTENCE_ANDROID, 1000457000) \ + _(XR_OBJECT_TYPE_FACE_TRACKER_ANDROID, 1000458000) \ + _(XR_OBJECT_TYPE_PASSTHROUGH_LAYER_ANDROID, 1000462000) \ _(XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML, 1000474000) \ _(XR_OBJECT_TYPE_FACIAL_EXPRESSION_CLIENT_ML, 1000482000) \ + _(XR_OBJECT_TYPE_ENVIRONMENT_RAYCASTER_META, 1000592000) \ + _(XR_OBJECT_TYPE_LIGHT_ESTIMATOR_ANDROID, 1000700000) \ + _(XR_OBJECT_TYPE_TRACKABLE_IMAGE_DATABASE_ANDROID, 1000709000) \ + _(XR_OBJECT_TYPE_SCENE_MESHING_TRACKER_ANDROID, 1000718000) \ + _(XR_OBJECT_TYPE_SCENE_MESH_SNAPSHOT_ANDROID, 1000718001) \ + _(XR_OBJECT_TYPE_SPATIAL_ENTITY_EXT, 1000740000) \ + _(XR_OBJECT_TYPE_SPATIAL_CONTEXT_EXT, 1000740001) \ + _(XR_OBJECT_TYPE_SPATIAL_SNAPSHOT_EXT, 1000740002) \ + _(XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT, 1000763000) \ _(XR_OBJECT_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrLoaderInterfaceStructs(_) \ @@ -866,6 +1160,7 @@ XR_ENUM_STR(XrResult); #define XR_LIST_ENUM_XrBodyJointSetFB(_) \ _(XR_BODY_JOINT_SET_DEFAULT_FB, 0) \ + _(XR_BODY_JOINT_SET_FULL_BODY_META, 1000274000) \ _(XR_BODY_JOINT_SET_MAX_ENUM_FB, 0x7FFFFFFF) #define XR_LIST_ENUM_XrHandJointsMotionRangeEXT(_) \ @@ -1011,6 +1306,7 @@ XR_ENUM_STR(XrResult); _(XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB, 6) \ _(XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB, 7) \ _(XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META, 1000269000) \ + _(XR_SPACE_COMPONENT_TYPE_ROOM_MESH_META, 1000553000) \ _(XR_SPACE_COMPONENT_TYPE_MAX_ENUM_FB, 0x7FFFFFFF) #define XR_LIST_ENUM_XrFoveationLevelFB(_) \ @@ -1335,6 +1631,106 @@ XR_ENUM_STR(XrResult); _(XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGBA_META, 2) \ _(XR_PASSTHROUGH_COLOR_LUT_CHANNELS_MAX_ENUM_META, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrFullBodyJointMETA(_) \ + _(XR_FULL_BODY_JOINT_ROOT_META, 0) \ + _(XR_FULL_BODY_JOINT_HIPS_META, 1) \ + _(XR_FULL_BODY_JOINT_SPINE_LOWER_META, 2) \ + _(XR_FULL_BODY_JOINT_SPINE_MIDDLE_META, 3) \ + _(XR_FULL_BODY_JOINT_SPINE_UPPER_META, 4) \ + _(XR_FULL_BODY_JOINT_CHEST_META, 5) \ + _(XR_FULL_BODY_JOINT_NECK_META, 6) \ + _(XR_FULL_BODY_JOINT_HEAD_META, 7) \ + _(XR_FULL_BODY_JOINT_LEFT_SHOULDER_META, 8) \ + _(XR_FULL_BODY_JOINT_LEFT_SCAPULA_META, 9) \ + _(XR_FULL_BODY_JOINT_LEFT_ARM_UPPER_META, 10) \ + _(XR_FULL_BODY_JOINT_LEFT_ARM_LOWER_META, 11) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_TWIST_META, 12) \ + _(XR_FULL_BODY_JOINT_RIGHT_SHOULDER_META, 13) \ + _(XR_FULL_BODY_JOINT_RIGHT_SCAPULA_META, 14) \ + _(XR_FULL_BODY_JOINT_RIGHT_ARM_UPPER_META, 15) \ + _(XR_FULL_BODY_JOINT_RIGHT_ARM_LOWER_META, 16) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_META, 17) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_PALM_META, 18) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_META, 19) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_META, 20) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_META, 21) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_META, 22) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_TIP_META, 23) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_META, 24) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_META, 25) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_META, 26) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_META, 27) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_TIP_META, 28) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_META, 29) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_META, 30) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_META, 31) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_META, 32) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_META, 33) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_RING_METACARPAL_META, 34) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_META, 35) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_META, 36) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_RING_DISTAL_META, 37) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_RING_TIP_META, 38) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_META, 39) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_META, 40) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_META, 41) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_META, 42) \ + _(XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_TIP_META, 43) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_PALM_META, 44) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_META, 45) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_META, 46) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_META, 47) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_META, 48) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_TIP_META, 49) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_META, 50) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_META, 51) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_META, 52) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_META, 53) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_TIP_META, 54) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_META, 55) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_META, 56) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_META, 57) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_META, 58) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_META, 59) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_META, 60) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_META, 61) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_META, 62) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_RING_DISTAL_META, 63) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_RING_TIP_META, 64) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_META, 65) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_META, 66) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_META, 67) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_META, 68) \ + _(XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_META, 69) \ + _(XR_FULL_BODY_JOINT_LEFT_UPPER_LEG_META, 70) \ + _(XR_FULL_BODY_JOINT_LEFT_LOWER_LEG_META, 71) \ + _(XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_TWIST_META, 72) \ + _(XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_META, 73) \ + _(XR_FULL_BODY_JOINT_LEFT_FOOT_SUBTALAR_META, 74) \ + _(XR_FULL_BODY_JOINT_LEFT_FOOT_TRANSVERSE_META, 75) \ + _(XR_FULL_BODY_JOINT_LEFT_FOOT_BALL_META, 76) \ + _(XR_FULL_BODY_JOINT_RIGHT_UPPER_LEG_META, 77) \ + _(XR_FULL_BODY_JOINT_RIGHT_LOWER_LEG_META, 78) \ + _(XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_TWIST_META, 79) \ + _(XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_META, 80) \ + _(XR_FULL_BODY_JOINT_RIGHT_FOOT_SUBTALAR_META, 81) \ + _(XR_FULL_BODY_JOINT_RIGHT_FOOT_TRANSVERSE_META, 82) \ + _(XR_FULL_BODY_JOINT_RIGHT_FOOT_BALL_META, 83) \ + _(XR_FULL_BODY_JOINT_COUNT_META, 84) \ + _(XR_FULL_BODY_JOINT_NONE_META, 85) \ + _(XR_FULL_BODY_JOINT_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrBodyTrackingCalibrationStateMETA(_) \ + _(XR_BODY_TRACKING_CALIBRATION_STATE_VALID_META, 1) \ + _(XR_BODY_TRACKING_CALIBRATION_STATE_CALIBRATING_META, 2) \ + _(XR_BODY_TRACKING_CALIBRATION_STATE_INVALID_META, 3) \ + _(XR_BODY_TRACKING_CALIBRATION_STATE_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrBodyTrackingFidelityMETA(_) \ + _(XR_BODY_TRACKING_FIDELITY_LOW_META, 1) \ + _(XR_BODY_TRACKING_FIDELITY_HIGH_META, 2) \ + _(XR_BODY_TRACKING_FIDELITY_MAX_ENUM_META, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrFaceExpression2FB(_) \ _(XR_FACE_EXPRESSION2_BROW_LOWERER_L_FB, 0) \ _(XR_FACE_EXPRESSION2_BROW_LOWERER_R_FB, 1) \ @@ -1436,6 +1832,13 @@ XR_ENUM_STR(XrResult); _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_HIGH_POWER_PRIORIZATION_QCOM, 4) \ _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_MAX_ENUM_QCOM, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrHandGestureTypeQCOM(_) \ + _(XR_HAND_GESTURE_TYPE_UNKNOWN_QCOM, -1) \ + _(XR_HAND_GESTURE_TYPE_OPEN_HAND_QCOM, 0) \ + _(XR_HAND_GESTURE_TYPE_GRAB_QCOM, 2) \ + _(XR_HAND_GESTURE_TYPE_PINCH_QCOM, 7) \ + _(XR_HAND_GESTURE_TYPE_MAX_ENUM_QCOM, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrPassthroughFormHTC(_) \ _(XR_PASSTHROUGH_FORM_PLANAR_HTC, 0) \ _(XR_PASSTHROUGH_FORM_PROJECTED_HTC, 1) \ @@ -1534,6 +1937,268 @@ XR_ENUM_STR(XrResult); _(XR_BODY_JOINT_SET_FULL_BODY_JOINTS_BD, 2) \ _(XR_BODY_JOINT_SET_MAX_ENUM_BD, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrFacialSimulationModeBD(_) \ + _(XR_FACIAL_SIMULATION_MODE_DEFAULT_BD, 0) \ + _(XR_FACIAL_SIMULATION_MODE_COMBINED_AUDIO_BD, 1) \ + _(XR_FACIAL_SIMULATION_MODE_COMBINED_AUDIO_WITH_LIP_BD, 2) \ + _(XR_FACIAL_SIMULATION_MODE_ONLY_AUDIO_WITH_LIP_BD, 3) \ + _(XR_FACIAL_SIMULATION_MODE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceExpressionBD(_) \ + _(XR_FACE_EXPRESSION_BROW_DROP_L_BD, 0) \ + _(XR_FACE_EXPRESSION_BROW_DROP_R_BD, 1) \ + _(XR_FACE_EXPRESSION_BROW_INNER_UPWARDS_BD, 2) \ + _(XR_FACE_EXPRESSION_BROW_OUTER_UPWARDS_L_BD, 3) \ + _(XR_FACE_EXPRESSION_BROW_OUTER_UPWARDS_R_BD, 4) \ + _(XR_FACE_EXPRESSION_EYE_BLINK_L_BD, 5) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_DROP_L_BD, 6) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_IN_L_BD, 7) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_OUT_L_BD, 8) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_UPWARDS_L_BD, 9) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_SQUINT_L_BD, 10) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_WIDE_L_BD, 11) \ + _(XR_FACE_EXPRESSION_EYE_BLINK_R_BD, 12) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_DROP_R_BD, 13) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_IN_R_BD, 14) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_OUT_R_BD, 15) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_UPWARDS_R_BD, 16) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_SQUINT_R_BD, 17) \ + _(XR_FACE_EXPRESSION_EYE_LOOK_WIDE_R_BD, 18) \ + _(XR_FACE_EXPRESSION_NOSE_SNEER_L_BD, 19) \ + _(XR_FACE_EXPRESSION_NOSE_SNEER_R_BD, 20) \ + _(XR_FACE_EXPRESSION_CHEEK_PUFF_BD, 21) \ + _(XR_FACE_EXPRESSION_CHEEK_SQUINT_L_BD, 22) \ + _(XR_FACE_EXPRESSION_CHEEK_SQUINT_R_BD, 23) \ + _(XR_FACE_EXPRESSION_MOUTH_CLOSE_BD, 24) \ + _(XR_FACE_EXPRESSION_MOUTH_FUNNEL_BD, 25) \ + _(XR_FACE_EXPRESSION_MOUTH_PUCKER_BD, 26) \ + _(XR_FACE_EXPRESSION_MOUTH_L_BD, 27) \ + _(XR_FACE_EXPRESSION_MOUTH_R_BD, 28) \ + _(XR_FACE_EXPRESSION_MOUTH_SMILE_L_BD, 29) \ + _(XR_FACE_EXPRESSION_MOUTH_SMILE_R_BD, 30) \ + _(XR_FACE_EXPRESSION_MOUTH_FROWN_L_BD, 31) \ + _(XR_FACE_EXPRESSION_MOUTH_FROWN_R_BD, 32) \ + _(XR_FACE_EXPRESSION_MOUTH_DIMPLE_L_BD, 33) \ + _(XR_FACE_EXPRESSION_MOUTH_DIMPLE_R_BD, 34) \ + _(XR_FACE_EXPRESSION_MOUTH_STRETCH_L_BD, 35) \ + _(XR_FACE_EXPRESSION_MOUTH_STRETCH_R_BD, 36) \ + _(XR_FACE_EXPRESSION_MOUTH_ROLL_LOWER_BD, 37) \ + _(XR_FACE_EXPRESSION_MOUTH_ROLL_UPPER_BD, 38) \ + _(XR_FACE_EXPRESSION_MOUTH_SHRUG_LOWER_BD, 39) \ + _(XR_FACE_EXPRESSION_MOUTH_SHRUG_UPPER_BD, 40) \ + _(XR_FACE_EXPRESSION_MOUTH_PRESS_L_BD, 41) \ + _(XR_FACE_EXPRESSION_MOUTH_PRESS_R_BD, 42) \ + _(XR_FACE_EXPRESSION_MOUTH_LOWER_DROP_L_BD, 43) \ + _(XR_FACE_EXPRESSION_MOUTH_LOWER_DROP_R_BD, 44) \ + _(XR_FACE_EXPRESSION_MOUTH_UPPER_UPWARDS_L_BD, 45) \ + _(XR_FACE_EXPRESSION_MOUTH_UPPER_UPWARDS_R_BD, 46) \ + _(XR_FACE_EXPRESSION_JAW_FORWARD_BD, 47) \ + _(XR_FACE_EXPRESSION_JAW_L_BD, 48) \ + _(XR_FACE_EXPRESSION_JAW_R_BD, 49) \ + _(XR_FACE_EXPRESSION_JAW_OPEN_BD, 50) \ + _(XR_FACE_EXPRESSION_TONGUE_OUT_BD, 51) \ + _(XR_FACE_EXPRESSION_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrLipExpressionBD(_) \ + _(XR_LIP_EXPRESSION_PP_BD, 0) \ + _(XR_LIP_EXPRESSION_CH_BD, 1) \ + _(XR_LIP_EXPRESSION_LO_BD, 2) \ + _(XR_LIP_EXPRESSION_O_BD, 3) \ + _(XR_LIP_EXPRESSION_I_BD, 4) \ + _(XR_LIP_EXPRESSION_LU_BD, 5) \ + _(XR_LIP_EXPRESSION_RR_BD, 6) \ + _(XR_LIP_EXPRESSION_XX_BD, 7) \ + _(XR_LIP_EXPRESSION_LAA_BD, 8) \ + _(XR_LIP_EXPRESSION_LI_BD, 9) \ + _(XR_LIP_EXPRESSION_FF_BD, 10) \ + _(XR_LIP_EXPRESSION_U_BD, 11) \ + _(XR_LIP_EXPRESSION_TH_BD, 12) \ + _(XR_LIP_EXPRESSION_LKK_BD, 13) \ + _(XR_LIP_EXPRESSION_SS_BD, 14) \ + _(XR_LIP_EXPRESSION_LE_BD, 15) \ + _(XR_LIP_EXPRESSION_DD_BD, 16) \ + _(XR_LIP_EXPRESSION_E_BD, 17) \ + _(XR_LIP_EXPRESSION_LNN_BD, 18) \ + _(XR_LIP_EXPRESSION_SIL_BD, 19) \ + _(XR_LIP_EXPRESSION_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialEntityComponentTypeBD(_) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_LOCATION_BD, 0) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_SEMANTIC_BD, 1) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_BOUNDING_BOX_2D_BD, 2) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_POLYGON_BD, 3) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_BOUNDING_BOX_3D_BD, 4) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_TRIANGLE_MESH_BD, 5) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_PLANE_ORIENTATION_BD, 1000396000) \ + _(XR_SPATIAL_ENTITY_COMPONENT_TYPE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSemanticLabelBD(_) \ + _(XR_SEMANTIC_LABEL_UNKNOWN_BD, 0) \ + _(XR_SEMANTIC_LABEL_FLOOR_BD, 1) \ + _(XR_SEMANTIC_LABEL_CEILING_BD, 2) \ + _(XR_SEMANTIC_LABEL_WALL_BD, 3) \ + _(XR_SEMANTIC_LABEL_DOOR_BD, 4) \ + _(XR_SEMANTIC_LABEL_WINDOW_BD, 5) \ + _(XR_SEMANTIC_LABEL_OPENING_BD, 6) \ + _(XR_SEMANTIC_LABEL_TABLE_BD, 7) \ + _(XR_SEMANTIC_LABEL_SOFA_BD, 8) \ + _(XR_SEMANTIC_LABEL_CHAIR_BD, 9) \ + _(XR_SEMANTIC_LABEL_HUMAN_BD, 10) \ + _(XR_SEMANTIC_LABEL_BEAM_BD, 11) \ + _(XR_SEMANTIC_LABEL_COLUMN_BD, 12) \ + _(XR_SEMANTIC_LABEL_CURTAIN_BD, 13) \ + _(XR_SEMANTIC_LABEL_CABINET_BD, 14) \ + _(XR_SEMANTIC_LABEL_BED_BD, 15) \ + _(XR_SEMANTIC_LABEL_PLANT_BD, 16) \ + _(XR_SEMANTIC_LABEL_SCREEN_BD, 17) \ + _(XR_SEMANTIC_LABEL_VIRTUAL_WALL_BD, 18) \ + _(XR_SEMANTIC_LABEL_REFRIGERATOR_BD, 19) \ + _(XR_SEMANTIC_LABEL_WASHING_MACHINE_BD, 20) \ + _(XR_SEMANTIC_LABEL_AIR_CONDITIONER_BD, 21) \ + _(XR_SEMANTIC_LABEL_LAMP_BD, 22) \ + _(XR_SEMANTIC_LABEL_WALL_ART_BD, 23) \ + _(XR_SEMANTIC_LABEL_STAIRWAY_BD, 24) \ + _(XR_SEMANTIC_LABEL_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSenseDataProviderTypeBD(_) \ + _(XR_SENSE_DATA_PROVIDER_TYPE_ANCHOR_BD, 1000390000) \ + _(XR_SENSE_DATA_PROVIDER_TYPE_SCENE_BD, 1000392000) \ + _(XR_SENSE_DATA_PROVIDER_TYPE_MESH_BD, 1000393000) \ + _(XR_SENSE_DATA_PROVIDER_TYPE_PLANE_BD, 1000396000) \ + _(XR_SENSE_DATA_PROVIDER_TYPE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSenseDataProviderStateBD(_) \ + _(XR_SENSE_DATA_PROVIDER_STATE_INITIALIZED_BD, 0) \ + _(XR_SENSE_DATA_PROVIDER_STATE_RUNNING_BD, 1) \ + _(XR_SENSE_DATA_PROVIDER_STATE_STOPPED_BD, 2) \ + _(XR_SENSE_DATA_PROVIDER_STATE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPersistenceLocationBD(_) \ + _(XR_PERSISTENCE_LOCATION_LOCAL_BD, 0) \ + _(XR_PERSISTENCE_LOCATION_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialMeshLodBD(_) \ + _(XR_SPATIAL_MESH_LOD_COARSE_BD, 0) \ + _(XR_SPATIAL_MESH_LOD_MEDIUM_BD, 1) \ + _(XR_SPATIAL_MESH_LOD_FINE_BD, 2) \ + _(XR_SPATIAL_MESH_LOD_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneOrientationBD(_) \ + _(XR_PLANE_ORIENTATION_HORIZONTAL_UPWARD_BD, 0) \ + _(XR_PLANE_ORIENTATION_HORIZONTAL_DOWNWARD_BD, 1) \ + _(XR_PLANE_ORIENTATION_VERTICAL_BD, 2) \ + _(XR_PLANE_ORIENTATION_ARBITRARY_BD, 3) \ + _(XR_PLANE_ORIENTATION_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrAudioSampleRateBD(_) \ + _(XR_AUDIO_SAMPLE_RATE_192000_HZ_BD, 1) \ + _(XR_AUDIO_SAMPLE_RATE_96000_HZ_BD, 2) \ + _(XR_AUDIO_SAMPLE_RATE_48000_HZ_BD, 3) \ + _(XR_AUDIO_SAMPLE_RATE_44100_HZ_BD, 4) \ + _(XR_AUDIO_SAMPLE_RATE_32000_HZ_BD, 5) \ + _(XR_AUDIO_SAMPLE_RATE_24000_HZ_BD, 6) \ + _(XR_AUDIO_SAMPLE_RATE_22050_HZ_BD, 7) \ + _(XR_AUDIO_SAMPLE_RATE_16000_HZ_BD, 8) \ + _(XR_AUDIO_SAMPLE_RATE_12000_HZ_BD, 9) \ + _(XR_AUDIO_SAMPLE_RATE_11025_HZ_BD, 10) \ + _(XR_AUDIO_SAMPLE_RATE_8000_HZ_BD, 11) \ + _(XR_AUDIO_SAMPLE_RATE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrAudioBufferChannelLayoutBD(_) \ + _(XR_AUDIO_BUFFER_CHANNEL_LAYOUT_INTERLEAVED_BD, 0) \ + _(XR_AUDIO_BUFFER_CHANNEL_LAYOUT_PLANAR_BD, 1) \ + _(XR_AUDIO_BUFFER_CHANNEL_LAYOUT_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSoundObjectDistanceAttenuationTypeBD(_) \ + _(XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_NONE_BD, 0) \ + _(XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_INVERSE_SQUARE_BD, 1) \ + _(XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_ROLLOFF_BD, 2) \ + _(XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_CUSTOMIZED_BD, 100) \ + _(XR_SOUND_OBJECT_DISTANCE_ATTENUATION_TYPE_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSoundFieldChannelMaskSurroundBD(_) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_LEFT_BD, 1) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_RIGHT_BD, 2) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_FRONT_CENTER_BD, 4) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_LOW_FREQUENCY_BD, 8) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_LEFT_BD, 16) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_RIGHT_BD, 32) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SIDE_LEFT_BD, 64) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SIDE_RIGHT_BD, 128) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_FRONT_LEFT_BD, 256) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_FRONT_RIGHT_BD, 512) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_BACK_LEFT_BD, 1024) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_BACK_RIGHT_BD, 2048) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_BACK_CENTER_BD, 4096) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_SIDE_LEFT_BD, 8192) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_TOP_SIDE_RIGHT_BD, 16384) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_STEREO_BD, 3) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_2_1_BD, 11) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_3_0_BD, 7) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_4_0_BD, 4099) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_BACK_SURROUND_BD, 48) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_QUAD_BD, 51) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_3_1_BD, 15) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_0_BD, 55) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_SIDE_SURROUND_BD, 192) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_0_SIDE_BD, 199) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_BD, 63) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_SIDE_BD, 207) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_0_BD, 247) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_BD, 255) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_2_BD, 831) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_5_1_4_BD, 3903) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_2_BD, 24831) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_SETUP_7_1_4_BD, 4095) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_SURROUND_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSoundFieldChannelMaskAmbixBD(_) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_1ST_ORDER_BD, 1) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_2ND_ORDER_BD, 2) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_3RD_ORDER_BD, 3) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_4TH_ORDER_BD, 4) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_5TH_ORDER_BD, 5) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_6TH_ORDER_BD, 6) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_7TH_ORDER_BD, 7) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_AMBIX_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSoundFieldChannelMaskFumaBD(_) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_FUMA_1ST_ORDER_BD, 1) \ + _(XR_SOUND_FIELD_CHANNEL_MASK_FUMA_MAX_ENUM_BD, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSoundObstacleMaterialTypeBD(_) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_ACOUSTIC_TILE_BD, 0) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_BRICK_BD, 1) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_BRICK_PAINTED_BD, 2) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_BD, 3) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_HEAVY_BD, 4) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CARPET_HEAVY_PADDED_BD, 5) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CERAMIC_TILE_BD, 6) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BD, 7) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_ROUGH_BD, 8) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BLOCK_BD, 9) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CONCRETE_BLOCK_PAINTED_BD, 10) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CURTAIN_BD, 11) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_FOLIAGE_BD, 12) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_GLASS_BD, 13) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_GLASS_HEAVY_BD, 14) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_GRASS_BD, 15) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_GRAVEL_BD, 16) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_GYPSUM_BOARD_BD, 17) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_PLASTER_ON_BRICK_BD, 18) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_PLASTER_ON_CONCRETE_BLOCK_BD, 19) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_SOIL_BD, 20) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_SOUND_PROOF_BD, 21) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_SNOW_BD, 22) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_STEEL_BD, 23) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_WATER_BD, 24) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_THIN_BD, 25) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_THICK_BD, 26) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_FLOOR_BD, 27) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_WOOD_ON_CONCRETE_BD, 28) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_CUSTOM_BD, 29) \ + _(XR_SOUND_OBSTACLE_MATERIAL_TYPE_MAX_ENUM_BD, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrHandTrackingDataSourceEXT(_) \ _(XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT, 1) \ _(XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT, 2) \ @@ -1562,6 +2227,172 @@ XR_ENUM_STR(XrResult); _(XR_PLANE_DETECTION_STATE_FATAL_EXT, 4) \ _(XR_PLANE_DETECTION_STATE_MAX_ENUM_EXT, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrTrackingStateANDROID(_) \ + _(XR_TRACKING_STATE_PAUSED_ANDROID, 0) \ + _(XR_TRACKING_STATE_STOPPED_ANDROID, 1) \ + _(XR_TRACKING_STATE_TRACKING_ANDROID, 2) \ + _(XR_TRACKING_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackableTypeANDROID(_) \ + _(XR_TRACKABLE_TYPE_NOT_VALID_ANDROID, 0) \ + _(XR_TRACKABLE_TYPE_PLANE_ANDROID, 1) \ + _(XR_TRACKABLE_TYPE_DEPTH_ANDROID, 1000463000) \ + _(XR_TRACKABLE_TYPE_OBJECT_ANDROID, 1000466000) \ + _(XR_TRACKABLE_TYPE_MARKER_ANDROID, 1000707000) \ + _(XR_TRACKABLE_TYPE_QR_CODE_ANDROID, 1000708000) \ + _(XR_TRACKABLE_TYPE_IMAGE_ANDROID, 1000709000) \ + _(XR_TRACKABLE_TYPE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneTypeANDROID(_) \ + _(XR_PLANE_TYPE_HORIZONTAL_DOWNWARD_FACING_ANDROID, 0) \ + _(XR_PLANE_TYPE_HORIZONTAL_UPWARD_FACING_ANDROID, 1) \ + _(XR_PLANE_TYPE_VERTICAL_ANDROID, 2) \ + _(XR_PLANE_TYPE_ARBITRARY_ANDROID, 3) \ + _(XR_PLANE_TYPE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneLabelANDROID(_) \ + _(XR_PLANE_LABEL_UNKNOWN_ANDROID, 0) \ + _(XR_PLANE_LABEL_WALL_ANDROID, 1) \ + _(XR_PLANE_LABEL_FLOOR_ANDROID, 2) \ + _(XR_PLANE_LABEL_CEILING_ANDROID, 3) \ + _(XR_PLANE_LABEL_TABLE_ANDROID, 4) \ + _(XR_PLANE_LABEL_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrEyeIndexANDROID(_) \ + _(XR_EYE_INDEX_LEFT_ANDROID, 0) \ + _(XR_EYE_INDEX_RIGHT_ANDROID, 1) \ + _(XR_EYE_INDEX_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrEyeStateANDROID(_) \ + _(XR_EYE_STATE_INVALID_ANDROID, 0) \ + _(XR_EYE_STATE_GAZING_ANDROID, 1) \ + _(XR_EYE_STATE_SHUT_ANDROID, 2) \ + _(XR_EYE_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrEyeTrackingModeANDROID(_) \ + _(XR_EYE_TRACKING_MODE_NOT_TRACKING_ANDROID, 0) \ + _(XR_EYE_TRACKING_MODE_RIGHT_ANDROID, 1) \ + _(XR_EYE_TRACKING_MODE_LEFT_ANDROID, 2) \ + _(XR_EYE_TRACKING_MODE_BOTH_ANDROID, 3) \ + _(XR_EYE_TRACKING_MODE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrAnchorPersistStateANDROID(_) \ + _(XR_ANCHOR_PERSIST_STATE_PERSIST_NOT_REQUESTED_ANDROID, 0) \ + _(XR_ANCHOR_PERSIST_STATE_PERSIST_PENDING_ANDROID, 1) \ + _(XR_ANCHOR_PERSIST_STATE_PERSISTED_ANDROID, 2) \ + _(XR_ANCHOR_PERSIST_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceParameterIndicesANDROID(_) \ + _(XR_FACE_PARAMETER_INDICES_BROW_LOWERER_L_ANDROID, 0) \ + _(XR_FACE_PARAMETER_INDICES_BROW_LOWERER_R_ANDROID, 1) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_PUFF_L_ANDROID, 2) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_PUFF_R_ANDROID, 3) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_RAISER_L_ANDROID, 4) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_RAISER_R_ANDROID, 5) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_SUCK_L_ANDROID, 6) \ + _(XR_FACE_PARAMETER_INDICES_CHEEK_SUCK_R_ANDROID, 7) \ + _(XR_FACE_PARAMETER_INDICES_CHIN_RAISER_B_ANDROID, 8) \ + _(XR_FACE_PARAMETER_INDICES_CHIN_RAISER_T_ANDROID, 9) \ + _(XR_FACE_PARAMETER_INDICES_DIMPLER_L_ANDROID, 10) \ + _(XR_FACE_PARAMETER_INDICES_DIMPLER_R_ANDROID, 11) \ + _(XR_FACE_PARAMETER_INDICES_EYES_CLOSED_L_ANDROID, 12) \ + _(XR_FACE_PARAMETER_INDICES_EYES_CLOSED_R_ANDROID, 13) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_L_ANDROID, 14) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_R_ANDROID, 15) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_L_ANDROID, 16) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_R_ANDROID, 17) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_L_ANDROID, 18) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_R_ANDROID, 19) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_UP_L_ANDROID, 20) \ + _(XR_FACE_PARAMETER_INDICES_EYES_LOOK_UP_R_ANDROID, 21) \ + _(XR_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_L_ANDROID, 22) \ + _(XR_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_R_ANDROID, 23) \ + _(XR_FACE_PARAMETER_INDICES_JAW_DROP_ANDROID, 24) \ + _(XR_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_LEFT_ANDROID, 25) \ + _(XR_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_RIGHT_ANDROID, 26) \ + _(XR_FACE_PARAMETER_INDICES_JAW_THRUST_ANDROID, 27) \ + _(XR_FACE_PARAMETER_INDICES_LID_TIGHTENER_L_ANDROID, 28) \ + _(XR_FACE_PARAMETER_INDICES_LID_TIGHTENER_R_ANDROID, 29) \ + _(XR_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_L_ANDROID, 30) \ + _(XR_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_R_ANDROID, 31) \ + _(XR_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_L_ANDROID, 32) \ + _(XR_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_R_ANDROID, 33) \ + _(XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_LB_ANDROID, 34) \ + _(XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_LT_ANDROID, 35) \ + _(XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_RB_ANDROID, 36) \ + _(XR_FACE_PARAMETER_INDICES_LIP_FUNNELER_RT_ANDROID, 37) \ + _(XR_FACE_PARAMETER_INDICES_LIP_PRESSOR_L_ANDROID, 38) \ + _(XR_FACE_PARAMETER_INDICES_LIP_PRESSOR_R_ANDROID, 39) \ + _(XR_FACE_PARAMETER_INDICES_LIP_PUCKER_L_ANDROID, 40) \ + _(XR_FACE_PARAMETER_INDICES_LIP_PUCKER_R_ANDROID, 41) \ + _(XR_FACE_PARAMETER_INDICES_LIP_STRETCHER_L_ANDROID, 42) \ + _(XR_FACE_PARAMETER_INDICES_LIP_STRETCHER_R_ANDROID, 43) \ + _(XR_FACE_PARAMETER_INDICES_LIP_SUCK_LB_ANDROID, 44) \ + _(XR_FACE_PARAMETER_INDICES_LIP_SUCK_LT_ANDROID, 45) \ + _(XR_FACE_PARAMETER_INDICES_LIP_SUCK_RB_ANDROID, 46) \ + _(XR_FACE_PARAMETER_INDICES_LIP_SUCK_RT_ANDROID, 47) \ + _(XR_FACE_PARAMETER_INDICES_LIP_TIGHTENER_L_ANDROID, 48) \ + _(XR_FACE_PARAMETER_INDICES_LIP_TIGHTENER_R_ANDROID, 49) \ + _(XR_FACE_PARAMETER_INDICES_LIPS_TOWARD_ANDROID, 50) \ + _(XR_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_L_ANDROID, 51) \ + _(XR_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_R_ANDROID, 52) \ + _(XR_FACE_PARAMETER_INDICES_MOUTH_LEFT_ANDROID, 53) \ + _(XR_FACE_PARAMETER_INDICES_MOUTH_RIGHT_ANDROID, 54) \ + _(XR_FACE_PARAMETER_INDICES_NOSE_WRINKLER_L_ANDROID, 55) \ + _(XR_FACE_PARAMETER_INDICES_NOSE_WRINKLER_R_ANDROID, 56) \ + _(XR_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_L_ANDROID, 57) \ + _(XR_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_R_ANDROID, 58) \ + _(XR_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_L_ANDROID, 59) \ + _(XR_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_R_ANDROID, 60) \ + _(XR_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_L_ANDROID, 61) \ + _(XR_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_R_ANDROID, 62) \ + _(XR_FACE_PARAMETER_INDICES_TONGUE_OUT_ANDROID, 63) \ + _(XR_FACE_PARAMETER_INDICES_TONGUE_LEFT_ANDROID, 64) \ + _(XR_FACE_PARAMETER_INDICES_TONGUE_RIGHT_ANDROID, 65) \ + _(XR_FACE_PARAMETER_INDICES_TONGUE_UP_ANDROID, 66) \ + _(XR_FACE_PARAMETER_INDICES_TONGUE_DOWN_ANDROID, 67) \ + _(XR_FACE_PARAMETER_INDICES_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceTrackingStateANDROID(_) \ + _(XR_FACE_TRACKING_STATE_PAUSED_ANDROID, 0) \ + _(XR_FACE_TRACKING_STATE_STOPPED_ANDROID, 1) \ + _(XR_FACE_TRACKING_STATE_TRACKING_ANDROID, 2) \ + _(XR_FACE_TRACKING_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceConfidenceRegionsANDROID(_) \ + _(XR_FACE_CONFIDENCE_REGIONS_LOWER_ANDROID, 0) \ + _(XR_FACE_CONFIDENCE_REGIONS_LEFT_UPPER_ANDROID, 1) \ + _(XR_FACE_CONFIDENCE_REGIONS_RIGHT_UPPER_ANDROID, 2) \ + _(XR_FACE_CONFIDENCE_REGIONS_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPassthroughCameraStateANDROID(_) \ + _(XR_PASSTHROUGH_CAMERA_STATE_DISABLED_ANDROID, 0) \ + _(XR_PASSTHROUGH_CAMERA_STATE_INITIALIZING_ANDROID, 1) \ + _(XR_PASSTHROUGH_CAMERA_STATE_READY_ANDROID, 2) \ + _(XR_PASSTHROUGH_CAMERA_STATE_ERROR_ANDROID, 3) \ + _(XR_PASSTHROUGH_CAMERA_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrWindingOrderANDROID(_) \ + _(XR_WINDING_ORDER_UNKNOWN_ANDROID, 0) \ + _(XR_WINDING_ORDER_CW_ANDROID, 1) \ + _(XR_WINDING_ORDER_CCW_ANDROID, 2) \ + _(XR_WINDING_ORDER_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPerformanceMetricsCounterUnitANDROID(_) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_GENERIC_ANDROID, 0) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_PERCENTAGE_ANDROID, 1) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_MILLISECONDS_ANDROID, 2) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_BYTES_ANDROID, 3) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_HERTZ_ANDROID, 4) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrObjectLabelANDROID(_) \ + _(XR_OBJECT_LABEL_UNKNOWN_ANDROID, 0) \ + _(XR_OBJECT_LABEL_KEYBOARD_ANDROID, 1) \ + _(XR_OBJECT_LABEL_MOUSE_ANDROID, 2) \ + _(XR_OBJECT_LABEL_LAPTOP_ANDROID, 3) \ + _(XR_OBJECT_LABEL_MAX_ENUM_ANDROID, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrFutureStateEXT(_) \ _(XR_FUTURE_STATE_PENDING_EXT, 1) \ _(XR_FUTURE_STATE_READY_EXT, 2) \ @@ -1650,6 +2481,235 @@ XR_ENUM_STR(XrResult); _(XR_FACIAL_BLEND_SHAPE_TONGUE_OUT_ML, 45) \ _(XR_FACIAL_BLEND_SHAPE_MAX_ENUM_ML, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrBoundaryVisibilityMETA(_) \ + _(XR_BOUNDARY_VISIBILITY_NOT_SUPPRESSED_META, 1) \ + _(XR_BOUNDARY_VISIBILITY_SUPPRESSED_META, 2) \ + _(XR_BOUNDARY_VISIBILITY_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceTrackingVisemeMETA(_) \ + _(XR_FACE_TRACKING_VISEME_SIL_META, 0) \ + _(XR_FACE_TRACKING_VISEME_PP_META, 1) \ + _(XR_FACE_TRACKING_VISEME_FF_META, 2) \ + _(XR_FACE_TRACKING_VISEME_TH_META, 3) \ + _(XR_FACE_TRACKING_VISEME_DD_META, 4) \ + _(XR_FACE_TRACKING_VISEME_KK_META, 5) \ + _(XR_FACE_TRACKING_VISEME_CH_META, 6) \ + _(XR_FACE_TRACKING_VISEME_SS_META, 7) \ + _(XR_FACE_TRACKING_VISEME_NN_META, 8) \ + _(XR_FACE_TRACKING_VISEME_RR_META, 9) \ + _(XR_FACE_TRACKING_VISEME_AA_META, 10) \ + _(XR_FACE_TRACKING_VISEME_E_META, 11) \ + _(XR_FACE_TRACKING_VISEME_IH_META, 12) \ + _(XR_FACE_TRACKING_VISEME_OH_META, 13) \ + _(XR_FACE_TRACKING_VISEME_OU_META, 14) \ + _(XR_FACE_TRACKING_VISEME_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSemanticLabelMETA(_) \ + _(XR_SEMANTIC_LABEL_UNKNOWN_META, 0) \ + _(XR_SEMANTIC_LABEL_FLOOR_META, 1) \ + _(XR_SEMANTIC_LABEL_CEILING_META, 2) \ + _(XR_SEMANTIC_LABEL_WALL_FACE_META, 3) \ + _(XR_SEMANTIC_LABEL_INNER_WALL_FACE_META, 4) \ + _(XR_SEMANTIC_LABEL_INVISIBLE_WALL_FACE_META, 5) \ + _(XR_SEMANTIC_LABEL_DOOR_FRAME_META, 6) \ + _(XR_SEMANTIC_LABEL_WINDOW_FRAME_META, 7) \ + _(XR_SEMANTIC_LABEL_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrEnvironmentRaycastHitStatusMETA(_) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_META, 1) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_NO_HIT_META, 2) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_POINT_OCCLUDED_META, 3) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_POINT_OUTSIDE_OF_FOV_META, 4) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_RAY_OCCLUDED_META, 5) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_HIT_INVALID_ORIENTATION_META, 6) \ + _(XR_ENVIRONMENT_RAYCAST_HIT_STATUS_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrLightEstimateStateANDROID(_) \ + _(XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID, 0) \ + _(XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID, 1) \ + _(XR_LIGHT_ESTIMATE_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSphericalHarmonicsKindANDROID(_) \ + _(XR_SPHERICAL_HARMONICS_KIND_TOTAL_ANDROID, 0) \ + _(XR_SPHERICAL_HARMONICS_KIND_AMBIENT_ANDROID, 1) \ + _(XR_SPHERICAL_HARMONICS_KIND_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackableMarkerTrackingModeANDROID(_) \ + _(XR_TRACKABLE_MARKER_TRACKING_MODE_DYNAMIC_ANDROID, 0) \ + _(XR_TRACKABLE_MARKER_TRACKING_MODE_STATIC_ANDROID, 1) \ + _(XR_TRACKABLE_MARKER_TRACKING_MODE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackableMarkerDictionaryANDROID(_) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_50_ANDROID, 0) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_100_ANDROID, 1) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_250_ANDROID, 2) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_4X4_1000_ANDROID, 3) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_50_ANDROID, 4) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_100_ANDROID, 5) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_250_ANDROID, 6) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_5X5_1000_ANDROID, 7) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_50_ANDROID, 8) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_100_ANDROID, 9) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_250_ANDROID, 10) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_6X6_1000_ANDROID, 11) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_50_ANDROID, 12) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_100_ANDROID, 13) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_250_ANDROID, 14) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_ARUCO_7X7_1000_ANDROID, 15) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_16H5_ANDROID, 16) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_25H9_ANDROID, 17) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_36H10_ANDROID, 18) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_APRILTAG_36H11_ANDROID, 19) \ + _(XR_TRACKABLE_MARKER_DICTIONARY_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrQrCodeTrackingModeANDROID(_) \ + _(XR_QR_CODE_TRACKING_MODE_DYNAMIC_ANDROID, 0) \ + _(XR_QR_CODE_TRACKING_MODE_STATIC_ANDROID, 1) \ + _(XR_QRCODE_TRACKING_MODE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackableImageTrackingModeANDROID(_) \ + _(XR_TRACKABLE_IMAGE_TRACKING_MODE_DYNAMIC_ANDROID, 1) \ + _(XR_TRACKABLE_IMAGE_TRACKING_MODE_STATIC_ANDROID, 2) \ + _(XR_TRACKABLE_IMAGE_TRACKING_MODE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackableImageFormatANDROID(_) \ + _(XR_TRACKABLE_IMAGE_FORMAT_R8G8B8A8_ANDROID, 1) \ + _(XR_TRACKABLE_IMAGE_FORMAT_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSceneMeshSemanticLabelSetANDROID(_) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID, 0) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID, 1) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_SET_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSceneMeshTrackingStateANDROID(_) \ + _(XR_SCENE_MESH_TRACKING_STATE_INITIALIZING_ANDROID, 0) \ + _(XR_SCENE_MESH_TRACKING_STATE_TRACKING_ANDROID, 1) \ + _(XR_SCENE_MESH_TRACKING_STATE_WAITING_ANDROID, 2) \ + _(XR_SCENE_MESH_TRACKING_STATE_ERROR_ANDROID, 3) \ + _(XR_SCENE_MESH_TRACKING_STATE_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSceneMeshSemanticLabelANDROID(_) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_OTHER_ANDROID, 0) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_FLOOR_ANDROID, 1) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_CEILING_ANDROID, 2) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_WALL_ANDROID, 3) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_TABLE_ANDROID, 4) \ + _(XR_SCENE_MESH_SEMANTIC_LABEL_MAX_ENUM_ANDROID, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialCapabilityEXT(_) \ + _(XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, 1000741000) \ + _(XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, 1000743000) \ + _(XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT, 1000743001) \ + _(XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT, 1000743002) \ + _(XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT, 1000743003) \ + _(XR_SPATIAL_CAPABILITY_ANCHOR_EXT, 1000762000) \ + _(XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID, 1000785000) \ + _(XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID, 1000786000) \ + _(XR_SPATIAL_CAPABILITY_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialCapabilityFeatureEXT(_) \ + _(XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT, 1000743000) \ + _(XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT, 1000743001) \ + _(XR_SPATIAL_CAPABILITY_FEATURE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialComponentTypeEXT(_) \ + _(XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT, 1) \ + _(XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT, 2) \ + _(XR_SPATIAL_COMPONENT_TYPE_PARENT_EXT, 3) \ + _(XR_SPATIAL_COMPONENT_TYPE_MESH_3D_EXT, 4) \ + _(XR_SPATIAL_COMPONENT_TYPE_PLANE_ALIGNMENT_EXT, 1000741000) \ + _(XR_SPATIAL_COMPONENT_TYPE_MESH_2D_EXT, 1000741001) \ + _(XR_SPATIAL_COMPONENT_TYPE_POLYGON_2D_EXT, 1000741002) \ + _(XR_SPATIAL_COMPONENT_TYPE_PLANE_SEMANTIC_LABEL_EXT, 1000741003) \ + _(XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT, 1000743000) \ + _(XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT, 1000762000) \ + _(XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT, 1000763000) \ + _(XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID, 1000785000) \ + _(XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID, 1000786000) \ + _(XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID, 1000791000) \ + _(XR_SPATIAL_COMPONENT_TYPE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialEntityTrackingStateEXT(_) \ + _(XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT, 1) \ + _(XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT, 2) \ + _(XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT, 3) \ + _(XR_SPATIAL_ENTITY_TRACKING_STATE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialBufferTypeEXT(_) \ + _(XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT, 0) \ + _(XR_SPATIAL_BUFFER_TYPE_STRING_EXT, 1) \ + _(XR_SPATIAL_BUFFER_TYPE_UINT8_EXT, 2) \ + _(XR_SPATIAL_BUFFER_TYPE_UINT16_EXT, 3) \ + _(XR_SPATIAL_BUFFER_TYPE_UINT32_EXT, 4) \ + _(XR_SPATIAL_BUFFER_TYPE_FLOAT_EXT, 5) \ + _(XR_SPATIAL_BUFFER_TYPE_VECTOR2F_EXT, 6) \ + _(XR_SPATIAL_BUFFER_TYPE_VECTOR3F_EXT, 7) \ + _(XR_SPATIAL_BUFFER_TYPE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialPlaneAlignmentEXT(_) \ + _(XR_SPATIAL_PLANE_ALIGNMENT_HORIZONTAL_UPWARD_EXT, 0) \ + _(XR_SPATIAL_PLANE_ALIGNMENT_HORIZONTAL_DOWNWARD_EXT, 1) \ + _(XR_SPATIAL_PLANE_ALIGNMENT_VERTICAL_EXT, 2) \ + _(XR_SPATIAL_PLANE_ALIGNMENT_ARBITRARY_EXT, 3) \ + _(XR_SPATIAL_PLANE_ALIGNMENT_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialPlaneSemanticLabelEXT(_) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_UNCATEGORIZED_EXT, 1) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_FLOOR_EXT, 2) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_WALL_EXT, 3) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_CEILING_EXT, 4) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_TABLE_EXT, 5) \ + _(XR_SPATIAL_PLANE_SEMANTIC_LABEL_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialMarkerArucoDictEXT(_) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT, 1) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT, 2) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT, 3) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT, 4) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT, 5) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT, 6) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT, 7) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT, 8) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT, 9) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT, 10) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT, 11) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT, 12) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT, 13) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT, 14) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT, 15) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT, 16) \ + _(XR_SPATIAL_MARKER_ARUCO_DICT_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialMarkerAprilTagDictEXT(_) \ + _(XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT, 1) \ + _(XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT, 2) \ + _(XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT, 3) \ + _(XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT, 4) \ + _(XR_SPATIAL_MARKER_APRIL_TAG_DICT_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialPersistenceScopeEXT(_) \ + _(XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT, 1) \ + _(XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT, 1000781000) \ + _(XR_SPATIAL_PERSISTENCE_SCOPE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialPersistenceContextResultEXT(_) \ + _(XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT, 0) \ + _(XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT, -1000781001) \ + _(XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT, -1000781002) \ + _(XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialPersistenceStateEXT(_) \ + _(XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT, 1) \ + _(XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT, 2) \ + _(XR_SPATIAL_PERSISTENCE_STATE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrSpatialObjectSemanticLabelANDROID(_) \ + _(XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_ANDROID, 0) \ + _(XR_SPATIAL_OBJECT_SEMANTIC_LABEL_KEYBOARD_ANDROID, 1) \ + _(XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MOUSE_ANDROID, 2) \ + _(XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAPTOP_BASE_ANDROID, 3) \ + _(XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MAX_ENUM_ANDROID, 0x7FFFFFFF) + #define XR_LIST_BITS_XrInstanceCreateFlags(_) #define XR_LIST_BITS_XrSessionCreateFlags(_) @@ -1846,6 +2906,33 @@ XR_ENUM_STR(XrResult); _(XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC, 0x00000002) \ _(XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC, 0x00000004) \ +#define XR_LIST_BITS_XrSpatialMeshConfigFlagsBD(_) \ + _(XR_SPATIAL_MESH_CONFIG_SEMANTIC_BIT_BD, 0x00000001) \ + _(XR_SPATIAL_MESH_CONFIG_ALIGN_SEMANTIC_WITH_VERTEX_BIT_BD, 0x00000002) \ + +#define XR_LIST_BITS_XrSoundObstacleFlagsBD(_) \ + _(XR_SOUND_OBSTACLE_ENABLED_BIT_BD, 0x00000001) \ + _(XR_SOUND_OBSTACLE_POSE_BIT_BD, 0x00000002) \ + _(XR_SOUND_OBSTACLE_MESH_BIT_BD, 0x00000004) \ + _(XR_SOUND_OBSTACLE_MATERIALS_BIT_BD, 0x00000008) \ + +#define XR_LIST_BITS_XrSoundObjectFlagsBD(_) \ + _(XR_SOUND_OBJECT_ENABLED_BIT_BD, 0x00000001) \ + _(XR_SOUND_OBJECT_POSE_BIT_BD, 0x00000002) \ + _(XR_SOUND_OBJECT_DIRECTIVITY_BIT_BD, 0x00000004) \ + _(XR_SOUND_OBJECT_SHAPE_BIT_BD, 0x00000008) \ + _(XR_SOUND_OBJECT_MAIN_VOLUME_BIT_BD, 0x00000010) \ + _(XR_SOUND_OBJECT_REFLECTION_GAIN_BIT_BD, 0x00000020) \ + _(XR_SOUND_OBJECT_ENABLE_DOPPLER_BIT_BD, 0x00000040) \ + _(XR_SOUND_OBJECT_DIRECT_SOUND_ATTENUATION_BIT_BD, 0x00000080) \ + _(XR_SOUND_OBJECT_INDIRECT_SOUND_ATTENUATION_BIT_BD, 0x00000100) \ + +#define XR_LIST_BITS_XrSoundFieldFlagsBD(_) \ + _(XR_SOUND_FIELD_ENABLED_BIT_BD, 0x00000001) \ + _(XR_SOUND_FIELD_ORIENTATION_BIT_BD, 0x00000002) \ + _(XR_SOUND_FIELD_MAIN_VOLUME_BIT_BD, 0x00000004) \ + _(XR_SOUND_FIELD_LFE_GAIN_BIT_BD, 0x00000008) \ + #define XR_LIST_BITS_XrPlaneDetectionCapabilityFlagsEXT(_) \ _(XR_PLANE_DETECTION_CAPABILITY_PLANE_DETECTION_BIT_EXT, 0x00000001) \ _(XR_PLANE_DETECTION_CAPABILITY_PLANE_HOLES_BIT_EXT, 0x00000002) \ @@ -1858,6 +2945,11 @@ XR_ENUM_STR(XrResult); #define XR_LIST_BITS_XrPlaneDetectorFlagsEXT(_) \ _(XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT, 0x00000001) \ +#define XR_LIST_BITS_XrPerformanceMetricsCounterFlagsANDROID(_) \ + _(XR_PERFORMANCE_METRICS_COUNTER_ANY_VALUE_VALID_BIT_ANDROID, 0x00000001) \ + _(XR_PERFORMANCE_METRICS_COUNTER_UINT_VALUE_VALID_BIT_ANDROID, 0x00000002) \ + _(XR_PERFORMANCE_METRICS_COUNTER_FLOAT_VALUE_VALID_BIT_ANDROID, 0x00000004) \ + #define XR_LIST_BITS_XrWorldMeshDetectorFlagsML(_) \ _(XR_WORLD_MESH_DETECTOR_POINT_CLOUD_BIT_ML, 0x00000001) \ _(XR_WORLD_MESH_DETECTOR_COMPUTE_NORMALS_BIT_ML, 0x00000002) \ @@ -1870,6 +2962,12 @@ XR_ENUM_STR(XrResult); _(XR_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_VALID_BIT_ML, 0x00000001) \ _(XR_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_TRACKED_BIT_ML, 0x00000002) \ +#define XR_LIST_BITS_XrBatteryStateDisplayStateFlagsEXT(_) \ + _(XR_BATTERY_STATE_DISPLAY_STATE_VALID_BIT_EXT, 0x00000001) \ + _(XR_BATTERY_STATE_DISPLAY_STATE_CHARGING_BIT_EXT, 0x00000002) \ + _(XR_BATTERY_STATE_DISPLAY_STATE_PLUGGED_IN_BIT_EXT, 0x00000004) \ + _(XR_BATTERY_STATE_DISPLAY_STATE_NO_BATTERY_BIT_EXT, 0x00000008) \ + /// Calls your macro with the name of each member of XrApiLayerProperties, in order. #define XR_LIST_STRUCT_XrApiLayerProperties(_) \ _(type) \ @@ -4753,6 +5851,63 @@ XR_ENUM_STR(XrResult); _(next) \ _(id) \ +/// Calls your macro with the name of each member of XrSystemSpaceDiscoveryPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemSpaceDiscoveryPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsSpaceDiscovery) \ + +/// Calls your macro with the name of each member of XrSpaceFilterBaseHeaderMETA, in order. +#define XR_LIST_STRUCT_XrSpaceFilterBaseHeaderMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpaceDiscoveryInfoMETA, in order. +#define XR_LIST_STRUCT_XrSpaceDiscoveryInfoMETA(_) \ + _(type) \ + _(next) \ + _(filterCount) \ + _(filters) \ + +/// Calls your macro with the name of each member of XrSpaceFilterUuidMETA, in order. +#define XR_LIST_STRUCT_XrSpaceFilterUuidMETA(_) \ + _(type) \ + _(next) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSpaceFilterComponentMETA, in order. +#define XR_LIST_STRUCT_XrSpaceFilterComponentMETA(_) \ + _(type) \ + _(next) \ + _(componentType) \ + +/// Calls your macro with the name of each member of XrSpaceDiscoveryResultMETA, in order. +#define XR_LIST_STRUCT_XrSpaceDiscoveryResultMETA(_) \ + _(space) \ + _(uuid) \ + +/// Calls your macro with the name of each member of XrSpaceDiscoveryResultsMETA, in order. +#define XR_LIST_STRUCT_XrSpaceDiscoveryResultsMETA(_) \ + _(type) \ + _(next) \ + _(resultCapacityInput) \ + _(resultCountOutput) \ + _(results) \ + +/// Calls your macro with the name of each member of XrEventDataSpaceDiscoveryResultsAvailableMETA, in order. +#define XR_LIST_STRUCT_XrEventDataSpaceDiscoveryResultsAvailableMETA(_) \ + _(type) \ + _(next) \ + _(requestId) \ + +/// Calls your macro with the name of each member of XrEventDataSpaceDiscoveryCompleteMETA, in order. +#define XR_LIST_STRUCT_XrEventDataSpaceDiscoveryCompleteMETA(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + /// Calls your macro with the name of each member of XrRecommendedLayerResolutionMETA, in order. #define XR_LIST_STRUCT_XrRecommendedLayerResolutionMETA(_) \ _(type) \ @@ -4767,6 +5922,42 @@ XR_ENUM_STR(XrResult); _(layer) \ _(predictedDisplayTime) \ +/// Calls your macro with the name of each member of XrSystemSpacePersistencePropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemSpacePersistencePropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsSpacePersistence) \ + +/// Calls your macro with the name of each member of XrSpacesSaveInfoMETA, in order. +#define XR_LIST_STRUCT_XrSpacesSaveInfoMETA(_) \ + _(type) \ + _(next) \ + _(spaceCount) \ + _(spaces) \ + +/// Calls your macro with the name of each member of XrEventDataSpacesSaveResultMETA, in order. +#define XR_LIST_STRUCT_XrEventDataSpacesSaveResultMETA(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + +/// Calls your macro with the name of each member of XrSpacesEraseInfoMETA, in order. +#define XR_LIST_STRUCT_XrSpacesEraseInfoMETA(_) \ + _(type) \ + _(next) \ + _(spaceCount) \ + _(spaces) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrEventDataSpacesEraseResultMETA, in order. +#define XR_LIST_STRUCT_XrEventDataSpacesEraseResultMETA(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + /// Calls your macro with the name of each member of XrPassthroughColorLutDataMETA, in order. #define XR_LIST_STRUCT_XrPassthroughColorLutDataMETA(_) \ _(bufferSize) \ @@ -4823,12 +6014,48 @@ XR_ENUM_STR(XrResult); _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrSystemPropertiesBodyTrackingFullBodyMETA, in order. +#define XR_LIST_STRUCT_XrSystemPropertiesBodyTrackingFullBodyMETA(_) \ + _(type) \ + _(next) \ + _(supportsFullBodyTracking) \ + /// Calls your macro with the name of each member of XrEventDataPassthroughLayerResumedMETA, in order. #define XR_LIST_STRUCT_XrEventDataPassthroughLayerResumedMETA(_) \ _(type) \ _(next) \ _(layer) \ +/// Calls your macro with the name of each member of XrBodyTrackingCalibrationStatusMETA, in order. +#define XR_LIST_STRUCT_XrBodyTrackingCalibrationStatusMETA(_) \ + _(type) \ + _(next) \ + _(status) \ + +/// Calls your macro with the name of each member of XrBodyTrackingCalibrationInfoMETA, in order. +#define XR_LIST_STRUCT_XrBodyTrackingCalibrationInfoMETA(_) \ + _(type) \ + _(next) \ + _(bodyHeight) \ + +/// Calls your macro with the name of each member of XrSystemPropertiesBodyTrackingCalibrationMETA, in order. +#define XR_LIST_STRUCT_XrSystemPropertiesBodyTrackingCalibrationMETA(_) \ + _(type) \ + _(next) \ + _(supportsHeightOverride) \ + +/// Calls your macro with the name of each member of XrSystemPropertiesBodyTrackingFidelityMETA, in order. +#define XR_LIST_STRUCT_XrSystemPropertiesBodyTrackingFidelityMETA(_) \ + _(type) \ + _(next) \ + _(supportsBodyTrackingFidelity) \ + +/// Calls your macro with the name of each member of XrBodyTrackingFidelityStatusMETA, in order. +#define XR_LIST_STRUCT_XrBodyTrackingFidelityStatusMETA(_) \ + _(type) \ + _(next) \ + _(fidelity) \ + /// Calls your macro with the name of each member of XrSystemFaceTrackingProperties2FB, in order. #define XR_LIST_STRUCT_XrSystemFaceTrackingProperties2FB(_) \ _(type) \ @@ -4931,6 +6158,12 @@ XR_ENUM_STR(XrResult); _(farZ) \ _(views) \ +/// Calls your macro with the name of each member of XrEnvironmentDepthImageTimestampMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentDepthImageTimestampMETA(_) \ + _(type) \ + _(next) \ + _(captureTime) \ + /// Calls your macro with the name of each member of XrEnvironmentDepthHandRemovalSetInfoMETA, in order. #define XR_LIST_STRUCT_XrEnvironmentDepthHandRemovalSetInfoMETA(_) \ _(type) \ @@ -4944,6 +6177,113 @@ XR_ENUM_STR(XrResult); _(supportsEnvironmentDepth) \ _(supportsHandRemoval) \ +/// Calls your macro with the name of each member of XrRenderModelCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(renderModelId) \ + _(gltfExtensionCount) \ + _(gltfExtensions) \ + +/// Calls your macro with the name of each member of XrRenderModelPropertiesGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelPropertiesGetInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrRenderModelPropertiesEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelPropertiesEXT(_) \ + _(type) \ + _(next) \ + _(cacheId) \ + _(animatableNodeCount) \ + +/// Calls your macro with the name of each member of XrRenderModelSpaceCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelSpaceCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(renderModel) \ + +/// Calls your macro with the name of each member of XrRenderModelStateGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelStateGetInfoEXT(_) \ + _(type) \ + _(next) \ + _(displayTime) \ + +/// Calls your macro with the name of each member of XrRenderModelNodeStateEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelNodeStateEXT(_) \ + _(nodePose) \ + _(isVisible) \ + +/// Calls your macro with the name of each member of XrRenderModelStateEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelStateEXT(_) \ + _(type) \ + _(next) \ + _(nodeStateCount) \ + _(nodeStates) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(cacheId) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetDataGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetDataGetInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetDataEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetDataEXT(_) \ + _(type) \ + _(next) \ + _(bufferCapacityInput) \ + _(bufferCountOutput) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetPropertiesGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetPropertiesGetInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetNodePropertiesEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetNodePropertiesEXT(_) \ + _(uniqueName) \ + +/// Calls your macro with the name of each member of XrRenderModelAssetPropertiesEXT, in order. +#define XR_LIST_STRUCT_XrRenderModelAssetPropertiesEXT(_) \ + _(type) \ + _(next) \ + _(nodePropertyCount) \ + _(nodeProperties) \ + +/// Calls your macro with the name of each member of XrInteractionRenderModelIdsEnumerateInfoEXT, in order. +#define XR_LIST_STRUCT_XrInteractionRenderModelIdsEnumerateInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrInteractionRenderModelSubactionPathInfoEXT, in order. +#define XR_LIST_STRUCT_XrInteractionRenderModelSubactionPathInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrInteractionRenderModelTopLevelUserPathGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrInteractionRenderModelTopLevelUserPathGetInfoEXT(_) \ + _(type) \ + _(next) \ + _(topLevelUserPathCount) \ + _(topLevelUserPaths) \ + +/// Calls your macro with the name of each member of XrEventDataInteractionRenderModelsChangedEXT, in order. +#define XR_LIST_STRUCT_XrEventDataInteractionRenderModelsChangedEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrHandGestureQCOM, in order. +#define XR_LIST_STRUCT_XrHandGestureQCOM(_) \ + _(gesture) \ + _(gestureRatio) \ + _(flipRatio) \ + /// Calls your macro with the name of each member of XrPassthroughCreateInfoHTC, in order. #define XR_LIST_STRUCT_XrPassthroughCreateInfoHTC(_) \ _(type) \ @@ -5130,6 +6470,428 @@ XR_ENUM_STR(XrResult); _(jointLocationCount) \ _(jointLocations) \ +/// Calls your macro with the name of each member of XrSystemFacialSimulationPropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemFacialSimulationPropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsFaceTracking) \ + +/// Calls your macro with the name of each member of XrFaceTrackerCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrFaceTrackerCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(mode) \ + +/// Calls your macro with the name of each member of XrFacialSimulationDataGetInfoBD, in order. +#define XR_LIST_STRUCT_XrFacialSimulationDataGetInfoBD(_) \ + _(type) \ + _(next) \ + _(time) \ + +/// Calls your macro with the name of each member of XrFacialSimulationDataBD, in order. +#define XR_LIST_STRUCT_XrFacialSimulationDataBD(_) \ + _(type) \ + _(next) \ + _(faceExpressionWeightCount) \ + _(faceExpressionWeights) \ + _(isUpperFaceDataValid) \ + _(isLowerFaceDataValid) \ + _(time) \ + +/// Calls your macro with the name of each member of XrLipExpressionDataBD, in order. +#define XR_LIST_STRUCT_XrLipExpressionDataBD(_) \ + _(type) \ + _(next) \ + _(lipsyncExpressionWeightCount) \ + _(lipsyncExpressionWeights) \ + +/// Calls your macro with the name of each member of XrSystemSpatialSensingPropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialSensingPropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialSensing) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentGetInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentGetInfoBD(_) \ + _(type) \ + _(next) \ + _(entityId) \ + _(componentType) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataBaseHeaderBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataBaseHeaderBD(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialEntityLocationGetInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityLocationGetInfoBD(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataLocationBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataLocationBD(_) \ + _(type) \ + _(next) \ + _(location) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataSemanticBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataSemanticBD(_) \ + _(type) \ + _(next) \ + _(labelCapacityInput) \ + _(labelCountOutput) \ + _(labels) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataBoundingBox2DBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataBoundingBox2DBD(_) \ + _(type) \ + _(next) \ + _(boundingBox2D) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataPolygonBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataPolygonBD(_) \ + _(type) \ + _(next) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertices) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataBoundingBox3DBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataBoundingBox3DBD(_) \ + _(type) \ + _(next) \ + _(boundingBox3D) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataTriangleMeshBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataTriangleMeshBD(_) \ + _(type) \ + _(next) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertices) \ + _(indexCapacityInput) \ + _(indexCountOutput) \ + _(indices) \ + +/// Calls your macro with the name of each member of XrSenseDataProviderCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrSenseDataProviderCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(providerType) \ + +/// Calls your macro with the name of each member of XrSenseDataProviderStartInfoBD, in order. +#define XR_LIST_STRUCT_XrSenseDataProviderStartInfoBD(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrEventDataSenseDataProviderStateChangedBD, in order. +#define XR_LIST_STRUCT_XrEventDataSenseDataProviderStateChangedBD(_) \ + _(type) \ + _(next) \ + _(provider) \ + _(newState) \ + +/// Calls your macro with the name of each member of XrEventDataSenseDataUpdatedBD, in order. +#define XR_LIST_STRUCT_XrEventDataSenseDataUpdatedBD(_) \ + _(type) \ + _(next) \ + _(provider) \ + +/// Calls your macro with the name of each member of XrSenseDataQueryInfoBD, in order. +#define XR_LIST_STRUCT_XrSenseDataQueryInfoBD(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSenseDataQueryCompletionBD, in order. +#define XR_LIST_STRUCT_XrSenseDataQueryCompletionBD(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(snapshot) \ + +/// Calls your macro with the name of each member of XrQueriedSenseDataGetInfoBD, in order. +#define XR_LIST_STRUCT_XrQueriedSenseDataGetInfoBD(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialEntityStateBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityStateBD(_) \ + _(type) \ + _(next) \ + _(entityId) \ + _(lastUpdateTime) \ + _(uuid) \ + +/// Calls your macro with the name of each member of XrQueriedSenseDataBD, in order. +#define XR_LIST_STRUCT_XrQueriedSenseDataBD(_) \ + _(type) \ + _(next) \ + _(stateCapacityInput) \ + _(stateCountOutput) \ + _(states) \ + +/// Calls your macro with the name of each member of XrSenseDataFilterUuidBD, in order. +#define XR_LIST_STRUCT_XrSenseDataFilterUuidBD(_) \ + _(type) \ + _(next) \ + _(uuidCount) \ + _(uuids) \ + +/// Calls your macro with the name of each member of XrSenseDataFilterSemanticBD, in order. +#define XR_LIST_STRUCT_XrSenseDataFilterSemanticBD(_) \ + _(type) \ + _(next) \ + _(labelCount) \ + _(labels) \ + +/// Calls your macro with the name of each member of XrSpatialEntityAnchorCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityAnchorCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(snapshot) \ + _(entityId) \ + +/// Calls your macro with the name of each member of XrAnchorSpaceCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrAnchorSpaceCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(anchor) \ + _(poseInAnchorSpace) \ + +/// Calls your macro with the name of each member of XrFutureCompletionEXT, in order. +#define XR_LIST_STRUCT_XrFutureCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + +/// Calls your macro with the name of each member of XrSystemSpatialAnchorPropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialAnchorPropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialAnchor) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(space) \ + _(pose) \ + _(time) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorCreateCompletionBD, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorCreateCompletionBD(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(uuid) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorPersistInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorPersistInfoBD(_) \ + _(type) \ + _(next) \ + _(location) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorUnpersistInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorUnpersistInfoBD(_) \ + _(type) \ + _(next) \ + _(location) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrSystemSpatialAnchorSharingPropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialAnchorSharingPropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialAnchorSharing) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorShareInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorShareInfoBD(_) \ + _(type) \ + _(next) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrSharedSpatialAnchorDownloadInfoBD, in order. +#define XR_LIST_STRUCT_XrSharedSpatialAnchorDownloadInfoBD(_) \ + _(type) \ + _(next) \ + _(uuid) \ + +/// Calls your macro with the name of each member of XrSystemSpatialScenePropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialScenePropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialScene) \ + +/// Calls your macro with the name of each member of XrSceneCaptureInfoBD, in order. +#define XR_LIST_STRUCT_XrSceneCaptureInfoBD(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSystemSpatialMeshPropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialMeshPropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialMesh) \ + +/// Calls your macro with the name of each member of XrSenseDataProviderCreateInfoSpatialMeshBD, in order. +#define XR_LIST_STRUCT_XrSenseDataProviderCreateInfoSpatialMeshBD(_) \ + _(type) \ + _(next) \ + _(configFlags) \ + _(lod) \ + +/// Calls your macro with the name of each member of XrFuturePollResultProgressBD, in order. +#define XR_LIST_STRUCT_XrFuturePollResultProgressBD(_) \ + _(type) \ + _(next) \ + _(isSupported) \ + _(progressPercentage) \ + +/// Calls your macro with the name of each member of XrSystemSpatialPlanePropertiesBD, in order. +#define XR_LIST_STRUCT_XrSystemSpatialPlanePropertiesBD(_) \ + _(type) \ + _(next) \ + _(supportsSpatialPlane) \ + +/// Calls your macro with the name of each member of XrSpatialEntityComponentDataPlaneOrientationBD, in order. +#define XR_LIST_STRUCT_XrSpatialEntityComponentDataPlaneOrientationBD(_) \ + _(type) \ + _(next) \ + _(orientation) \ + +/// Calls your macro with the name of each member of XrSenseDataFilterPlaneOrientationBD, in order. +#define XR_LIST_STRUCT_XrSenseDataFilterPlaneOrientationBD(_) \ + _(type) \ + _(next) \ + _(orientationCount) \ + _(orientations) \ + +/// Calls your macro with the name of each member of XrSpatialAudioRendererCreateInfoBD, in order. +#define XR_LIST_STRUCT_XrSpatialAudioRendererCreateInfoBD(_) \ + _(type) \ + _(next) \ + _(framesPerBuffer) \ + _(sampleRate) \ + +/// Calls your macro with the name of each member of XrAudioBufferBD, in order. +#define XR_LIST_STRUCT_XrAudioBufferBD(_) \ + _(type) \ + _(next) \ + _(channelLayout) \ + _(bufferChannels) \ + _(bufferLength) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrSoundObjectDirectivityCardioidBD, in order. +#define XR_LIST_STRUCT_XrSoundObjectDirectivityCardioidBD(_) \ + _(type) \ + _(next) \ + _(alpha) \ + _(order) \ + +/// Calls your macro with the name of each member of XrSoundObjectShapeSphereBD, in order. +#define XR_LIST_STRUCT_XrSoundObjectShapeSphereBD(_) \ + _(type) \ + _(next) \ + _(radius) \ + +/// Calls your macro with the name of each member of XrAttenuationCurvePointBD, in order. +#define XR_LIST_STRUCT_XrAttenuationCurvePointBD(_) \ + _(distance) \ + _(gain) \ + +/// Calls your macro with the name of each member of XrSoundObjectDistanceAttenuationCurveBD, in order. +#define XR_LIST_STRUCT_XrSoundObjectDistanceAttenuationCurveBD(_) \ + _(type) \ + _(next) \ + _(curvePointCount) \ + _(curvePoints) \ + +/// Calls your macro with the name of each member of XrSoundObjectDistanceAttenuationBD, in order. +#define XR_LIST_STRUCT_XrSoundObjectDistanceAttenuationBD(_) \ + _(type) \ + _(next) \ + _(distanceAttenuationType) \ + _(minAttenuationRange) \ + _(maxAttenuationRange) \ + _(referenceDistance) \ + _(rolloffFactor) \ + _(customDistanceAttenuationCurve) \ + +/// Calls your macro with the name of each member of XrSoundObjectConfigBD, in order. +#define XR_LIST_STRUCT_XrSoundObjectConfigBD(_) \ + _(type) \ + _(next) \ + _(enabled) \ + _(pose) \ + _(baseSpace) \ + _(mainVolume) \ + _(reflectionGain) \ + _(enableDoppler) \ + _(directSoundAttenuation) \ + _(indirectSoundAttenuation) \ + +/// Calls your macro with the name of each member of XrSoundFieldConfigBD, in order. +#define XR_LIST_STRUCT_XrSoundFieldConfigBD(_) \ + _(type) \ + _(next) \ + _(enabled) \ + _(orientation) \ + _(baseSpace) \ + _(mainVolume) \ + _(lfeGain) \ + +/// Calls your macro with the name of each member of XrSoundFieldChannelDefinitionSurroundBD, in order. +#define XR_LIST_STRUCT_XrSoundFieldChannelDefinitionSurroundBD(_) \ + _(type) \ + _(next) \ + _(channelMask) \ + +/// Calls your macro with the name of each member of XrSoundFieldChannelDefinitionAmbixBD, in order. +#define XR_LIST_STRUCT_XrSoundFieldChannelDefinitionAmbixBD(_) \ + _(type) \ + _(next) \ + _(channelMask) \ + +/// Calls your macro with the name of each member of XrSoundFieldChannelDefinitionFumaBD, in order. +#define XR_LIST_STRUCT_XrSoundFieldChannelDefinitionFumaBD(_) \ + _(type) \ + _(next) \ + _(channelMask) \ + +/// Calls your macro with the name of each member of XrSoundTriangleMeshBD, in order. +#define XR_LIST_STRUCT_XrSoundTriangleMeshBD(_) \ + _(type) \ + _(next) \ + _(vertexCount) \ + _(vertices) \ + _(indexCount) \ + _(indices) \ + +/// Calls your macro with the name of each member of XrSoundObstacleConfigBD, in order. +#define XR_LIST_STRUCT_XrSoundObstacleConfigBD(_) \ + _(type) \ + _(next) \ + _(enabled) \ + _(pose) \ + _(baseSpace) \ + _(materialCount) \ + _(materials) \ + +/// Calls your macro with the name of each member of XrSoundObstacleMaterialConfigBD, in order. +#define XR_LIST_STRUCT_XrSoundObstacleMaterialConfigBD(_) \ + _(type) \ + _(next) \ + _(materialType) \ + _(bandCount) \ + _(bandFrequencies) \ + _(bandAbsorptions) \ + _(bandScatterings) \ + _(bandTransmissions) \ + /// Calls your macro with the name of each member of XrHandTrackingDataSourceInfoEXT, in order. #define XR_LIST_STRUCT_XrHandTrackingDataSourceInfoEXT(_) \ _(type) \ @@ -5206,6 +6968,245 @@ XR_ENUM_STR(XrResult); _(vertexCountOutput) \ _(vertices) \ +/// Calls your macro with the name of each member of XrTrackableTrackerCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableTrackerCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(trackableType) \ + +/// Calls your macro with the name of each member of XrTrackableGetInfoANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableGetInfoANDROID(_) \ + _(type) \ + _(next) \ + _(trackable) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrTrackablePlaneANDROID, in order. +#define XR_LIST_STRUCT_XrTrackablePlaneANDROID(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + _(centerPose) \ + _(extents) \ + _(planeType) \ + _(planeLabel) \ + _(subsumedByPlane) \ + _(lastUpdatedTime) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertices) \ + +/// Calls your macro with the name of each member of XrAnchorSpaceCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrAnchorSpaceCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(space) \ + _(time) \ + _(pose) \ + _(trackable) \ + +/// Calls your macro with the name of each member of XrSystemTrackablesPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemTrackablesPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsAnchor) \ + _(maxAnchors) \ + +/// Calls your macro with the name of each member of XrSystemEyeTrackingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemEyeTrackingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsEyeTracking) \ + +/// Calls your macro with the name of each member of XrEyeANDROID, in order. +#define XR_LIST_STRUCT_XrEyeANDROID(_) \ + _(eyeState) \ + _(eyePose) \ + +/// Calls your macro with the name of each member of XrEyesANDROID, in order. +#define XR_LIST_STRUCT_XrEyesANDROID(_) \ + _(type) \ + _(next) \ + _(eyes) \ + _(mode) \ + +/// Calls your macro with the name of each member of XrEyesGetInfoANDROID, in order. +#define XR_LIST_STRUCT_XrEyesGetInfoANDROID(_) \ + _(type) \ + _(next) \ + _(time) \ + _(baseSpace) \ + +/// Calls your macro with the name of each member of XrEyeTrackerCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrEyeTrackerCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrDeviceAnchorPersistenceCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrDeviceAnchorPersistenceCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrPersistedAnchorSpaceCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrPersistedAnchorSpaceCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(anchorId) \ + +/// Calls your macro with the name of each member of XrPersistedAnchorSpaceInfoANDROID, in order. +#define XR_LIST_STRUCT_XrPersistedAnchorSpaceInfoANDROID(_) \ + _(type) \ + _(next) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrSystemDeviceAnchorPersistencePropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemDeviceAnchorPersistencePropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsAnchorPersistence) \ + +/// Calls your macro with the name of each member of XrFaceTrackerCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrFaceTrackerCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrFaceStateGetInfoANDROID, in order. +#define XR_LIST_STRUCT_XrFaceStateGetInfoANDROID(_) \ + _(type) \ + _(next) \ + _(time) \ + +/// Calls your macro with the name of each member of XrFaceStateANDROID, in order. +#define XR_LIST_STRUCT_XrFaceStateANDROID(_) \ + _(type) \ + _(next) \ + _(parametersCapacityInput) \ + _(parametersCountOutput) \ + _(parameters) \ + _(faceTrackingState) \ + _(sampleTime) \ + _(isValid) \ + _(regionConfidencesCapacityInput) \ + _(regionConfidencesCountOutput) \ + _(regionConfidences) \ + +/// Calls your macro with the name of each member of XrSystemFaceTrackingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemFaceTrackingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsFaceTracking) \ + +/// Calls your macro with the name of each member of XrSystemPassthroughCameraStatePropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemPassthroughCameraStatePropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsPassthroughCameraState) \ + +/// Calls your macro with the name of each member of XrPassthroughCameraStateGetInfoANDROID, in order. +#define XR_LIST_STRUCT_XrPassthroughCameraStateGetInfoANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrEventDataRecommendedResolutionChangedANDROID, in order. +#define XR_LIST_STRUCT_XrEventDataRecommendedResolutionChangedANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrPassthroughLayerCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrPassthroughLayerCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(vertexCapacity) \ + _(indexCapacity) \ + +/// Calls your macro with the name of each member of XrPassthroughLayerMeshANDROID, in order. +#define XR_LIST_STRUCT_XrPassthroughLayerMeshANDROID(_) \ + _(type) \ + _(next) \ + _(windingOrder) \ + _(vertexCount) \ + _(vertices) \ + _(indexCount) \ + _(indices) \ + +/// Calls your macro with the name of each member of XrCompositionLayerPassthroughANDROID, in order. +#define XR_LIST_STRUCT_XrCompositionLayerPassthroughANDROID(_) \ + _(type) \ + _(next) \ + _(layerFlags) \ + _(space) \ + _(pose) \ + _(scale) \ + _(opacity) \ + _(layer) \ + +/// Calls your macro with the name of each member of XrSystemPassthroughLayerPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemPassthroughLayerPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsPassthroughLayer) \ + _(maxMeshIndexCount) \ + _(maxMeshVertexCount) \ + +/// Calls your macro with the name of each member of XrRaycastInfoANDROID, in order. +#define XR_LIST_STRUCT_XrRaycastInfoANDROID(_) \ + _(type) \ + _(next) \ + _(maxResults) \ + _(trackerCount) \ + _(trackers) \ + _(origin) \ + _(trajectory) \ + _(space) \ + _(time) \ + +/// Calls your macro with the name of each member of XrRaycastHitResultANDROID, in order. +#define XR_LIST_STRUCT_XrRaycastHitResultANDROID(_) \ + _(type) \ + _(trackable) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrRaycastHitResultsANDROID, in order. +#define XR_LIST_STRUCT_XrRaycastHitResultsANDROID(_) \ + _(type) \ + _(next) \ + _(resultsCapacityInput) \ + _(resultsCountOutput) \ + _(results) \ + +/// Calls your macro with the name of each member of XrPerformanceMetricsStateANDROID, in order. +#define XR_LIST_STRUCT_XrPerformanceMetricsStateANDROID(_) \ + _(type) \ + _(next) \ + _(enabled) \ + +/// Calls your macro with the name of each member of XrPerformanceMetricsCounterANDROID, in order. +#define XR_LIST_STRUCT_XrPerformanceMetricsCounterANDROID(_) \ + _(type) \ + _(next) \ + _(counterFlags) \ + _(counterUnit) \ + _(uintValue) \ + _(floatValue) \ + +/// Calls your macro with the name of each member of XrTrackableObjectANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableObjectANDROID(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + _(centerPose) \ + _(extents) \ + _(objectLabel) \ + _(lastUpdatedTime) \ + +/// Calls your macro with the name of each member of XrTrackableObjectConfigurationANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableObjectConfigurationANDROID(_) \ + _(type) \ + _(next) \ + _(labelCount) \ + _(activeLabels) \ + /// Calls your macro with the name of each member of XrFutureCancelInfoEXT, in order. #define XR_LIST_STRUCT_XrFutureCancelInfoEXT(_) \ _(type) \ @@ -5224,12 +7225,6 @@ XR_ENUM_STR(XrResult); _(next) \ _(futureResult) \ -/// Calls your macro with the name of each member of XrFutureCompletionEXT, in order. -#define XR_LIST_STRUCT_XrFutureCompletionEXT(_) \ - _(type) \ - _(next) \ - _(futureResult) \ - /// Calls your macro with the name of each member of XrFuturePollResultEXT, in order. #define XR_LIST_STRUCT_XrFuturePollResultEXT(_) \ _(type) \ @@ -5403,6 +7398,79 @@ XR_ENUM_STR(XrResult); _(flags) \ _(time) \ +/// Calls your macro with the name of each member of XrSystemBoundaryVisibilityPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemBoundaryVisibilityPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsBoundaryVisibility) \ + +/// Calls your macro with the name of each member of XrEventDataBoundaryVisibilityChangedMETA, in order. +#define XR_LIST_STRUCT_XrEventDataBoundaryVisibilityChangedMETA(_) \ + _(type) \ + _(next) \ + _(boundaryVisibility) \ + +/// Calls your macro with the name of each member of XrSystemSimultaneousHandsAndControllersPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemSimultaneousHandsAndControllersPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsSimultaneousHandsAndControllers) \ + +/// Calls your macro with the name of each member of XrSimultaneousHandsAndControllersTrackingResumeInfoMETA, in order. +#define XR_LIST_STRUCT_XrSimultaneousHandsAndControllersTrackingResumeInfoMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSimultaneousHandsAndControllersTrackingPauseInfoMETA, in order. +#define XR_LIST_STRUCT_XrSimultaneousHandsAndControllersTrackingPauseInfoMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrFaceTrackingVisemesMETA, in order. +#define XR_LIST_STRUCT_XrFaceTrackingVisemesMETA(_) \ + _(type) \ + _(next) \ + _(isValid) \ + _(visemes) \ + +/// Calls your macro with the name of each member of XrSystemFaceTrackingVisemesPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemFaceTrackingVisemesPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsVisemes) \ + +/// Calls your macro with the name of each member of XrRoomMeshFaceMETA, in order. +#define XR_LIST_STRUCT_XrRoomMeshFaceMETA(_) \ + _(uuid) \ + _(parentUuid) \ + _(semanticLabel) \ + +/// Calls your macro with the name of each member of XrRoomMeshFaceIndicesMETA, in order. +#define XR_LIST_STRUCT_XrRoomMeshFaceIndicesMETA(_) \ + _(type) \ + _(next) \ + _(indexCapacityInput) \ + _(indexCountOutput) \ + _(indices) \ + +/// Calls your macro with the name of each member of XrSpaceRoomMeshGetInfoMETA, in order. +#define XR_LIST_STRUCT_XrSpaceRoomMeshGetInfoMETA(_) \ + _(type) \ + _(next) \ + _(recognizedSemanticLabelCount) \ + _(recognizedSemanticLabels) \ + +/// Calls your macro with the name of each member of XrRoomMeshMETA, in order. +#define XR_LIST_STRUCT_XrRoomMeshMETA(_) \ + _(type) \ + _(next) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertices) \ + _(faceCapacityInput) \ + _(faceCountOutput) \ + _(faces) \ + /// Calls your macro with the name of each member of XrColocationDiscoveryStartInfoMETA, in order. #define XR_LIST_STRUCT_XrColocationDiscoveryStartInfoMETA(_) \ _(type) \ @@ -5502,6 +7570,772 @@ XR_ENUM_STR(XrResult); _(next) \ _(groupUuid) \ +/// Calls your macro with the name of each member of XrSystemEnvironmentRaycastPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemEnvironmentRaycastPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsEnvironmentRaycast) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycasterCreateInfoMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycasterCreateInfoMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycasterCreateCompletionMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycasterCreateCompletionMETA(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(environmentRaycaster) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycastFilterBaseHeaderMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycastFilterBaseHeaderMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycastHitGetInfoMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycastHitGetInfoMETA(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(origin) \ + _(direction) \ + _(filterCount) \ + _(filters) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycastHitMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycastHitMETA(_) \ + _(type) \ + _(next) \ + _(status) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrEnvironmentRaycastFilterDistanceMETA, in order. +#define XR_LIST_STRUCT_XrEnvironmentRaycastFilterDistanceMETA(_) \ + _(type) \ + _(next) \ + _(maxDistance) \ + +/// Calls your macro with the name of each member of XrExtent3DiMETA, in order. +#define XR_LIST_STRUCT_XrExtent3DiMETA(_) \ + _(width) \ + _(height) \ + _(depth) \ + +/// Calls your macro with the name of each member of XrTilePropertiesMETA, in order. +#define XR_LIST_STRUCT_XrTilePropertiesMETA(_) \ + _(type) \ + _(next) \ + _(tileDimensions) \ + _(apronDimensions) \ + _(origin) \ + +/// Calls your macro with the name of each member of XrTilePropertiesHintMETA, in order. +#define XR_LIST_STRUCT_XrTilePropertiesHintMETA(_) \ + _(type) \ + _(next) \ + _(propertiesCount) \ + _(properties) \ + +/// Calls your macro with the name of each member of XrSystemLightEstimationPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemLightEstimationPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsLightEstimation) \ + +/// Calls your macro with the name of each member of XrLightEstimatorCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrLightEstimatorCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrLightEstimateGetInfoANDROID, in order. +#define XR_LIST_STRUCT_XrLightEstimateGetInfoANDROID(_) \ + _(type) \ + _(next) \ + _(space) \ + _(time) \ + +/// Calls your macro with the name of each member of XrLightEstimateANDROID, in order. +#define XR_LIST_STRUCT_XrLightEstimateANDROID(_) \ + _(type) \ + _(next) \ + _(state) \ + _(lastUpdatedTime) \ + +/// Calls your macro with the name of each member of XrDirectionalLightANDROID, in order. +#define XR_LIST_STRUCT_XrDirectionalLightANDROID(_) \ + _(type) \ + _(next) \ + _(state) \ + _(intensity) \ + _(direction) \ + +/// Calls your macro with the name of each member of XrAmbientLightANDROID, in order. +#define XR_LIST_STRUCT_XrAmbientLightANDROID(_) \ + _(type) \ + _(next) \ + _(state) \ + _(intensity) \ + _(colorCorrection) \ + +/// Calls your macro with the name of each member of XrSphericalHarmonicsANDROID, in order. +#define XR_LIST_STRUCT_XrSphericalHarmonicsANDROID(_) \ + _(type) \ + _(next) \ + _(state) \ + _(kind) \ + _(coefficients) \ + +/// Calls your macro with the name of each member of XrAnchorSharingInfoANDROID, in order. +#define XR_LIST_STRUCT_XrAnchorSharingInfoANDROID(_) \ + _(type) \ + _(next) \ + _(anchor) \ + +/// Calls your macro with the name of each member of XrAnchorSharingTokenANDROID, in order. +#define XR_LIST_STRUCT_XrAnchorSharingTokenANDROID(_) \ + _(type) \ + _(next) \ + _(token) \ + +/// Calls your macro with the name of each member of XrSystemAnchorSharingExportPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemAnchorSharingExportPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsAnchorSharingExport) \ + +/// Calls your macro with the name of each member of XrSystemMarkerTrackingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemMarkerTrackingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsMarkerTracking) \ + _(supportsMarkerSizeEstimation) \ + _(maxMarkerCount) \ + +/// Calls your macro with the name of each member of XrTrackableMarkerDatabaseEntryANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableMarkerDatabaseEntryANDROID(_) \ + _(id) \ + _(edgeSize) \ + +/// Calls your macro with the name of each member of XrTrackableMarkerDatabaseANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableMarkerDatabaseANDROID(_) \ + _(dictionary) \ + _(entryCount) \ + _(entries) \ + +/// Calls your macro with the name of each member of XrTrackableMarkerConfigurationANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableMarkerConfigurationANDROID(_) \ + _(type) \ + _(next) \ + _(trackingMode) \ + _(databaseCount) \ + _(databases) \ + +/// Calls your macro with the name of each member of XrTrackableMarkerANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableMarkerANDROID(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + _(lastUpdatedTime) \ + _(dictionary) \ + _(markerId) \ + _(centerPose) \ + _(extents) \ + +/// Calls your macro with the name of each member of XrSystemQrCodeTrackingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemQrCodeTrackingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsQrCodeTracking) \ + _(supportsQrCodeSizeEstimation) \ + _(maxQrCodeCount) \ + +/// Calls your macro with the name of each member of XrTrackableQrCodeConfigurationANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableQrCodeConfigurationANDROID(_) \ + _(type) \ + _(next) \ + _(trackingMode) \ + _(qrCodeEdgeSize) \ + +/// Calls your macro with the name of each member of XrTrackableQrCodeANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableQrCodeANDROID(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + _(lastUpdatedTime) \ + _(centerPose) \ + _(extents) \ + _(bufferCapacityInput) \ + _(bufferCountOutput) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrSystemImageTrackingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemImageTrackingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsImageTracking) \ + _(supportsPhysicalSizeEstimation) \ + _(maxTrackedImageCount) \ + _(maxLoadedImageCount) \ + +/// Calls your macro with the name of each member of XrTrackableImageDatabaseEntryANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableImageDatabaseEntryANDROID(_) \ + _(type) \ + _(next) \ + _(trackingMode) \ + _(physicalWidth) \ + _(imageWidth) \ + _(imageHeight) \ + _(format) \ + _(bufferSize) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrTrackableImageDatabaseCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableImageDatabaseCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(entryCount) \ + _(entries) \ + +/// Calls your macro with the name of each member of XrCreateTrackableImageDatabaseCompletionANDROID, in order. +#define XR_LIST_STRUCT_XrCreateTrackableImageDatabaseCompletionANDROID(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(database) \ + +/// Calls your macro with the name of each member of XrTrackableImageConfigurationANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableImageConfigurationANDROID(_) \ + _(type) \ + _(next) \ + _(databaseCount) \ + _(databases) \ + +/// Calls your macro with the name of each member of XrTrackableImageANDROID, in order. +#define XR_LIST_STRUCT_XrTrackableImageANDROID(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + _(lastUpdatedTime) \ + _(database) \ + _(databaseEntryIndex) \ + _(centerPose) \ + _(extents) \ + +/// Calls your macro with the name of each member of XrEventDataImageTrackingLostANDROID, in order. +#define XR_LIST_STRUCT_XrEventDataImageTrackingLostANDROID(_) \ + _(type) \ + _(next) \ + _(time) \ + +/// Calls your macro with the name of each member of XrSystemSceneMeshingPropertiesANDROID, in order. +#define XR_LIST_STRUCT_XrSystemSceneMeshingPropertiesANDROID(_) \ + _(type) \ + _(next) \ + _(supportsSceneMeshing) \ + +/// Calls your macro with the name of each member of XrSceneMeshingTrackerCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrSceneMeshingTrackerCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(semanticLabelSet) \ + _(enableNormals) \ + +/// Calls your macro with the name of each member of XrSceneMeshSnapshotCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrSceneMeshSnapshotCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(boundingBox) \ + +/// Calls your macro with the name of each member of XrSceneMeshSnapshotCreationResultANDROID, in order. +#define XR_LIST_STRUCT_XrSceneMeshSnapshotCreationResultANDROID(_) \ + _(type) \ + _(next) \ + _(snapshot) \ + _(trackingState) \ + +/// Calls your macro with the name of each member of XrSceneSubmeshStateANDROID, in order. +#define XR_LIST_STRUCT_XrSceneSubmeshStateANDROID(_) \ + _(type) \ + _(next) \ + _(submeshId) \ + _(lastUpdatedTime) \ + _(submeshPoseInBaseSpace) \ + _(bounds) \ + +/// Calls your macro with the name of each member of XrSceneSubmeshDataANDROID, in order. +#define XR_LIST_STRUCT_XrSceneSubmeshDataANDROID(_) \ + _(type) \ + _(next) \ + _(submeshId) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertexPositions) \ + _(vertexNormals) \ + _(vertexSemantics) \ + _(indexCapacityInput) \ + _(indexCountOutput) \ + _(indices) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityComponentTypesEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityComponentTypesEXT(_) \ + _(type) \ + _(next) \ + _(componentTypeCapacityInput) \ + _(componentTypeCountOutput) \ + _(componentTypes) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationBaseHeaderEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationBaseHeaderEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialContextCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialContextCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(capabilityConfigCount) \ + _(capabilityConfigs) \ + +/// Calls your macro with the name of each member of XrCreateSpatialContextCompletionEXT, in order. +#define XR_LIST_STRUCT_XrCreateSpatialContextCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(spatialContext) \ + +/// Calls your macro with the name of each member of XrSpatialDiscoverySnapshotCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialDiscoverySnapshotCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(componentTypeCount) \ + _(componentTypes) \ + +/// Calls your macro with the name of each member of XrCreateSpatialDiscoverySnapshotCompletionInfoEXT, in order. +#define XR_LIST_STRUCT_XrCreateSpatialDiscoverySnapshotCompletionInfoEXT(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(future) \ + +/// Calls your macro with the name of each member of XrCreateSpatialDiscoverySnapshotCompletionEXT, in order. +#define XR_LIST_STRUCT_XrCreateSpatialDiscoverySnapshotCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(snapshot) \ + +/// Calls your macro with the name of each member of XrSpatialComponentDataQueryConditionEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentDataQueryConditionEXT(_) \ + _(type) \ + _(next) \ + _(componentTypeCount) \ + _(componentTypes) \ + +/// Calls your macro with the name of each member of XrSpatialComponentDataQueryResultEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentDataQueryResultEXT(_) \ + _(type) \ + _(next) \ + _(entityIdCapacityInput) \ + _(entityIdCountOutput) \ + _(entityIds) \ + _(entityStateCapacityInput) \ + _(entityStateCountOutput) \ + _(entityStates) \ + +/// Calls your macro with the name of each member of XrSpatialBufferEXT, in order. +#define XR_LIST_STRUCT_XrSpatialBufferEXT(_) \ + _(bufferId) \ + _(bufferType) \ + +/// Calls your macro with the name of each member of XrSpatialBufferGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialBufferGetInfoEXT(_) \ + _(type) \ + _(next) \ + _(bufferId) \ + +/// Calls your macro with the name of each member of XrSpatialBounded2DDataEXT, in order. +#define XR_LIST_STRUCT_XrSpatialBounded2DDataEXT(_) \ + _(center) \ + _(extents) \ + +/// Calls your macro with the name of each member of XrSpatialComponentBounded2DListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentBounded2DListEXT(_) \ + _(type) \ + _(next) \ + _(boundCount) \ + _(bounds) \ + +/// Calls your macro with the name of each member of XrSpatialComponentBounded3DListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentBounded3DListEXT(_) \ + _(type) \ + _(next) \ + _(boundCount) \ + _(bounds) \ + +/// Calls your macro with the name of each member of XrSpatialComponentParentListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentParentListEXT(_) \ + _(type) \ + _(next) \ + _(parentCount) \ + _(parents) \ + +/// Calls your macro with the name of each member of XrSpatialMeshDataEXT, in order. +#define XR_LIST_STRUCT_XrSpatialMeshDataEXT(_) \ + _(origin) \ + _(vertexBuffer) \ + _(indexBuffer) \ + +/// Calls your macro with the name of each member of XrSpatialComponentMesh3DListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentMesh3DListEXT(_) \ + _(type) \ + _(next) \ + _(meshCount) \ + _(meshes) \ + +/// Calls your macro with the name of each member of XrSpatialEntityFromIdCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialEntityFromIdCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(entityId) \ + +/// Calls your macro with the name of each member of XrSpatialUpdateSnapshotCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialUpdateSnapshotCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(entityCount) \ + _(entities) \ + _(componentTypeCount) \ + _(componentTypes) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrEventDataSpatialDiscoveryRecommendedEXT, in order. +#define XR_LIST_STRUCT_XrEventDataSpatialDiscoveryRecommendedEXT(_) \ + _(type) \ + _(next) \ + _(spatialContext) \ + +/// Calls your macro with the name of each member of XrSpatialFilterTrackingStateEXT, in order. +#define XR_LIST_STRUCT_XrSpatialFilterTrackingStateEXT(_) \ + _(type) \ + _(next) \ + _(trackingState) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationPlaneTrackingEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationPlaneTrackingEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialComponentPlaneAlignmentListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentPlaneAlignmentListEXT(_) \ + _(type) \ + _(next) \ + _(planeAlignmentCount) \ + _(planeAlignments) \ + +/// Calls your macro with the name of each member of XrSpatialComponentMesh2DListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentMesh2DListEXT(_) \ + _(type) \ + _(next) \ + _(meshCount) \ + _(meshes) \ + +/// Calls your macro with the name of each member of XrSpatialPolygon2DDataEXT, in order. +#define XR_LIST_STRUCT_XrSpatialPolygon2DDataEXT(_) \ + _(origin) \ + _(vertexBuffer) \ + +/// Calls your macro with the name of each member of XrSpatialComponentPolygon2DListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentPolygon2DListEXT(_) \ + _(type) \ + _(next) \ + _(polygonCount) \ + _(polygons) \ + +/// Calls your macro with the name of each member of XrSpatialComponentPlaneSemanticLabelListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentPlaneSemanticLabelListEXT(_) \ + _(type) \ + _(next) \ + _(semanticLabelCount) \ + _(semanticLabels) \ + +/// Calls your macro with the name of each member of XrStationaryReferenceSpaceGenerationIdGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrStationaryReferenceSpaceGenerationIdGetInfoEXT(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrStationaryReferenceSpaceGenerationIdResultEXT, in order. +#define XR_LIST_STRUCT_XrStationaryReferenceSpaceGenerationIdResultEXT(_) \ + _(type) \ + _(next) \ + _(generationId) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationQrCodeEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationQrCodeEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationMicroQrCodeEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationMicroQrCodeEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationArucoMarkerEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationArucoMarkerEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + _(arUcoDict) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationAprilTagEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationAprilTagEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + _(aprilDict) \ + +/// Calls your macro with the name of each member of XrSpatialMarkerSizeEXT, in order. +#define XR_LIST_STRUCT_XrSpatialMarkerSizeEXT(_) \ + _(type) \ + _(next) \ + _(markerSideLength) \ + +/// Calls your macro with the name of each member of XrSpatialMarkerStaticOptimizationEXT, in order. +#define XR_LIST_STRUCT_XrSpatialMarkerStaticOptimizationEXT(_) \ + _(type) \ + _(next) \ + _(optimizeForStaticMarker) \ + +/// Calls your macro with the name of each member of XrSpatialMarkerDataEXT, in order. +#define XR_LIST_STRUCT_XrSpatialMarkerDataEXT(_) \ + _(capability) \ + _(markerId) \ + _(data) \ + +/// Calls your macro with the name of each member of XrSpatialComponentMarkerListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentMarkerListEXT(_) \ + _(type) \ + _(next) \ + _(markerCount) \ + _(markers) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationAnchorEXT, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationAnchorEXT(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialComponentAnchorListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentAnchorListEXT(_) \ + _(type) \ + _(next) \ + _(locationCount) \ + _(locations) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrSpatialPersistenceContextCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialPersistenceContextCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(scope) \ + +/// Calls your macro with the name of each member of XrCreateSpatialPersistenceContextCompletionEXT, in order. +#define XR_LIST_STRUCT_XrCreateSpatialPersistenceContextCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(createResult) \ + _(persistenceContext) \ + +/// Calls your macro with the name of each member of XrSpatialContextPersistenceConfigEXT, in order. +#define XR_LIST_STRUCT_XrSpatialContextPersistenceConfigEXT(_) \ + _(type) \ + _(next) \ + _(persistenceContextCount) \ + _(persistenceContexts) \ + +/// Calls your macro with the name of each member of XrSpatialDiscoveryPersistenceUuidFilterEXT, in order. +#define XR_LIST_STRUCT_XrSpatialDiscoveryPersistenceUuidFilterEXT(_) \ + _(type) \ + _(next) \ + _(persistedUuidCount) \ + _(persistedUuids) \ + +/// Calls your macro with the name of each member of XrSpatialPersistenceDataEXT, in order. +#define XR_LIST_STRUCT_XrSpatialPersistenceDataEXT(_) \ + _(persistUuid) \ + _(persistState) \ + +/// Calls your macro with the name of each member of XrSpatialComponentPersistenceListEXT, in order. +#define XR_LIST_STRUCT_XrSpatialComponentPersistenceListEXT(_) \ + _(type) \ + _(next) \ + _(persistDataCount) \ + _(persistData) \ + +/// Calls your macro with the name of each member of XrSpatialEntityPersistInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialEntityPersistInfoEXT(_) \ + _(type) \ + _(next) \ + _(spatialContext) \ + _(spatialEntityId) \ + +/// Calls your macro with the name of each member of XrPersistSpatialEntityCompletionEXT, in order. +#define XR_LIST_STRUCT_XrPersistSpatialEntityCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(persistResult) \ + _(persistUuid) \ + +/// Calls your macro with the name of each member of XrSpatialEntityUnpersistInfoEXT, in order. +#define XR_LIST_STRUCT_XrSpatialEntityUnpersistInfoEXT(_) \ + _(type) \ + _(next) \ + _(persistUuid) \ + +/// Calls your macro with the name of each member of XrUnpersistSpatialEntityCompletionEXT, in order. +#define XR_LIST_STRUCT_XrUnpersistSpatialEntityCompletionEXT(_) \ + _(type) \ + _(next) \ + _(futureResult) \ + _(unpersistResult) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationObjectTrackingANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationObjectTrackingANDROID(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + _(activeSemanticLabelCount) \ + _(activeSemanticLabels) \ + +/// Calls your macro with the name of each member of XrSpatialComponentObjectSemanticLabelListANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialComponentObjectSemanticLabelListANDROID(_) \ + _(type) \ + _(next) \ + _(semanticLabelCount) \ + _(semanticLabels) \ + +/// Calls your macro with the name of each member of XrSpatialRaycastResultDataANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialRaycastResultDataANDROID(_) \ + _(hitPose) \ + _(distanceSquared) \ + +/// Calls your macro with the name of each member of XrSpatialCapabilityConfigurationDepthRaycastANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialCapabilityConfigurationDepthRaycastANDROID(_) \ + _(type) \ + _(next) \ + _(capability) \ + _(enabledComponentCount) \ + _(enabledComponents) \ + +/// Calls your macro with the name of each member of XrSpatialRaycastInfoANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialRaycastInfoANDROID(_) \ + _(type) \ + _(next) \ + _(space) \ + _(time) \ + _(origin) \ + _(direction) \ + _(maxDistance) \ + +/// Calls your macro with the name of each member of XrSpatialComponentRaycastResultListANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialComponentRaycastResultListANDROID(_) \ + _(type) \ + _(next) \ + _(raycastResultCount) \ + _(raycastResults) \ + +/// Calls your macro with the name of each member of XrSpatialRaycastSnapshotCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialRaycastSnapshotCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(componentTypeCount) \ + _(componentTypes) \ + _(raycastInfo) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorParentANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorParentANDROID(_) \ + _(type) \ + _(next) \ + _(parentId) \ + +/// Calls your macro with the name of each member of XrSpatialDiscoveryUniqueEntitiesFilterANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialDiscoveryUniqueEntitiesFilterANDROID(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrSpatialComponentSubsumedByListANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialComponentSubsumedByListANDROID(_) \ + _(type) \ + _(next) \ + _(subsumedUniqueIdCount) \ + _(subsumedUniqueIds) \ + +/// Calls your macro with the name of each member of XrSpatialAnchorSpaceFromIdCreateInfoANDROID, in order. +#define XR_LIST_STRUCT_XrSpatialAnchorSpaceFromIdCreateInfoANDROID(_) \ + _(type) \ + _(next) \ + _(anchorEntityId) \ + +/// Calls your macro with the name of each member of XrBatteryStateDisplayEXT, in order. +#define XR_LIST_STRUCT_XrBatteryStateDisplayEXT(_) \ + _(type) \ + _(next) \ + _(stateFlags) \ + _(batteryLevel) \ + +/// Calls your macro with the name of each member of XrLoaderInitPropertyValueEXT, in order. +#define XR_LIST_STRUCT_XrLoaderInitPropertyValueEXT(_) \ + _(name) \ + _(value) \ + +/// Calls your macro with the name of each member of XrLoaderInitInfoPropertiesEXT, in order. +#define XR_LIST_STRUCT_XrLoaderInitInfoPropertiesEXT(_) \ + _(type) \ + _(next) \ + _(propertyValueCount) \ + _(propertyValues) \ + +/// Calls your macro with the name of each member of XrEventDataViewConfigurationViewsChangedEXT, in order. +#define XR_LIST_STRUCT_XrEventDataViewConfigurationViewsChangedEXT(_) \ + _(type) \ + _(next) \ + _(systemId) \ + _(viewConfigurationType) \ + /// Calls your macro with the structure type name and the XrStructureType constant for @@ -5813,8 +8647,20 @@ XR_ENUM_STR(XrResult); _(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ _(XrSpaceUserCreateInfoFB, XR_TYPE_SPACE_USER_CREATE_INFO_FB) \ _(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _(XrSystemSpaceDiscoveryPropertiesMETA, XR_TYPE_SYSTEM_SPACE_DISCOVERY_PROPERTIES_META) \ + _(XrSpaceDiscoveryInfoMETA, XR_TYPE_SPACE_DISCOVERY_INFO_META) \ + _(XrSpaceFilterUuidMETA, XR_TYPE_SPACE_FILTER_UUID_META) \ + _(XrSpaceFilterComponentMETA, XR_TYPE_SPACE_FILTER_COMPONENT_META) \ + _(XrSpaceDiscoveryResultsMETA, XR_TYPE_SPACE_DISCOVERY_RESULTS_META) \ + _(XrEventDataSpaceDiscoveryResultsAvailableMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META) \ + _(XrEventDataSpaceDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META) \ _(XrRecommendedLayerResolutionMETA, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_META) \ _(XrRecommendedLayerResolutionGetInfoMETA, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_GET_INFO_META) \ + _(XrSystemSpacePersistencePropertiesMETA, XR_TYPE_SYSTEM_SPACE_PERSISTENCE_PROPERTIES_META) \ + _(XrSpacesSaveInfoMETA, XR_TYPE_SPACES_SAVE_INFO_META) \ + _(XrEventDataSpacesSaveResultMETA, XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META) \ + _(XrSpacesEraseInfoMETA, XR_TYPE_SPACES_ERASE_INFO_META) \ + _(XrEventDataSpacesEraseResultMETA, XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META) \ _(XrPassthroughColorLutCreateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META) \ _(XrPassthroughColorLutUpdateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META) \ _(XrPassthroughColorMapLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META) \ @@ -5822,7 +8668,13 @@ XR_ENUM_STR(XrResult); _(XrSystemPassthroughColorLutPropertiesMETA, XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META) \ _(XrSpaceTriangleMeshGetInfoMETA, XR_TYPE_SPACE_TRIANGLE_MESH_GET_INFO_META) \ _(XrSpaceTriangleMeshMETA, XR_TYPE_SPACE_TRIANGLE_MESH_META) \ + _(XrSystemPropertiesBodyTrackingFullBodyMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FULL_BODY_META) \ _(XrEventDataPassthroughLayerResumedMETA, XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META) \ + _(XrBodyTrackingCalibrationStatusMETA, XR_TYPE_BODY_TRACKING_CALIBRATION_STATUS_META) \ + _(XrBodyTrackingCalibrationInfoMETA, XR_TYPE_BODY_TRACKING_CALIBRATION_INFO_META) \ + _(XrSystemPropertiesBodyTrackingCalibrationMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_CALIBRATION_META) \ + _(XrSystemPropertiesBodyTrackingFidelityMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FIDELITY_META) \ + _(XrBodyTrackingFidelityStatusMETA, XR_TYPE_BODY_TRACKING_FIDELITY_STATUS_META) \ _(XrSystemFaceTrackingProperties2FB, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES2_FB) \ _(XrFaceTrackerCreateInfo2FB, XR_TYPE_FACE_TRACKER_CREATE_INFO2_FB) \ _(XrFaceExpressionInfo2FB, XR_TYPE_FACE_EXPRESSION_INFO2_FB) \ @@ -5836,8 +8688,24 @@ XR_ENUM_STR(XrResult); _(XrEnvironmentDepthImageAcquireInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_ACQUIRE_INFO_META) \ _(XrEnvironmentDepthImageViewMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_VIEW_META) \ _(XrEnvironmentDepthImageMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_META) \ + _(XrEnvironmentDepthImageTimestampMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_TIMESTAMP_META) \ _(XrEnvironmentDepthHandRemovalSetInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_HAND_REMOVAL_SET_INFO_META) \ _(XrSystemEnvironmentDepthPropertiesMETA, XR_TYPE_SYSTEM_ENVIRONMENT_DEPTH_PROPERTIES_META) \ + _(XrRenderModelCreateInfoEXT, XR_TYPE_RENDER_MODEL_CREATE_INFO_EXT) \ + _(XrRenderModelPropertiesGetInfoEXT, XR_TYPE_RENDER_MODEL_PROPERTIES_GET_INFO_EXT) \ + _(XrRenderModelPropertiesEXT, XR_TYPE_RENDER_MODEL_PROPERTIES_EXT) \ + _(XrRenderModelSpaceCreateInfoEXT, XR_TYPE_RENDER_MODEL_SPACE_CREATE_INFO_EXT) \ + _(XrRenderModelStateGetInfoEXT, XR_TYPE_RENDER_MODEL_STATE_GET_INFO_EXT) \ + _(XrRenderModelStateEXT, XR_TYPE_RENDER_MODEL_STATE_EXT) \ + _(XrRenderModelAssetCreateInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_CREATE_INFO_EXT) \ + _(XrRenderModelAssetDataGetInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_DATA_GET_INFO_EXT) \ + _(XrRenderModelAssetDataEXT, XR_TYPE_RENDER_MODEL_ASSET_DATA_EXT) \ + _(XrRenderModelAssetPropertiesGetInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_GET_INFO_EXT) \ + _(XrRenderModelAssetPropertiesEXT, XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_EXT) \ + _(XrInteractionRenderModelIdsEnumerateInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_IDS_ENUMERATE_INFO_EXT) \ + _(XrInteractionRenderModelSubactionPathInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_SUBACTION_PATH_INFO_EXT) \ + _(XrInteractionRenderModelTopLevelUserPathGetInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_TOP_LEVEL_USER_PATH_GET_INFO_EXT) \ + _(XrEventDataInteractionRenderModelsChangedEXT, XR_TYPE_EVENT_DATA_INTERACTION_RENDER_MODELS_CHANGED_EXT) \ _(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ _(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ _(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ @@ -5859,6 +8727,64 @@ XR_ENUM_STR(XrResult); _(XrBodyTrackerCreateInfoBD, XR_TYPE_BODY_TRACKER_CREATE_INFO_BD) \ _(XrBodyJointsLocateInfoBD, XR_TYPE_BODY_JOINTS_LOCATE_INFO_BD) \ _(XrBodyJointLocationsBD, XR_TYPE_BODY_JOINT_LOCATIONS_BD) \ + _(XrSystemFacialSimulationPropertiesBD, XR_TYPE_SYSTEM_FACIAL_SIMULATION_PROPERTIES_BD) \ + _(XrFaceTrackerCreateInfoBD, XR_TYPE_FACE_TRACKER_CREATE_INFO_BD) \ + _(XrFacialSimulationDataGetInfoBD, XR_TYPE_FACIAL_SIMULATION_DATA_GET_INFO_BD) \ + _(XrFacialSimulationDataBD, XR_TYPE_FACIAL_SIMULATION_DATA_BD) \ + _(XrLipExpressionDataBD, XR_TYPE_LIP_EXPRESSION_DATA_BD) \ + _(XrSystemSpatialSensingPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_SENSING_PROPERTIES_BD) \ + _(XrSpatialEntityComponentGetInfoBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_GET_INFO_BD) \ + _(XrSpatialEntityLocationGetInfoBD, XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO_BD) \ + _(XrSpatialEntityComponentDataLocationBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_LOCATION_BD) \ + _(XrSpatialEntityComponentDataSemanticBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_SEMANTIC_BD) \ + _(XrSpatialEntityComponentDataBoundingBox2DBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_2D_BD) \ + _(XrSpatialEntityComponentDataPolygonBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_POLYGON_BD) \ + _(XrSpatialEntityComponentDataBoundingBox3DBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_3D_BD) \ + _(XrSpatialEntityComponentDataTriangleMeshBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_TRIANGLE_MESH_BD) \ + _(XrSenseDataProviderCreateInfoBD, XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_BD) \ + _(XrSenseDataProviderStartInfoBD, XR_TYPE_SENSE_DATA_PROVIDER_START_INFO_BD) \ + _(XrEventDataSenseDataProviderStateChangedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED_BD) \ + _(XrEventDataSenseDataUpdatedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED_BD) \ + _(XrSenseDataQueryInfoBD, XR_TYPE_SENSE_DATA_QUERY_INFO_BD) \ + _(XrSenseDataQueryCompletionBD, XR_TYPE_SENSE_DATA_QUERY_COMPLETION_BD) \ + _(XrQueriedSenseDataGetInfoBD, XR_TYPE_QUERIED_SENSE_DATA_GET_INFO_BD) \ + _(XrSpatialEntityStateBD, XR_TYPE_SPATIAL_ENTITY_STATE_BD) \ + _(XrQueriedSenseDataBD, XR_TYPE_QUERIED_SENSE_DATA_BD) \ + _(XrSenseDataFilterUuidBD, XR_TYPE_SENSE_DATA_FILTER_UUID_BD) \ + _(XrSenseDataFilterSemanticBD, XR_TYPE_SENSE_DATA_FILTER_SEMANTIC_BD) \ + _(XrSpatialEntityAnchorCreateInfoBD, XR_TYPE_SPATIAL_ENTITY_ANCHOR_CREATE_INFO_BD) \ + _(XrAnchorSpaceCreateInfoBD, XR_TYPE_ANCHOR_SPACE_CREATE_INFO_BD) \ + _(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ + _(XrSystemSpatialAnchorPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_ANCHOR_PROPERTIES_BD) \ + _(XrSpatialAnchorCreateInfoBD, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_BD) \ + _(XrSpatialAnchorCreateCompletionBD, XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION_BD) \ + _(XrSpatialAnchorPersistInfoBD, XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO_BD) \ + _(XrSpatialAnchorUnpersistInfoBD, XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO_BD) \ + _(XrSystemSpatialAnchorSharingPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_ANCHOR_SHARING_PROPERTIES_BD) \ + _(XrSpatialAnchorShareInfoBD, XR_TYPE_SPATIAL_ANCHOR_SHARE_INFO_BD) \ + _(XrSharedSpatialAnchorDownloadInfoBD, XR_TYPE_SHARED_SPATIAL_ANCHOR_DOWNLOAD_INFO_BD) \ + _(XrSystemSpatialScenePropertiesBD, XR_TYPE_SYSTEM_SPATIAL_SCENE_PROPERTIES_BD) \ + _(XrSceneCaptureInfoBD, XR_TYPE_SCENE_CAPTURE_INFO_BD) \ + _(XrSystemSpatialMeshPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_MESH_PROPERTIES_BD) \ + _(XrSenseDataProviderCreateInfoSpatialMeshBD, XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_MESH_BD) \ + _(XrFuturePollResultProgressBD, XR_TYPE_FUTURE_POLL_RESULT_PROGRESS_BD) \ + _(XrSystemSpatialPlanePropertiesBD, XR_TYPE_SYSTEM_SPATIAL_PLANE_PROPERTIES_BD) \ + _(XrSpatialEntityComponentDataPlaneOrientationBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_PLANE_ORIENTATION_BD) \ + _(XrSenseDataFilterPlaneOrientationBD, XR_TYPE_SENSE_DATA_FILTER_PLANE_ORIENTATION_BD) \ + _(XrSpatialAudioRendererCreateInfoBD, XR_TYPE_SPATIAL_AUDIO_RENDERER_CREATE_INFO_BD) \ + _(XrAudioBufferBD, XR_TYPE_AUDIO_BUFFER_BD) \ + _(XrSoundObjectDirectivityCardioidBD, XR_TYPE_SOUND_OBJECT_DIRECTIVITY_CARDIOID_BD) \ + _(XrSoundObjectShapeSphereBD, XR_TYPE_SOUND_OBJECT_SHAPE_SPHERE_BD) \ + _(XrSoundObjectDistanceAttenuationCurveBD, XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_CURVE_BD) \ + _(XrSoundObjectDistanceAttenuationBD, XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_BD) \ + _(XrSoundObjectConfigBD, XR_TYPE_SOUND_OBJECT_CONFIG_BD) \ + _(XrSoundFieldConfigBD, XR_TYPE_SOUND_FIELD_CONFIG_BD) \ + _(XrSoundFieldChannelDefinitionSurroundBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_SURROUND_BD) \ + _(XrSoundFieldChannelDefinitionAmbixBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_AMBIX_BD) \ + _(XrSoundFieldChannelDefinitionFumaBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_FUMA_BD) \ + _(XrSoundTriangleMeshBD, XR_TYPE_SOUND_TRIANGLE_MESH_BD) \ + _(XrSoundObstacleConfigBD, XR_TYPE_SOUND_OBSTACLE_CONFIG_BD) \ + _(XrSoundObstacleMaterialConfigBD, XR_TYPE_SOUND_OBSTACLE_MATERIAL_CONFIG_BD) \ _(XrHandTrackingDataSourceInfoEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT) \ _(XrHandTrackingDataSourceStateEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT) \ _(XrSystemPlaneDetectionPropertiesEXT, XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT) \ @@ -5868,9 +8794,38 @@ XR_ENUM_STR(XrResult); _(XrPlaneDetectorLocationEXT, XR_TYPE_PLANE_DETECTOR_LOCATION_EXT) \ _(XrPlaneDetectorLocationsEXT, XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT) \ _(XrPlaneDetectorPolygonBufferEXT, XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT) \ + _(XrTrackableTrackerCreateInfoANDROID, XR_TYPE_TRACKABLE_TRACKER_CREATE_INFO_ANDROID) \ + _(XrTrackableGetInfoANDROID, XR_TYPE_TRACKABLE_GET_INFO_ANDROID) \ + _(XrTrackablePlaneANDROID, XR_TYPE_TRACKABLE_PLANE_ANDROID) \ + _(XrAnchorSpaceCreateInfoANDROID, XR_TYPE_ANCHOR_SPACE_CREATE_INFO_ANDROID) \ + _(XrSystemTrackablesPropertiesANDROID, XR_TYPE_SYSTEM_TRACKABLES_PROPERTIES_ANDROID) \ + _(XrSystemEyeTrackingPropertiesANDROID, XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_ANDROID) \ + _(XrEyesANDROID, XR_TYPE_EYES_ANDROID) \ + _(XrEyesGetInfoANDROID, XR_TYPE_EYES_GET_INFO_ANDROID) \ + _(XrEyeTrackerCreateInfoANDROID, XR_TYPE_EYE_TRACKER_CREATE_INFO_ANDROID) \ + _(XrDeviceAnchorPersistenceCreateInfoANDROID, XR_TYPE_DEVICE_ANCHOR_PERSISTENCE_CREATE_INFO_ANDROID) \ + _(XrPersistedAnchorSpaceCreateInfoANDROID, XR_TYPE_PERSISTED_ANCHOR_SPACE_CREATE_INFO_ANDROID) \ + _(XrPersistedAnchorSpaceInfoANDROID, XR_TYPE_PERSISTED_ANCHOR_SPACE_INFO_ANDROID) \ + _(XrSystemDeviceAnchorPersistencePropertiesANDROID, XR_TYPE_SYSTEM_DEVICE_ANCHOR_PERSISTENCE_PROPERTIES_ANDROID) \ + _(XrFaceTrackerCreateInfoANDROID, XR_TYPE_FACE_TRACKER_CREATE_INFO_ANDROID) \ + _(XrFaceStateGetInfoANDROID, XR_TYPE_FACE_STATE_GET_INFO_ANDROID) \ + _(XrFaceStateANDROID, XR_TYPE_FACE_STATE_ANDROID) \ + _(XrSystemFaceTrackingPropertiesANDROID, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_ANDROID) \ + _(XrSystemPassthroughCameraStatePropertiesANDROID, XR_TYPE_SYSTEM_PASSTHROUGH_CAMERA_STATE_PROPERTIES_ANDROID) \ + _(XrPassthroughCameraStateGetInfoANDROID, XR_TYPE_PASSTHROUGH_CAMERA_STATE_GET_INFO_ANDROID) \ + _(XrEventDataRecommendedResolutionChangedANDROID, XR_TYPE_EVENT_DATA_RECOMMENDED_RESOLUTION_CHANGED_ANDROID) \ + _(XrPassthroughLayerCreateInfoANDROID, XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_ANDROID) \ + _(XrPassthroughLayerMeshANDROID, XR_TYPE_PASSTHROUGH_LAYER_MESH_ANDROID) \ + _(XrCompositionLayerPassthroughANDROID, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_ANDROID) \ + _(XrSystemPassthroughLayerPropertiesANDROID, XR_TYPE_SYSTEM_PASSTHROUGH_LAYER_PROPERTIES_ANDROID) \ + _(XrRaycastInfoANDROID, XR_TYPE_RAYCAST_INFO_ANDROID) \ + _(XrRaycastHitResultsANDROID, XR_TYPE_RAYCAST_HIT_RESULTS_ANDROID) \ + _(XrPerformanceMetricsStateANDROID, XR_TYPE_PERFORMANCE_METRICS_STATE_ANDROID) \ + _(XrPerformanceMetricsCounterANDROID, XR_TYPE_PERFORMANCE_METRICS_COUNTER_ANDROID) \ + _(XrTrackableObjectANDROID, XR_TYPE_TRACKABLE_OBJECT_ANDROID) \ + _(XrTrackableObjectConfigurationANDROID, XR_TYPE_TRACKABLE_OBJECT_CONFIGURATION_ANDROID) \ _(XrFutureCancelInfoEXT, XR_TYPE_FUTURE_CANCEL_INFO_EXT) \ _(XrFuturePollInfoEXT, XR_TYPE_FUTURE_POLL_INFO_EXT) \ - _(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ _(XrFuturePollResultEXT, XR_TYPE_FUTURE_POLL_RESULT_EXT) \ _(XrEventDataUserPresenceChangedEXT, XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT) \ _(XrSystemUserPresencePropertiesEXT, XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT) \ @@ -5894,6 +8849,16 @@ XR_ENUM_STR(XrResult); _(XrFacialExpressionClientCreateInfoML, XR_TYPE_FACIAL_EXPRESSION_CLIENT_CREATE_INFO_ML) \ _(XrFacialExpressionBlendShapeGetInfoML, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_GET_INFO_ML) \ _(XrFacialExpressionBlendShapePropertiesML, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_ML) \ + _(XrSystemBoundaryVisibilityPropertiesMETA, XR_TYPE_SYSTEM_BOUNDARY_VISIBILITY_PROPERTIES_META) \ + _(XrEventDataBoundaryVisibilityChangedMETA, XR_TYPE_EVENT_DATA_BOUNDARY_VISIBILITY_CHANGED_META) \ + _(XrSystemSimultaneousHandsAndControllersPropertiesMETA, XR_TYPE_SYSTEM_SIMULTANEOUS_HANDS_AND_CONTROLLERS_PROPERTIES_META) \ + _(XrSimultaneousHandsAndControllersTrackingResumeInfoMETA, XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_RESUME_INFO_META) \ + _(XrSimultaneousHandsAndControllersTrackingPauseInfoMETA, XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_PAUSE_INFO_META) \ + _(XrFaceTrackingVisemesMETA, XR_TYPE_FACE_TRACKING_VISEMES_META) \ + _(XrSystemFaceTrackingVisemesPropertiesMETA, XR_TYPE_SYSTEM_FACE_TRACKING_VISEMES_PROPERTIES_META) \ + _(XrRoomMeshFaceIndicesMETA, XR_TYPE_ROOM_MESH_FACE_INDICES_META) \ + _(XrSpaceRoomMeshGetInfoMETA, XR_TYPE_SPACE_ROOM_MESH_GET_INFO_META) \ + _(XrRoomMeshMETA, XR_TYPE_ROOM_MESH_META) \ _(XrColocationDiscoveryStartInfoMETA, XR_TYPE_COLOCATION_DISCOVERY_START_INFO_META) \ _(XrColocationDiscoveryStopInfoMETA, XR_TYPE_COLOCATION_DISCOVERY_STOP_INFO_META) \ _(XrColocationAdvertisementStartInfoMETA, XR_TYPE_COLOCATION_ADVERTISEMENT_START_INFO_META) \ @@ -5909,6 +8874,96 @@ XR_ENUM_STR(XrResult); _(XrSystemSpatialEntityGroupSharingPropertiesMETA, XR_TYPE_SYSTEM_SPATIAL_ENTITY_GROUP_SHARING_PROPERTIES_META) \ _(XrShareSpacesRecipientGroupsMETA, XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META) \ _(XrSpaceGroupUuidFilterInfoMETA, XR_TYPE_SPACE_GROUP_UUID_FILTER_INFO_META) \ + _(XrSystemEnvironmentRaycastPropertiesMETA, XR_TYPE_SYSTEM_ENVIRONMENT_RAYCAST_PROPERTIES_META) \ + _(XrEnvironmentRaycasterCreateInfoMETA, XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_INFO_META) \ + _(XrEnvironmentRaycasterCreateCompletionMETA, XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_COMPLETION_META) \ + _(XrEnvironmentRaycastHitGetInfoMETA, XR_TYPE_ENVIRONMENT_RAYCAST_HIT_GET_INFO_META) \ + _(XrEnvironmentRaycastHitMETA, XR_TYPE_ENVIRONMENT_RAYCAST_HIT_META) \ + _(XrEnvironmentRaycastFilterDistanceMETA, XR_TYPE_ENVIRONMENT_RAYCAST_FILTER_DISTANCE_META) \ + _(XrTilePropertiesMETA, XR_TYPE_TILE_PROPERTIES_META) \ + _(XrTilePropertiesHintMETA, XR_TYPE_TILE_PROPERTIES_HINT_META) \ + _(XrSystemLightEstimationPropertiesANDROID, XR_TYPE_SYSTEM_LIGHT_ESTIMATION_PROPERTIES_ANDROID) \ + _(XrLightEstimatorCreateInfoANDROID, XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID) \ + _(XrLightEstimateGetInfoANDROID, XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID) \ + _(XrLightEstimateANDROID, XR_TYPE_LIGHT_ESTIMATE_ANDROID) \ + _(XrDirectionalLightANDROID, XR_TYPE_DIRECTIONAL_LIGHT_ANDROID) \ + _(XrAmbientLightANDROID, XR_TYPE_AMBIENT_LIGHT_ANDROID) \ + _(XrSphericalHarmonicsANDROID, XR_TYPE_SPHERICAL_HARMONICS_ANDROID) \ + _(XrSystemMarkerTrackingPropertiesANDROID, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_ANDROID) \ + _(XrTrackableMarkerConfigurationANDROID, XR_TYPE_TRACKABLE_MARKER_CONFIGURATION_ANDROID) \ + _(XrTrackableMarkerANDROID, XR_TYPE_TRACKABLE_MARKER_ANDROID) \ + _(XrSystemQrCodeTrackingPropertiesANDROID, XR_TYPE_SYSTEM_QR_CODE_TRACKING_PROPERTIES_ANDROID) \ + _(XrTrackableQrCodeConfigurationANDROID, XR_TYPE_TRACKABLE_QR_CODE_CONFIGURATION_ANDROID) \ + _(XrTrackableQrCodeANDROID, XR_TYPE_TRACKABLE_QR_CODE_ANDROID) \ + _(XrSystemImageTrackingPropertiesANDROID, XR_TYPE_SYSTEM_IMAGE_TRACKING_PROPERTIES_ANDROID) \ + _(XrTrackableImageDatabaseEntryANDROID, XR_TYPE_TRACKABLE_IMAGE_DATABASE_ENTRY_ANDROID) \ + _(XrTrackableImageDatabaseCreateInfoANDROID, XR_TYPE_TRACKABLE_IMAGE_DATABASE_CREATE_INFO_ANDROID) \ + _(XrCreateTrackableImageDatabaseCompletionANDROID, XR_TYPE_CREATE_TRACKABLE_IMAGE_DATABASE_COMPLETION_ANDROID) \ + _(XrTrackableImageConfigurationANDROID, XR_TYPE_TRACKABLE_IMAGE_CONFIGURATION_ANDROID) \ + _(XrTrackableImageANDROID, XR_TYPE_TRACKABLE_IMAGE_ANDROID) \ + _(XrEventDataImageTrackingLostANDROID, XR_TYPE_EVENT_DATA_IMAGE_TRACKING_LOST_ANDROID) \ + _(XrSystemSceneMeshingPropertiesANDROID, XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID) \ + _(XrSceneMeshingTrackerCreateInfoANDROID, XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID) \ + _(XrSceneMeshSnapshotCreateInfoANDROID, XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID) \ + _(XrSceneMeshSnapshotCreationResultANDROID, XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID) \ + _(XrSceneSubmeshStateANDROID, XR_TYPE_SCENE_SUBMESH_STATE_ANDROID) \ + _(XrSceneSubmeshDataANDROID, XR_TYPE_SCENE_SUBMESH_DATA_ANDROID) \ + _(XrSpatialCapabilityComponentTypesEXT, XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT) \ + _(XrSpatialContextCreateInfoEXT, XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT) \ + _(XrCreateSpatialContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT) \ + _(XrSpatialDiscoverySnapshotCreateInfoEXT, XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT) \ + _(XrCreateSpatialDiscoverySnapshotCompletionInfoEXT, XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT) \ + _(XrCreateSpatialDiscoverySnapshotCompletionEXT, XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT) \ + _(XrSpatialComponentDataQueryConditionEXT, XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT) \ + _(XrSpatialComponentDataQueryResultEXT, XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT) \ + _(XrSpatialBufferGetInfoEXT, XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT) \ + _(XrSpatialComponentBounded2DListEXT, XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT) \ + _(XrSpatialComponentBounded3DListEXT, XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT) \ + _(XrSpatialComponentParentListEXT, XR_TYPE_SPATIAL_COMPONENT_PARENT_LIST_EXT) \ + _(XrSpatialComponentMesh3DListEXT, XR_TYPE_SPATIAL_COMPONENT_MESH_3D_LIST_EXT) \ + _(XrSpatialEntityFromIdCreateInfoEXT, XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT) \ + _(XrSpatialUpdateSnapshotCreateInfoEXT, XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT) \ + _(XrEventDataSpatialDiscoveryRecommendedEXT, XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT) \ + _(XrSpatialFilterTrackingStateEXT, XR_TYPE_SPATIAL_FILTER_TRACKING_STATE_EXT) \ + _(XrSpatialCapabilityConfigurationPlaneTrackingEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT) \ + _(XrSpatialComponentPlaneAlignmentListEXT, XR_TYPE_SPATIAL_COMPONENT_PLANE_ALIGNMENT_LIST_EXT) \ + _(XrSpatialComponentMesh2DListEXT, XR_TYPE_SPATIAL_COMPONENT_MESH_2D_LIST_EXT) \ + _(XrSpatialComponentPolygon2DListEXT, XR_TYPE_SPATIAL_COMPONENT_POLYGON_2D_LIST_EXT) \ + _(XrSpatialComponentPlaneSemanticLabelListEXT, XR_TYPE_SPATIAL_COMPONENT_PLANE_SEMANTIC_LABEL_LIST_EXT) \ + _(XrStationaryReferenceSpaceGenerationIdGetInfoEXT, XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_GET_INFO_EXT) \ + _(XrStationaryReferenceSpaceGenerationIdResultEXT, XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_RESULT_EXT) \ + _(XrSpatialCapabilityConfigurationQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT) \ + _(XrSpatialCapabilityConfigurationMicroQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT) \ + _(XrSpatialCapabilityConfigurationArucoMarkerEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT) \ + _(XrSpatialCapabilityConfigurationAprilTagEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT) \ + _(XrSpatialMarkerSizeEXT, XR_TYPE_SPATIAL_MARKER_SIZE_EXT) \ + _(XrSpatialMarkerStaticOptimizationEXT, XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT) \ + _(XrSpatialComponentMarkerListEXT, XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT) \ + _(XrSpatialCapabilityConfigurationAnchorEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT) \ + _(XrSpatialComponentAnchorListEXT, XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT) \ + _(XrSpatialAnchorCreateInfoEXT, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT) \ + _(XrSpatialPersistenceContextCreateInfoEXT, XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT) \ + _(XrCreateSpatialPersistenceContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT) \ + _(XrSpatialContextPersistenceConfigEXT, XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT) \ + _(XrSpatialDiscoveryPersistenceUuidFilterEXT, XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT) \ + _(XrSpatialComponentPersistenceListEXT, XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT) \ + _(XrSpatialEntityPersistInfoEXT, XR_TYPE_SPATIAL_ENTITY_PERSIST_INFO_EXT) \ + _(XrPersistSpatialEntityCompletionEXT, XR_TYPE_PERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ + _(XrSpatialEntityUnpersistInfoEXT, XR_TYPE_SPATIAL_ENTITY_UNPERSIST_INFO_EXT) \ + _(XrUnpersistSpatialEntityCompletionEXT, XR_TYPE_UNPERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ + _(XrSpatialCapabilityConfigurationObjectTrackingANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID) \ + _(XrSpatialComponentObjectSemanticLabelListANDROID, XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID) \ + _(XrSpatialCapabilityConfigurationDepthRaycastANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID) \ + _(XrSpatialRaycastInfoANDROID, XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID) \ + _(XrSpatialComponentRaycastResultListANDROID, XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID) \ + _(XrSpatialRaycastSnapshotCreateInfoANDROID, XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID) \ + _(XrSpatialAnchorParentANDROID, XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID) \ + _(XrSpatialDiscoveryUniqueEntitiesFilterANDROID, XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID) \ + _(XrSpatialComponentSubsumedByListANDROID, XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID) \ + _(XrSpatialAnchorSpaceFromIdCreateInfoANDROID, XR_TYPE_SPATIAL_ANCHOR_SPACE_FROM_ID_CREATE_INFO_ANDROID) \ + _(XrBatteryStateDisplayEXT, XR_TYPE_BATTERY_STATE_DISPLAY_EXT) \ + _(XrLoaderInitInfoPropertiesEXT, XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT) \ + _(XrEventDataViewConfigurationViewsChangedEXT, XR_TYPE_EVENT_DATA_VIEW_CONFIGURATION_VIEWS_CHANGED_EXT) \ #if defined(XR_USE_GRAPHICS_API_D3D11) @@ -6047,6 +9102,9 @@ XR_ENUM_STR(XrResult); _(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ _(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ _(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + _(XrAnchorSharingInfoANDROID, XR_TYPE_ANCHOR_SHARING_INFO_ANDROID) \ + _(XrAnchorSharingTokenANDROID, XR_TYPE_ANCHOR_SHARING_TOKEN_ANDROID) \ + _(XrSystemAnchorSharingExportPropertiesANDROID, XR_TYPE_SYSTEM_ANCHOR_SHARING_EXPORT_PROPERTIES_ANDROID) \ #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) @@ -6184,6 +9242,7 @@ XR_ENUM_STR(XrResult); _(XR_ML_spatial_anchors_storage, 142) \ _(XR_MSFT_spatial_anchor_persistence, 143) \ _(XR_MSFT_scene_marker, 148) \ + _(XR_KHR_extended_struct_name_lengths, 149) \ _(XR_ULTRALEAP_hand_tracking_forearm, 150) \ _(XR_FB_spatial_entity_query, 157) \ _(XR_FB_spatial_entity_storage, 159) \ @@ -6218,20 +9277,30 @@ XR_ENUM_STR(XrResult); _(XR_META_vulkan_swapchain_create_info, 228) \ _(XR_META_performance_metrics, 233) \ _(XR_FB_spatial_entity_storage_batch, 239) \ + _(XR_META_detached_controllers, 241) \ _(XR_FB_spatial_entity_user, 242) \ _(XR_META_headset_id, 246) \ + _(XR_META_spatial_entity_discovery, 248) \ + _(XR_META_hand_tracking_microgestures, 253) \ _(XR_META_recommended_layer_resolution, 255) \ + _(XR_META_spatial_entity_persistence, 260) \ _(XR_META_passthrough_color_lut, 267) \ _(XR_META_spatial_entity_mesh, 270) \ _(XR_META_automatic_layer_filter, 272) \ + _(XR_META_body_tracking_full_body, 275) \ _(XR_META_touch_controller_plus, 280) \ _(XR_META_passthrough_layer_resumed_event, 283) \ + _(XR_META_body_tracking_calibration, 284) \ + _(XR_META_body_tracking_fidelity, 285) \ _(XR_FB_face_tracking2, 288) \ _(XR_META_spatial_entity_sharing, 291) \ _(XR_META_environment_depth, 292) \ _(XR_EXT_uuid, 300) \ + _(XR_EXT_render_model, 301) \ + _(XR_EXT_interaction_render_model, 302) \ _(XR_EXT_hand_interaction, 303) \ _(XR_QCOM_tracking_optimization_settings, 307) \ + _(XR_QCOM_hand_tracking_gesture, 311) \ _(XR_HTC_passthrough, 318) \ _(XR_HTC_foveation, 319) \ _(XR_HTC_anchor, 320) \ @@ -6240,10 +9309,31 @@ XR_ENUM_STR(XrResult); _(XR_MNDX_force_feedback_curl, 376) \ _(XR_BD_controller_interaction, 385) \ _(XR_BD_body_tracking, 386) \ + _(XR_BD_facial_simulation, 387) \ + _(XR_BD_spatial_sensing, 390) \ + _(XR_BD_spatial_anchor, 391) \ + _(XR_BD_spatial_anchor_sharing, 392) \ + _(XR_BD_spatial_scene, 393) \ + _(XR_BD_spatial_mesh, 394) \ + _(XR_BD_future_progress, 395) \ + _(XR_BD_spatial_plane, 397) \ + _(XR_BD_ultra_controller_interaction, 404) \ + _(XR_BD_spatial_audio_rendering, 410) \ _(XR_EXT_local_floor, 427) \ _(XR_EXT_hand_tracking_data_source, 429) \ _(XR_EXT_plane_detection, 430) \ _(XR_OPPO_controller_interaction, 454) \ + _(XR_ANDROID_trackables, 456) \ + _(XR_ANDROID_eye_tracking, 457) \ + _(XR_ANDROID_device_anchor_persistence, 458) \ + _(XR_ANDROID_face_tracking, 459) \ + _(XR_ANDROID_passthrough_camera_state, 461) \ + _(XR_ANDROID_recommended_resolution, 462) \ + _(XR_ANDROID_composition_layer_passthrough_mesh, 463) \ + _(XR_ANDROID_raycast, 464) \ + _(XR_ANDROID_performance_metrics, 466) \ + _(XR_ANDROID_trackables_object, 467) \ + _(XR_ANDROID_unbounded_reference_space, 468) \ _(XR_EXT_future, 470) \ _(XR_EXT_user_presence, 471) \ _(XR_KHR_locate_spaces, 472) \ @@ -6253,10 +9343,41 @@ XR_ENUM_STR(XrResult); _(XR_ML_facial_expression, 483) \ _(XR_ML_view_configuration_depth_range_change, 484) \ _(XR_YVR_controller_interaction, 498) \ + _(XR_META_boundary_visibility, 529) \ + _(XR_META_simultaneous_hands_and_controllers, 533) \ + _(XR_META_face_tracking_visemes, 542) \ + _(XR_META_spatial_entity_semantic_label, 553) \ + _(XR_META_spatial_entity_room_mesh, 554) \ _(XR_EXT_composition_layer_inverted_alpha, 555) \ _(XR_META_colocation_discovery, 572) \ _(XR_META_spatial_entity_group_sharing, 573) \ + _(XR_META_environment_raycast, 593) \ + _(XR_META_tile_properties_hint, 610) \ + _(XR_ANDROID_light_estimation, 701) \ + _(XR_ANDROID_anchor_sharing_export, 702) \ + _(XR_ANDROID_mouse_interaction, 705) \ + _(XR_ANDROID_trackables_marker, 708) \ + _(XR_ANDROID_trackables_qr_code, 709) \ + _(XR_ANDROID_trackables_image, 710) \ _(XR_KHR_maintenance1, 711) \ + _(XR_KHR_generic_controller, 712) \ + _(XR_ANDROID_scene_meshing, 719) \ + _(XR_EXT_spatial_entity, 741) \ + _(XR_EXT_spatial_plane_tracking, 742) \ + _(XR_EXT_stationary_reference_space, 743) \ + _(XR_EXT_spatial_marker_tracking, 744) \ + _(XR_LOGITECH_mx_ink_stylus_interaction, 746) \ + _(XR_EXT_spatial_anchor, 763) \ + _(XR_EXT_spatial_persistence, 764) \ + _(XR_EXT_spatial_persistence_operations, 782) \ + _(XR_ANDROID_spatial_object_tracking, 786) \ + _(XR_ANDROID_spatial_discovery_raycast, 787) \ + _(XR_ANDROID_spatial_entity_bound_anchor, 791) \ + _(XR_ANDROID_spatial_component_subsumed_by, 792) \ + _(XR_ANDROID_spatial_anchor_space, 796) \ + _(XR_EXT_interaction_profile_battery_state_display, 837) \ + _(XR_EXT_loader_init_properties, 839) \ + _(XR_EXT_view_configuration_views_change, 840) \ @@ -6449,6 +9570,23 @@ XR_ENUM_STR(XrResult); _(CreateVulkanInstanceKHR, KHR_vulkan_enable2) \ _(CreateVulkanDeviceKHR, KHR_vulkan_enable2) \ _(GetVulkanGraphicsDevice2KHR, KHR_vulkan_enable2) \ + _(GetVulkanGraphicsRequirements2KHR, KHR_vulkan_enable2) \ + + +/// For every function defined by XR_KHR_extended_struct_name_lengths in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_KHR_extended_struct_name_lengths(_) \ + _(StructureTypeToString2KHR, KHR_extended_struct_name_lengths) \ + + +/// For every function defined by XR_KHR_locate_spaces in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_KHR_locate_spaces(_) \ + _(LocateSpacesKHR, KHR_locate_spaces) \ /// For every function defined by XR_EXT_performance_settings in this version of the spec, @@ -7021,6 +10159,15 @@ XR_ENUM_STR(XrResult); _(DestroySpaceUserFB, FB_spatial_entity_user) \ +/// For every function defined by XR_META_spatial_entity_discovery in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_spatial_entity_discovery(_) \ + _(DiscoverSpacesMETA, META_spatial_entity_discovery) \ + _(RetrieveSpaceDiscoveryResultsMETA, META_spatial_entity_discovery) \ + + /// For every function defined by XR_META_recommended_layer_resolution in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7029,6 +10176,15 @@ XR_ENUM_STR(XrResult); _(GetRecommendedLayerResolutionMETA, META_recommended_layer_resolution) \ +/// For every function defined by XR_META_spatial_entity_persistence in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_spatial_entity_persistence(_) \ + _(SaveSpacesMETA, META_spatial_entity_persistence) \ + _(EraseSpacesMETA, META_spatial_entity_persistence) \ + + /// For every function defined by XR_META_passthrough_color_lut in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7047,6 +10203,23 @@ XR_ENUM_STR(XrResult); _(GetSpaceTriangleMeshMETA, META_spatial_entity_mesh) \ +/// For every function defined by XR_META_body_tracking_calibration in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_body_tracking_calibration(_) \ + _(SuggestBodyTrackingCalibrationOverrideMETA, META_body_tracking_calibration) \ + _(ResetBodyTrackingCalibrationMETA, META_body_tracking_calibration) \ + + +/// For every function defined by XR_META_body_tracking_fidelity in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_body_tracking_fidelity(_) \ + _(RequestBodyTrackingFidelityMETA, META_body_tracking_fidelity) \ + + /// For every function defined by XR_FB_face_tracking2 in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7082,6 +10255,32 @@ XR_ENUM_STR(XrResult); _(SetEnvironmentDepthHandRemovalMETA, META_environment_depth) \ +/// For every function defined by XR_EXT_render_model in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_render_model(_) \ + _(CreateRenderModelEXT, EXT_render_model) \ + _(DestroyRenderModelEXT, EXT_render_model) \ + _(GetRenderModelPropertiesEXT, EXT_render_model) \ + _(CreateRenderModelSpaceEXT, EXT_render_model) \ + _(CreateRenderModelAssetEXT, EXT_render_model) \ + _(DestroyRenderModelAssetEXT, EXT_render_model) \ + _(GetRenderModelAssetDataEXT, EXT_render_model) \ + _(GetRenderModelAssetPropertiesEXT, EXT_render_model) \ + _(GetRenderModelStateEXT, EXT_render_model) \ + + +/// For every function defined by XR_EXT_interaction_render_model in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_interaction_render_model(_) \ + _(EnumerateInteractionRenderModelIdsEXT, EXT_interaction_render_model) \ + _(EnumerateRenderModelSubactionPathsEXT, EXT_interaction_render_model) \ + _(GetRenderModelPoseTopLevelUserPathEXT, EXT_interaction_render_model) \ + + /// For every function defined by XR_QCOM_tracking_optimization_settings in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7090,6 +10289,14 @@ XR_ENUM_STR(XrResult); _(SetTrackingOptimizationSettingsHintQCOM, QCOM_tracking_optimization_settings) \ +/// For every function defined by XR_QCOM_hand_tracking_gesture in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_QCOM_hand_tracking_gesture(_) \ + _(GetHandGestureQCOM, QCOM_hand_tracking_gesture) \ + + /// For every function defined by XR_HTC_passthrough in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7145,6 +10352,103 @@ XR_ENUM_STR(XrResult); _(LocateBodyJointsBD, BD_body_tracking) \ +/// For every function defined by XR_BD_facial_simulation in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_facial_simulation(_) \ + _(EnumerateFacialSimulationModesBD, BD_facial_simulation) \ + _(CreateFaceTrackerBD, BD_facial_simulation) \ + _(DestroyFaceTrackerBD, BD_facial_simulation) \ + _(GetFacialSimulationDataBD, BD_facial_simulation) \ + _(SetFacialSimulationModeBD, BD_facial_simulation) \ + _(GetFacialSimulationModeBD, BD_facial_simulation) \ + + +/// For every function defined by XR_BD_spatial_sensing in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_spatial_sensing(_) \ + _(EnumerateSpatialEntityComponentTypesBD, BD_spatial_sensing) \ + _(GetSpatialEntityUuidBD, BD_spatial_sensing) \ + _(GetSpatialEntityComponentDataBD, BD_spatial_sensing) \ + _(CreateSenseDataProviderBD, BD_spatial_sensing) \ + _(StartSenseDataProviderAsyncBD, BD_spatial_sensing) \ + _(StartSenseDataProviderCompleteBD, BD_spatial_sensing) \ + _(GetSenseDataProviderStateBD, BD_spatial_sensing) \ + _(QuerySenseDataAsyncBD, BD_spatial_sensing) \ + _(QuerySenseDataCompleteBD, BD_spatial_sensing) \ + _(DestroySenseDataSnapshotBD, BD_spatial_sensing) \ + _(GetQueriedSenseDataBD, BD_spatial_sensing) \ + _(StopSenseDataProviderBD, BD_spatial_sensing) \ + _(DestroySenseDataProviderBD, BD_spatial_sensing) \ + _(CreateSpatialEntityAnchorBD, BD_spatial_sensing) \ + _(DestroyAnchorBD, BD_spatial_sensing) \ + _(GetAnchorUuidBD, BD_spatial_sensing) \ + _(CreateAnchorSpaceBD, BD_spatial_sensing) \ + + +/// For every function defined by XR_BD_spatial_anchor in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_spatial_anchor(_) \ + _(CreateSpatialAnchorAsyncBD, BD_spatial_anchor) \ + _(CreateSpatialAnchorCompleteBD, BD_spatial_anchor) \ + _(PersistSpatialAnchorAsyncBD, BD_spatial_anchor) \ + _(PersistSpatialAnchorCompleteBD, BD_spatial_anchor) \ + _(UnpersistSpatialAnchorAsyncBD, BD_spatial_anchor) \ + _(UnpersistSpatialAnchorCompleteBD, BD_spatial_anchor) \ + + +/// For every function defined by XR_BD_spatial_anchor_sharing in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_spatial_anchor_sharing(_) \ + _(ShareSpatialAnchorAsyncBD, BD_spatial_anchor_sharing) \ + _(ShareSpatialAnchorCompleteBD, BD_spatial_anchor_sharing) \ + _(DownloadSharedSpatialAnchorAsyncBD, BD_spatial_anchor_sharing) \ + _(DownloadSharedSpatialAnchorCompleteBD, BD_spatial_anchor_sharing) \ + + +/// For every function defined by XR_BD_spatial_scene in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_spatial_scene(_) \ + _(CaptureSceneAsyncBD, BD_spatial_scene) \ + _(CaptureSceneCompleteBD, BD_spatial_scene) \ + + +/// For every function defined by XR_BD_spatial_audio_rendering in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_BD_spatial_audio_rendering(_) \ + _(EnumerateSupportedAudioSampleRateBD, BD_spatial_audio_rendering) \ + _(QueryFramesPerBufferRangeBD, BD_spatial_audio_rendering) \ + _(CreateSpatialAudioRendererBD, BD_spatial_audio_rendering) \ + _(DestroySpatialAudioRendererBD, BD_spatial_audio_rendering) \ + _(CreateSoundObstacleMaterialBD, BD_spatial_audio_rendering) \ + _(UpdateSoundObstacleMaterialConfigBD, BD_spatial_audio_rendering) \ + _(DestroySoundObstacleMaterialBD, BD_spatial_audio_rendering) \ + _(CreateSoundObstacleBD, BD_spatial_audio_rendering) \ + _(UpdateSoundObstacleConfigBD, BD_spatial_audio_rendering) \ + _(DestroySoundObstacleBD, BD_spatial_audio_rendering) \ + _(CreateSoundObjectBD, BD_spatial_audio_rendering) \ + _(UpdateSoundObjectConfigBD, BD_spatial_audio_rendering) \ + _(SubmitSoundObjectBufferBD, BD_spatial_audio_rendering) \ + _(DestroySoundObjectBD, BD_spatial_audio_rendering) \ + _(CreateSoundFieldBD, BD_spatial_audio_rendering) \ + _(UpdateSoundFieldConfigBD, BD_spatial_audio_rendering) \ + _(SubmitSoundFieldBufferBD, BD_spatial_audio_rendering) \ + _(DestroySoundFieldBD, BD_spatial_audio_rendering) \ + _(WaitAudioPeriodBD, BD_spatial_audio_rendering) \ + _(EndAudioPeriodBD, BD_spatial_audio_rendering) \ + + /// For every function defined by XR_EXT_plane_detection in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7158,6 +10462,103 @@ XR_ENUM_STR(XrResult); _(GetPlanePolygonBufferEXT, EXT_plane_detection) \ +/// For every function defined by XR_ANDROID_trackables in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_trackables(_) \ + _(EnumerateSupportedTrackableTypesANDROID, ANDROID_trackables) \ + _(EnumerateSupportedAnchorTrackableTypesANDROID, ANDROID_trackables) \ + _(CreateTrackableTrackerANDROID, ANDROID_trackables) \ + _(DestroyTrackableTrackerANDROID, ANDROID_trackables) \ + _(GetAllTrackablesANDROID, ANDROID_trackables) \ + _(GetTrackablePlaneANDROID, ANDROID_trackables) \ + _(CreateAnchorSpaceANDROID, ANDROID_trackables) \ + + +/// For every function defined by XR_ANDROID_eye_tracking in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_eye_tracking(_) \ + _(CreateEyeTrackerANDROID, ANDROID_eye_tracking) \ + _(DestroyEyeTrackerANDROID, ANDROID_eye_tracking) \ + _(GetFineTrackingEyesInfoANDROID, ANDROID_eye_tracking) \ + _(GetCoarseTrackingEyesInfoANDROID, ANDROID_eye_tracking) \ + + +/// For every function defined by XR_ANDROID_device_anchor_persistence in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_device_anchor_persistence(_) \ + _(EnumerateSupportedPersistenceAnchorTypesANDROID, ANDROID_device_anchor_persistence) \ + _(CreateDeviceAnchorPersistenceANDROID, ANDROID_device_anchor_persistence) \ + _(DestroyDeviceAnchorPersistenceANDROID, ANDROID_device_anchor_persistence) \ + _(PersistAnchorANDROID, ANDROID_device_anchor_persistence) \ + _(GetAnchorPersistStateANDROID, ANDROID_device_anchor_persistence) \ + _(CreatePersistedAnchorSpaceANDROID, ANDROID_device_anchor_persistence) \ + _(EnumeratePersistedAnchorsANDROID, ANDROID_device_anchor_persistence) \ + _(UnpersistAnchorANDROID, ANDROID_device_anchor_persistence) \ + + +/// For every function defined by XR_ANDROID_face_tracking in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_face_tracking(_) \ + _(CreateFaceTrackerANDROID, ANDROID_face_tracking) \ + _(DestroyFaceTrackerANDROID, ANDROID_face_tracking) \ + _(GetFaceStateANDROID, ANDROID_face_tracking) \ + _(GetFaceCalibrationStateANDROID, ANDROID_face_tracking) \ + + +/// For every function defined by XR_ANDROID_passthrough_camera_state in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_passthrough_camera_state(_) \ + _(GetPassthroughCameraStateANDROID, ANDROID_passthrough_camera_state) \ + + +/// For every function defined by XR_ANDROID_composition_layer_passthrough_mesh in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_composition_layer_passthrough_mesh(_) \ + _(CreatePassthroughLayerANDROID, ANDROID_composition_layer_passthrough_mesh) \ + _(DestroyPassthroughLayerANDROID, ANDROID_composition_layer_passthrough_mesh) \ + _(SetPassthroughLayerMeshANDROID, ANDROID_composition_layer_passthrough_mesh) \ + + +/// For every function defined by XR_ANDROID_raycast in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_raycast(_) \ + _(EnumerateRaycastSupportedTrackableTypesANDROID, ANDROID_raycast) \ + _(RaycastANDROID, ANDROID_raycast) \ + + +/// For every function defined by XR_ANDROID_performance_metrics in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_performance_metrics(_) \ + _(EnumeratePerformanceMetricsCounterPathsANDROID, ANDROID_performance_metrics) \ + _(SetPerformanceMetricsStateANDROID, ANDROID_performance_metrics) \ + _(GetPerformanceMetricsStateANDROID, ANDROID_performance_metrics) \ + _(QueryPerformanceMetricsCounterANDROID, ANDROID_performance_metrics) \ + + +/// For every function defined by XR_ANDROID_trackables_object in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_trackables_object(_) \ + _(GetTrackableObjectANDROID, ANDROID_trackables_object) \ + + /// For every function defined by XR_EXT_future in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7209,6 +10610,32 @@ XR_ENUM_STR(XrResult); _(GetFacialExpressionBlendShapePropertiesML, ML_facial_expression) \ +/// For every function defined by XR_META_boundary_visibility in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_boundary_visibility(_) \ + _(RequestBoundaryVisibilityMETA, META_boundary_visibility) \ + + +/// For every function defined by XR_META_simultaneous_hands_and_controllers in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_simultaneous_hands_and_controllers(_) \ + _(ResumeSimultaneousHandsAndControllersTrackingMETA, META_simultaneous_hands_and_controllers) \ + _(PauseSimultaneousHandsAndControllersTrackingMETA, META_simultaneous_hands_and_controllers) \ + + +/// For every function defined by XR_META_spatial_entity_room_mesh in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_spatial_entity_room_mesh(_) \ + _(GetSpaceRoomMeshMETA, META_spatial_entity_room_mesh) \ + _(GetSpaceRoomMeshFaceIndicesMETA, META_spatial_entity_room_mesh) \ + + /// For every function defined by XR_META_colocation_discovery in this version of the spec, /// calls your macro with the function name and extension name. /// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, @@ -7220,6 +10647,177 @@ XR_ENUM_STR(XrResult); _(StopColocationAdvertisementMETA, META_colocation_discovery) \ +/// For every function defined by XR_META_environment_raycast in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_environment_raycast(_) \ + _(CreateEnvironmentRaycasterAsyncMETA, META_environment_raycast) \ + _(CreateEnvironmentRaycasterCompleteMETA, META_environment_raycast) \ + _(DestroyEnvironmentRaycasterMETA, META_environment_raycast) \ + _(PerformEnvironmentRaycastMETA, META_environment_raycast) \ + + +/// For every function defined by XR_META_tile_properties_hint in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_META_tile_properties_hint(_) \ + _(SetTilePropertiesHintMETA, META_tile_properties_hint) \ + + +/// For every function defined by XR_ANDROID_light_estimation in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_light_estimation(_) \ + _(CreateLightEstimatorANDROID, ANDROID_light_estimation) \ + _(DestroyLightEstimatorANDROID, ANDROID_light_estimation) \ + _(GetLightEstimateANDROID, ANDROID_light_estimation) \ + + +/// For every function defined by XR_ANDROID_anchor_sharing_export in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_anchor_sharing_export(_) \ + _(ShareAnchorANDROID, ANDROID_anchor_sharing_export) \ + _(UnshareAnchorANDROID, ANDROID_anchor_sharing_export) \ + + +/// For every function defined by XR_ANDROID_trackables_marker in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_trackables_marker(_) \ + _(GetTrackableMarkerANDROID, ANDROID_trackables_marker) \ + + +/// For every function defined by XR_ANDROID_trackables_qr_code in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_trackables_qr_code(_) \ + _(GetTrackableQrCodeANDROID, ANDROID_trackables_qr_code) \ + + +/// For every function defined by XR_ANDROID_trackables_image in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_trackables_image(_) \ + _(CreateTrackableImageDatabaseAsyncANDROID, ANDROID_trackables_image) \ + _(CreateTrackableImageDatabaseCompleteANDROID, ANDROID_trackables_image) \ + _(DestroyTrackableImageDatabaseANDROID, ANDROID_trackables_image) \ + _(AddTrackableImageDatabaseANDROID, ANDROID_trackables_image) \ + _(RemoveTrackableImageDatabaseANDROID, ANDROID_trackables_image) \ + _(GetTrackableImageANDROID, ANDROID_trackables_image) \ + + +/// For every function defined by XR_ANDROID_scene_meshing in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_scene_meshing(_) \ + _(EnumerateSupportedSemanticLabelSetsANDROID, ANDROID_scene_meshing) \ + _(CreateSceneMeshingTrackerANDROID, ANDROID_scene_meshing) \ + _(DestroySceneMeshingTrackerANDROID, ANDROID_scene_meshing) \ + _(CreateSceneMeshSnapshotANDROID, ANDROID_scene_meshing) \ + _(DestroySceneMeshSnapshotANDROID, ANDROID_scene_meshing) \ + _(GetAllSubmeshStatesANDROID, ANDROID_scene_meshing) \ + _(GetSubmeshDataANDROID, ANDROID_scene_meshing) \ + + +/// For every function defined by XR_EXT_spatial_entity in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_spatial_entity(_) \ + _(EnumerateSpatialCapabilitiesEXT, EXT_spatial_entity) \ + _(EnumerateSpatialCapabilityComponentTypesEXT, EXT_spatial_entity) \ + _(EnumerateSpatialCapabilityFeaturesEXT, EXT_spatial_entity) \ + _(CreateSpatialContextAsyncEXT, EXT_spatial_entity) \ + _(CreateSpatialContextCompleteEXT, EXT_spatial_entity) \ + _(DestroySpatialContextEXT, EXT_spatial_entity) \ + _(CreateSpatialDiscoverySnapshotAsyncEXT, EXT_spatial_entity) \ + _(CreateSpatialDiscoverySnapshotCompleteEXT, EXT_spatial_entity) \ + _(QuerySpatialComponentDataEXT, EXT_spatial_entity) \ + _(DestroySpatialSnapshotEXT, EXT_spatial_entity) \ + _(CreateSpatialEntityFromIdEXT, EXT_spatial_entity) \ + _(DestroySpatialEntityEXT, EXT_spatial_entity) \ + _(CreateSpatialUpdateSnapshotEXT, EXT_spatial_entity) \ + _(GetSpatialBufferStringEXT, EXT_spatial_entity) \ + _(GetSpatialBufferUint8EXT, EXT_spatial_entity) \ + _(GetSpatialBufferUint16EXT, EXT_spatial_entity) \ + _(GetSpatialBufferUint32EXT, EXT_spatial_entity) \ + _(GetSpatialBufferFloatEXT, EXT_spatial_entity) \ + _(GetSpatialBufferVector2fEXT, EXT_spatial_entity) \ + _(GetSpatialBufferVector3fEXT, EXT_spatial_entity) \ + + +/// For every function defined by XR_EXT_stationary_reference_space in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_stationary_reference_space(_) \ + _(GetStationaryReferenceSpaceGenerationIdEXT, EXT_stationary_reference_space) \ + + +/// For every function defined by XR_EXT_spatial_anchor in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_spatial_anchor(_) \ + _(CreateSpatialAnchorEXT, EXT_spatial_anchor) \ + + +/// For every function defined by XR_EXT_spatial_persistence in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_spatial_persistence(_) \ + _(EnumerateSpatialPersistenceScopesEXT, EXT_spatial_persistence) \ + _(CreateSpatialPersistenceContextAsyncEXT, EXT_spatial_persistence) \ + _(CreateSpatialPersistenceContextCompleteEXT, EXT_spatial_persistence) \ + _(DestroySpatialPersistenceContextEXT, EXT_spatial_persistence) \ + + +/// For every function defined by XR_EXT_spatial_persistence_operations in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_EXT_spatial_persistence_operations(_) \ + _(PersistSpatialEntityAsyncEXT, EXT_spatial_persistence_operations) \ + _(PersistSpatialEntityCompleteEXT, EXT_spatial_persistence_operations) \ + _(UnpersistSpatialEntityAsyncEXT, EXT_spatial_persistence_operations) \ + _(UnpersistSpatialEntityCompleteEXT, EXT_spatial_persistence_operations) \ + + +/// For every function defined by XR_ANDROID_spatial_discovery_raycast in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_spatial_discovery_raycast(_) \ + _(CreateSpatialRaycastSnapshotANDROID, ANDROID_spatial_discovery_raycast) \ + + +/// For every function defined by XR_ANDROID_spatial_entity_bound_anchor in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_spatial_entity_bound_anchor(_) \ + _(EnumerateSpatialAnchorAttachableComponentsANDROID, ANDROID_spatial_entity_bound_anchor) \ + + +/// For every function defined by XR_ANDROID_spatial_anchor_space in this version of the spec, +/// calls your macro with the function name and extension name. +/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name, +/// because it is easy to add back but impossible to remove with the preprocessor. +#define XR_LIST_FUNCTIONS_XR_ANDROID_spatial_anchor_space(_) \ + _(CreateSpatialAnchorSpaceANDROID, ANDROID_spatial_anchor_space) \ + _(CreateSpatialAnchorSpaceFromIdANDROID, ANDROID_spatial_anchor_space) \ + + #endif diff --git a/src/video/khronos/openxr/openxr_reflection_parent_structs.h b/src/video/khronos/openxr/openxr_reflection_parent_structs.h index f55d05e266..f970b32f3a 100644 --- a/src/video/khronos/openxr/openxr_reflection_parent_structs.h +++ b/src/video/khronos/openxr/openxr_reflection_parent_structs.h @@ -2,7 +2,7 @@ #define OPENXR_REFLECTION_PARENT_STRUCTS_H_ 1 /* -** Copyright (c) 2017-2025 The Khronos Group Inc. +** Copyright (c) 2017-2026 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -34,6 +34,7 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _avail(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \ _avail(XrCompositionLayerPassthroughFB, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB) \ _avail(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \ + _avail(XrCompositionLayerPassthroughANDROID, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_ANDROID) \ @@ -58,6 +59,7 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _avail(XrEventDataViveTrackerConnectedHTCX, XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX) \ _avail(XrEventDataSpatialAnchorCreateCompleteFB, XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) \ _avail(XrEventDataSpaceSetStatusCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB) \ + _avail(XrEventDataPassthroughStateChangedFB, XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB) \ _avail(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ _avail(XrEventDataLocalizationChangedML, XR_TYPE_EVENT_DATA_LOCALIZATION_CHANGED_ML) \ _avail(XrEventDataSpaceQueryResultsAvailableFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB) \ @@ -65,10 +67,37 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ _avail(XrEventDataSpaceShareCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) \ + _avail(XrEventDataSceneCaptureCompleteFB, XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB) \ + _avail(XrEventDataVirtualKeyboardCommitTextMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META) \ + _avail(XrEventDataVirtualKeyboardBackspaceMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META) \ + _avail(XrEventDataVirtualKeyboardEnterMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META) \ + _avail(XrEventDataVirtualKeyboardShownMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META) \ + _avail(XrEventDataVirtualKeyboardHiddenMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META) \ _avail(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ + _avail(XrEventDataSpaceDiscoveryResultsAvailableMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META) \ + _avail(XrEventDataSpaceDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataSpacesSaveResultMETA, XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META) \ + _avail(XrEventDataSpacesEraseResultMETA, XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META) \ _avail(XrEventDataPassthroughLayerResumedMETA, XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META) \ + _avail(XrEventDataShareSpacesCompleteMETA, XR_TYPE_EVENT_DATA_SHARE_SPACES_COMPLETE_META) \ + _avail(XrEventDataInteractionRenderModelsChangedEXT, XR_TYPE_EVENT_DATA_INTERACTION_RENDER_MODELS_CHANGED_EXT) \ + _avail(XrEventDataSenseDataProviderStateChangedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED_BD) \ + _avail(XrEventDataSenseDataUpdatedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED_BD) \ + _avail(XrEventDataRecommendedResolutionChangedANDROID, XR_TYPE_EVENT_DATA_RECOMMENDED_RESOLUTION_CHANGED_ANDROID) \ + _avail(XrEventDataUserPresenceChangedEXT, XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT) \ _avail(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \ _avail(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \ + _avail(XrEventDataBoundaryVisibilityChangedMETA, XR_TYPE_EVENT_DATA_BOUNDARY_VISIBILITY_CHANGED_META) \ + _avail(XrEventDataStartColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_START_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataStopColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_STOP_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataStartColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_START_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataColocationDiscoveryResultMETA, XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_RESULT_META) \ + _avail(XrEventDataColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataStopColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_STOP_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataImageTrackingLostANDROID, XR_TYPE_EVENT_DATA_IMAGE_TRACKING_LOST_ANDROID) \ + _avail(XrEventDataSpatialDiscoveryRecommendedEXT, XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT) \ + _avail(XrEventDataViewConfigurationViewsChangedEXT, XR_TYPE_EVENT_DATA_VIEW_CONFIGURATION_VIEWS_CHANGED_EXT) \ @@ -94,6 +123,7 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_CORE(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ @@ -123,6 +153,16 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a #endif +#if defined(XR_USE_GRAPHICS_API_METAL) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _avail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _unavail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + +#endif + #if defined(XR_USE_GRAPHICS_API_OPENGL) #define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ _avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ @@ -164,6 +204,7 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a // Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR() #define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_CORE(_avail, _unavail) \ + _avail(XrLoaderInitInfoPropertiesEXT, XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT) \ #if defined(XR_USE_PLATFORM_ANDROID) @@ -265,9 +306,18 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \ _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \ _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \ + _avail(XrSenseDataQueryCompletionBD, XR_TYPE_SENSE_DATA_QUERY_COMPLETION_BD) \ _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ + _avail(XrSpatialAnchorCreateCompletionBD, XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION_BD) \ _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \ _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \ + _avail(XrEnvironmentRaycasterCreateCompletionMETA, XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_COMPLETION_META) \ + _avail(XrCreateTrackableImageDatabaseCompletionANDROID, XR_TYPE_CREATE_TRACKABLE_IMAGE_DATABASE_COMPLETION_ANDROID) \ + _avail(XrCreateSpatialContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT) \ + _avail(XrCreateSpatialDiscoverySnapshotCompletionEXT, XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT) \ + _avail(XrCreateSpatialPersistenceContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT) \ + _avail(XrPersistSpatialEntityCompletionEXT, XR_TYPE_PERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ + _avail(XrUnpersistSpatialEntityCompletionEXT, XR_TYPE_UNPERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ @@ -313,6 +363,20 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceFilterBaseHeaderMETA +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterBaseHeaderMETA(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterBaseHeaderMETA_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterBaseHeaderMETA() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterBaseHeaderMETA_CORE(_avail, _unavail) \ + _avail(XrSpaceFilterUuidMETA, XR_TYPE_SPACE_FILTER_UUID_META) \ + _avail(XrSpaceFilterComponentMETA, XR_TYPE_SPACE_FILTER_COMPONENT_META) \ + + + + + /// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrShareSpacesRecipientBaseHeaderMETA #define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrShareSpacesRecipientBaseHeaderMETA(_avail, _unavail) \ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrShareSpacesRecipientBaseHeaderMETA_CORE(_avail, _unavail) \ @@ -326,5 +390,38 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrEnvironmentRaycastFilterBaseHeaderMETA +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEnvironmentRaycastFilterBaseHeaderMETA(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEnvironmentRaycastFilterBaseHeaderMETA_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEnvironmentRaycastFilterBaseHeaderMETA() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEnvironmentRaycastFilterBaseHeaderMETA_CORE(_avail, _unavail) \ + _avail(XrEnvironmentRaycastFilterDistanceMETA, XR_TYPE_ENVIRONMENT_RAYCAST_FILTER_DISTANCE_META) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialCapabilityConfigurationBaseHeaderEXT +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialCapabilityConfigurationBaseHeaderEXT(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialCapabilityConfigurationBaseHeaderEXT_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialCapabilityConfigurationBaseHeaderEXT() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialCapabilityConfigurationBaseHeaderEXT_CORE(_avail, _unavail) \ + _avail(XrSpatialCapabilityConfigurationPlaneTrackingEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT) \ + _avail(XrSpatialCapabilityConfigurationQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT) \ + _avail(XrSpatialCapabilityConfigurationMicroQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT) \ + _avail(XrSpatialCapabilityConfigurationArucoMarkerEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT) \ + _avail(XrSpatialCapabilityConfigurationAprilTagEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT) \ + _avail(XrSpatialCapabilityConfigurationAnchorEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT) \ + _avail(XrSpatialCapabilityConfigurationObjectTrackingANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID) \ + _avail(XrSpatialCapabilityConfigurationDepthRaycastANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID) \ + + + + + #endif diff --git a/src/video/khronos/openxr/openxr_reflection_structs.h b/src/video/khronos/openxr/openxr_reflection_structs.h new file mode 100644 index 0000000000..4e6b592393 --- /dev/null +++ b/src/video/khronos/openxr/openxr_reflection_structs.h @@ -0,0 +1,854 @@ +#ifndef OPENXR_REFLECTION_STRUCTS_H_ +#define OPENXR_REFLECTION_STRUCTS_H_ 1 + +/* +** Copyright (c) 2017-2026 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +/* +** This header is generated from the Khronos OpenXR XML API Registry. +** +*/ + +#include "openxr.h" + +/* +This file contains expansion macros (X Macros) for OpenXR structures. +*/ + + + +/// Calls one of your macros with the structure type name and the XrStructureType constant for +/// each known structure type. The first macro (_avail) is called for those that are available, +/// while the second macro (_unavail) is called for those unavailable due to preprocessor definitions. +#define XR_LIST_ALL_STRUCTURE_TYPES(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_STRUCTURE_TYPES() +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \ + _avail(XrApiLayerProperties, XR_TYPE_API_LAYER_PROPERTIES) \ + _avail(XrExtensionProperties, XR_TYPE_EXTENSION_PROPERTIES) \ + _avail(XrInstanceCreateInfo, XR_TYPE_INSTANCE_CREATE_INFO) \ + _avail(XrInstanceProperties, XR_TYPE_INSTANCE_PROPERTIES) \ + _avail(XrEventDataBuffer, XR_TYPE_EVENT_DATA_BUFFER) \ + _avail(XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO) \ + _avail(XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES) \ + _avail(XrSessionCreateInfo, XR_TYPE_SESSION_CREATE_INFO) \ + _avail(XrSpaceVelocity, XR_TYPE_SPACE_VELOCITY) \ + _avail(XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO) \ + _avail(XrActionSpaceCreateInfo, XR_TYPE_ACTION_SPACE_CREATE_INFO) \ + _avail(XrSpaceLocation, XR_TYPE_SPACE_LOCATION) \ + _avail(XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES) \ + _avail(XrViewConfigurationView, XR_TYPE_VIEW_CONFIGURATION_VIEW) \ + _avail(XrSwapchainCreateInfo, XR_TYPE_SWAPCHAIN_CREATE_INFO) \ + _avail(XrSwapchainImageAcquireInfo, XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO) \ + _avail(XrSwapchainImageWaitInfo, XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO) \ + _avail(XrSwapchainImageReleaseInfo, XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO) \ + _avail(XrSessionBeginInfo, XR_TYPE_SESSION_BEGIN_INFO) \ + _avail(XrFrameWaitInfo, XR_TYPE_FRAME_WAIT_INFO) \ + _avail(XrFrameState, XR_TYPE_FRAME_STATE) \ + _avail(XrFrameBeginInfo, XR_TYPE_FRAME_BEGIN_INFO) \ + _avail(XrFrameEndInfo, XR_TYPE_FRAME_END_INFO) \ + _avail(XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO) \ + _avail(XrViewState, XR_TYPE_VIEW_STATE) \ + _avail(XrView, XR_TYPE_VIEW) \ + _avail(XrActionSetCreateInfo, XR_TYPE_ACTION_SET_CREATE_INFO) \ + _avail(XrActionCreateInfo, XR_TYPE_ACTION_CREATE_INFO) \ + _avail(XrInteractionProfileSuggestedBinding, XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING) \ + _avail(XrSessionActionSetsAttachInfo, XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO) \ + _avail(XrInteractionProfileState, XR_TYPE_INTERACTION_PROFILE_STATE) \ + _avail(XrActionStateGetInfo, XR_TYPE_ACTION_STATE_GET_INFO) \ + _avail(XrActionStateBoolean, XR_TYPE_ACTION_STATE_BOOLEAN) \ + _avail(XrActionStateFloat, XR_TYPE_ACTION_STATE_FLOAT) \ + _avail(XrActionStateVector2f, XR_TYPE_ACTION_STATE_VECTOR2F) \ + _avail(XrActionStatePose, XR_TYPE_ACTION_STATE_POSE) \ + _avail(XrActionsSyncInfo, XR_TYPE_ACTIONS_SYNC_INFO) \ + _avail(XrBoundSourcesForActionEnumerateInfo, XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO) \ + _avail(XrInputSourceLocalizedNameGetInfo, XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO) \ + _avail(XrHapticActionInfo, XR_TYPE_HAPTIC_ACTION_INFO) \ + _avail(XrCompositionLayerProjectionView, XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW) \ + _avail(XrCompositionLayerProjection, XR_TYPE_COMPOSITION_LAYER_PROJECTION) \ + _avail(XrCompositionLayerQuad, XR_TYPE_COMPOSITION_LAYER_QUAD) \ + _avail(XrEventDataEventsLost, XR_TYPE_EVENT_DATA_EVENTS_LOST) \ + _avail(XrEventDataInstanceLossPending, XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING) \ + _avail(XrEventDataSessionStateChanged, XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) \ + _avail(XrEventDataReferenceSpaceChangePending, XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING) \ + _avail(XrEventDataInteractionProfileChanged, XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED) \ + _avail(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \ + _avail(XrSpacesLocateInfo, XR_TYPE_SPACES_LOCATE_INFO) \ + _avail(XrSpaceLocations, XR_TYPE_SPACE_LOCATIONS) \ + _avail(XrSpaceVelocities, XR_TYPE_SPACE_VELOCITIES) \ + _avail(XrCompositionLayerCubeKHR, XR_TYPE_COMPOSITION_LAYER_CUBE_KHR) \ + _avail(XrCompositionLayerDepthInfoKHR, XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR) \ + _avail(XrCompositionLayerCylinderKHR, XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR) \ + _avail(XrCompositionLayerEquirectKHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR) \ + _avail(XrVisibilityMaskKHR, XR_TYPE_VISIBILITY_MASK_KHR) \ + _avail(XrEventDataVisibilityMaskChangedKHR, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR) \ + _avail(XrCompositionLayerColorScaleBiasKHR, XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR) \ + _avail(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \ + _avail(XrBindingModificationsKHR, XR_TYPE_BINDING_MODIFICATIONS_KHR) \ + _avail(XrEventDataPerfSettingsEXT, XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT) \ + _avail(XrDebugUtilsObjectNameInfoEXT, XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT) \ + _avail(XrDebugUtilsLabelEXT, XR_TYPE_DEBUG_UTILS_LABEL_EXT) \ + _avail(XrDebugUtilsMessengerCallbackDataEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT) \ + _avail(XrDebugUtilsMessengerCreateInfoEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) \ + _avail(XrSystemEyeGazeInteractionPropertiesEXT, XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT) \ + _avail(XrEyeGazeSampleTimeEXT, XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT) \ + _avail(XrSessionCreateInfoOverlayEXTX, XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX) \ + _avail(XrEventDataMainSessionVisibilityChangedEXTX, XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX) \ + _avail(XrSpatialAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT) \ + _avail(XrSpatialAnchorSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT) \ + _avail(XrCompositionLayerImageLayoutFB, XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB) \ + _avail(XrCompositionLayerAlphaBlendFB, XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB) \ + _avail(XrViewConfigurationDepthRangeEXT, XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT) \ + _avail(XrSpatialGraphNodeSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT) \ + _avail(XrSpatialGraphStaticNodeBindingCreateInfoMSFT, XR_TYPE_SPATIAL_GRAPH_STATIC_NODE_BINDING_CREATE_INFO_MSFT) \ + _avail(XrSpatialGraphNodeBindingPropertiesGetInfoMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_GET_INFO_MSFT) \ + _avail(XrSpatialGraphNodeBindingPropertiesMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_MSFT) \ + _avail(XrSystemHandTrackingPropertiesEXT, XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT) \ + _avail(XrHandTrackerCreateInfoEXT, XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT) \ + _avail(XrHandJointsLocateInfoEXT, XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT) \ + _avail(XrHandJointLocationsEXT, XR_TYPE_HAND_JOINT_LOCATIONS_EXT) \ + _avail(XrHandJointVelocitiesEXT, XR_TYPE_HAND_JOINT_VELOCITIES_EXT) \ + _avail(XrSystemHandTrackingMeshPropertiesMSFT, XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT) \ + _avail(XrHandMeshSpaceCreateInfoMSFT, XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT) \ + _avail(XrHandMeshUpdateInfoMSFT, XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT) \ + _avail(XrHandMeshMSFT, XR_TYPE_HAND_MESH_MSFT) \ + _avail(XrHandPoseTypeInfoMSFT, XR_TYPE_HAND_POSE_TYPE_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationSessionBeginInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT) \ + _avail(XrSecondaryViewConfigurationFrameStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT) \ + _avail(XrSecondaryViewConfigurationLayerInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationFrameEndInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationSwapchainCreateInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT) \ + _avail(XrControllerModelKeyStateMSFT, XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT) \ + _avail(XrControllerModelNodePropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT) \ + _avail(XrControllerModelPropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT) \ + _avail(XrControllerModelNodeStateMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT) \ + _avail(XrControllerModelStateMSFT, XR_TYPE_CONTROLLER_MODEL_STATE_MSFT) \ + _avail(XrViewConfigurationViewFovEPIC, XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC) \ + _avail(XrCompositionLayerReprojectionInfoMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT) \ + _avail(XrCompositionLayerReprojectionPlaneOverrideMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT) \ + _avail(XrCompositionLayerSecureContentFB, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB) \ + _avail(XrSystemBodyTrackingPropertiesFB, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB) \ + _avail(XrBodyTrackerCreateInfoFB, XR_TYPE_BODY_TRACKER_CREATE_INFO_FB) \ + _avail(XrBodySkeletonFB, XR_TYPE_BODY_SKELETON_FB) \ + _avail(XrBodyJointsLocateInfoFB, XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB) \ + _avail(XrBodyJointLocationsFB, XR_TYPE_BODY_JOINT_LOCATIONS_FB) \ + _avail(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \ + _avail(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \ + _avail(XrHandJointsMotionRangeInfoEXT, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT) \ + _avail(XrSceneObserverCreateInfoMSFT, XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT) \ + _avail(XrSceneCreateInfoMSFT, XR_TYPE_SCENE_CREATE_INFO_MSFT) \ + _avail(XrNewSceneComputeInfoMSFT, XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT) \ + _avail(XrVisualMeshComputeLodInfoMSFT, XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT) \ + _avail(XrSceneComponentsMSFT, XR_TYPE_SCENE_COMPONENTS_MSFT) \ + _avail(XrSceneComponentsGetInfoMSFT, XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT) \ + _avail(XrSceneComponentLocationsMSFT, XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT) \ + _avail(XrSceneComponentsLocateInfoMSFT, XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT) \ + _avail(XrSceneObjectsMSFT, XR_TYPE_SCENE_OBJECTS_MSFT) \ + _avail(XrSceneComponentParentFilterInfoMSFT, XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT) \ + _avail(XrSceneObjectTypesFilterInfoMSFT, XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT) \ + _avail(XrScenePlanesMSFT, XR_TYPE_SCENE_PLANES_MSFT) \ + _avail(XrScenePlaneAlignmentFilterInfoMSFT, XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT) \ + _avail(XrSceneMeshesMSFT, XR_TYPE_SCENE_MESHES_MSFT) \ + _avail(XrSceneMeshBuffersGetInfoMSFT, XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT) \ + _avail(XrSceneMeshBuffersMSFT, XR_TYPE_SCENE_MESH_BUFFERS_MSFT) \ + _avail(XrSceneMeshVertexBufferMSFT, XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT) \ + _avail(XrSceneMeshIndicesUint32MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT) \ + _avail(XrSceneMeshIndicesUint16MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT) \ + _avail(XrSerializedSceneFragmentDataGetInfoMSFT, XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT) \ + _avail(XrSceneDeserializeInfoMSFT, XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT) \ + _avail(XrEventDataDisplayRefreshRateChangedFB, XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB) \ + _avail(XrViveTrackerPathsHTCX, XR_TYPE_VIVE_TRACKER_PATHS_HTCX) \ + _avail(XrEventDataViveTrackerConnectedHTCX, XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX) \ + _avail(XrSystemFacialTrackingPropertiesHTC, XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC) \ + _avail(XrFacialExpressionsHTC, XR_TYPE_FACIAL_EXPRESSIONS_HTC) \ + _avail(XrFacialTrackerCreateInfoHTC, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC) \ + _avail(XrSystemColorSpacePropertiesFB, XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB) \ + _avail(XrHandTrackingMeshFB, XR_TYPE_HAND_TRACKING_MESH_FB) \ + _avail(XrHandTrackingScaleFB, XR_TYPE_HAND_TRACKING_SCALE_FB) \ + _avail(XrHandTrackingAimStateFB, XR_TYPE_HAND_TRACKING_AIM_STATE_FB) \ + _avail(XrHandTrackingCapsulesStateFB, XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB) \ + _avail(XrSystemSpatialEntityPropertiesFB, XR_TYPE_SYSTEM_SPATIAL_ENTITY_PROPERTIES_FB) \ + _avail(XrSpatialAnchorCreateInfoFB, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_FB) \ + _avail(XrSpaceComponentStatusSetInfoFB, XR_TYPE_SPACE_COMPONENT_STATUS_SET_INFO_FB) \ + _avail(XrSpaceComponentStatusFB, XR_TYPE_SPACE_COMPONENT_STATUS_FB) \ + _avail(XrEventDataSpatialAnchorCreateCompleteFB, XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) \ + _avail(XrEventDataSpaceSetStatusCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB) \ + _avail(XrFoveationProfileCreateInfoFB, XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB) \ + _avail(XrSwapchainCreateInfoFoveationFB, XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB) \ + _avail(XrSwapchainStateFoveationFB, XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB) \ + _avail(XrFoveationLevelProfileCreateInfoFB, XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB) \ + _avail(XrSystemKeyboardTrackingPropertiesFB, XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB) \ + _avail(XrKeyboardSpaceCreateInfoFB, XR_TYPE_KEYBOARD_SPACE_CREATE_INFO_FB) \ + _avail(XrKeyboardTrackingQueryFB, XR_TYPE_KEYBOARD_TRACKING_QUERY_FB) \ + _avail(XrTriangleMeshCreateInfoFB, XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB) \ + _avail(XrSystemPassthroughPropertiesFB, XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB) \ + _avail(XrSystemPassthroughProperties2FB, XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB) \ + _avail(XrPassthroughCreateInfoFB, XR_TYPE_PASSTHROUGH_CREATE_INFO_FB) \ + _avail(XrPassthroughLayerCreateInfoFB, XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB) \ + _avail(XrCompositionLayerPassthroughFB, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB) \ + _avail(XrGeometryInstanceCreateInfoFB, XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB) \ + _avail(XrGeometryInstanceTransformFB, XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB) \ + _avail(XrPassthroughStyleFB, XR_TYPE_PASSTHROUGH_STYLE_FB) \ + _avail(XrPassthroughColorMapMonoToRgbaFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB) \ + _avail(XrPassthroughColorMapMonoToMonoFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB) \ + _avail(XrPassthroughBrightnessContrastSaturationFB, XR_TYPE_PASSTHROUGH_BRIGHTNESS_CONTRAST_SATURATION_FB) \ + _avail(XrEventDataPassthroughStateChangedFB, XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB) \ + _avail(XrRenderModelPathInfoFB, XR_TYPE_RENDER_MODEL_PATH_INFO_FB) \ + _avail(XrRenderModelPropertiesFB, XR_TYPE_RENDER_MODEL_PROPERTIES_FB) \ + _avail(XrRenderModelBufferFB, XR_TYPE_RENDER_MODEL_BUFFER_FB) \ + _avail(XrRenderModelLoadInfoFB, XR_TYPE_RENDER_MODEL_LOAD_INFO_FB) \ + _avail(XrSystemRenderModelPropertiesFB, XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB) \ + _avail(XrRenderModelCapabilitiesRequestFB, XR_TYPE_RENDER_MODEL_CAPABILITIES_REQUEST_FB) \ + _avail(XrViewLocateFoveatedRenderingVARJO, XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO) \ + _avail(XrFoveatedViewConfigurationViewVARJO, XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO) \ + _avail(XrSystemFoveatedRenderingPropertiesVARJO, XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO) \ + _avail(XrCompositionLayerDepthTestVARJO, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO) \ + _avail(XrSystemMarkerTrackingPropertiesVARJO, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO) \ + _avail(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ + _avail(XrMarkerSpaceCreateInfoVARJO, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO) \ + _avail(XrFrameEndInfoML, XR_TYPE_FRAME_END_INFO_ML) \ + _avail(XrGlobalDimmerFrameEndInfoML, XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML) \ + _avail(XrSystemMarkerUnderstandingPropertiesML, XR_TYPE_SYSTEM_MARKER_UNDERSTANDING_PROPERTIES_ML) \ + _avail(XrMarkerDetectorCreateInfoML, XR_TYPE_MARKER_DETECTOR_CREATE_INFO_ML) \ + _avail(XrMarkerDetectorArucoInfoML, XR_TYPE_MARKER_DETECTOR_ARUCO_INFO_ML) \ + _avail(XrMarkerDetectorSizeInfoML, XR_TYPE_MARKER_DETECTOR_SIZE_INFO_ML) \ + _avail(XrMarkerDetectorAprilTagInfoML, XR_TYPE_MARKER_DETECTOR_APRIL_TAG_INFO_ML) \ + _avail(XrMarkerDetectorCustomProfileInfoML, XR_TYPE_MARKER_DETECTOR_CUSTOM_PROFILE_INFO_ML) \ + _avail(XrMarkerDetectorSnapshotInfoML, XR_TYPE_MARKER_DETECTOR_SNAPSHOT_INFO_ML) \ + _avail(XrMarkerDetectorStateML, XR_TYPE_MARKER_DETECTOR_STATE_ML) \ + _avail(XrMarkerSpaceCreateInfoML, XR_TYPE_MARKER_SPACE_CREATE_INFO_ML) \ + _avail(XrLocalizationMapML, XR_TYPE_LOCALIZATION_MAP_ML) \ + _avail(XrEventDataLocalizationChangedML, XR_TYPE_EVENT_DATA_LOCALIZATION_CHANGED_ML) \ + _avail(XrMapLocalizationRequestInfoML, XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML) \ + _avail(XrLocalizationMapImportInfoML, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML) \ + _avail(XrLocalizationEnableEventsInfoML, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML) \ + _avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \ + _avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \ + _avail(XrSpatialAnchorStateML, XR_TYPE_SPATIAL_ANCHOR_STATE_ML) \ + _avail(XrSpatialAnchorsCreateStorageInfoML, XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML) \ + _avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \ + _avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \ + _avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \ + _avail(XrSpatialAnchorsPublishInfoML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML) \ + _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \ + _avail(XrSpatialAnchorsDeleteInfoML, XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML) \ + _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationInfoML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \ + _avail(XrSpatialAnchorsPublishCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML) \ + _avail(XrSpatialAnchorsDeleteCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML) \ + _avail(XrSpatialAnchorsUpdateExpirationCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML) \ + _avail(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ + _avail(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ + _avail(XrSceneMarkersMSFT, XR_TYPE_SCENE_MARKERS_MSFT) \ + _avail(XrSceneMarkerTypeFilterMSFT, XR_TYPE_SCENE_MARKER_TYPE_FILTER_MSFT) \ + _avail(XrSceneMarkerQRCodesMSFT, XR_TYPE_SCENE_MARKER_QR_CODES_MSFT) \ + _avail(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \ + _avail(XrSpaceStorageLocationFilterInfoFB, XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB) \ + _avail(XrSpaceUuidFilterInfoFB, XR_TYPE_SPACE_UUID_FILTER_INFO_FB) \ + _avail(XrSpaceComponentFilterInfoFB, XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB) \ + _avail(XrSpaceQueryResultsFB, XR_TYPE_SPACE_QUERY_RESULTS_FB) \ + _avail(XrEventDataSpaceQueryResultsAvailableFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB) \ + _avail(XrEventDataSpaceQueryCompleteFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) \ + _avail(XrSpaceSaveInfoFB, XR_TYPE_SPACE_SAVE_INFO_FB) \ + _avail(XrSpaceEraseInfoFB, XR_TYPE_SPACE_ERASE_INFO_FB) \ + _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ + _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + _avail(XrSpaceShareInfoFB, XR_TYPE_SPACE_SHARE_INFO_FB) \ + _avail(XrEventDataSpaceShareCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) \ + _avail(XrCompositionLayerSpaceWarpInfoFB, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB) \ + _avail(XrSystemSpaceWarpPropertiesFB, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB) \ + _avail(XrHapticAmplitudeEnvelopeVibrationFB, XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB) \ + _avail(XrSemanticLabelsFB, XR_TYPE_SEMANTIC_LABELS_FB) \ + _avail(XrRoomLayoutFB, XR_TYPE_ROOM_LAYOUT_FB) \ + _avail(XrBoundary2DFB, XR_TYPE_BOUNDARY_2D_FB) \ + _avail(XrSemanticLabelsSupportInfoFB, XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB) \ + _avail(XrDigitalLensControlALMALENCE, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE) \ + _avail(XrEventDataSceneCaptureCompleteFB, XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB) \ + _avail(XrSceneCaptureRequestInfoFB, XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB) \ + _avail(XrSpaceContainerFB, XR_TYPE_SPACE_CONTAINER_FB) \ + _avail(XrFoveationEyeTrackedProfileCreateInfoMETA, XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META) \ + _avail(XrFoveationEyeTrackedStateMETA, XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META) \ + _avail(XrSystemFoveationEyeTrackedPropertiesMETA, XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META) \ + _avail(XrSystemFaceTrackingPropertiesFB, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB) \ + _avail(XrFaceTrackerCreateInfoFB, XR_TYPE_FACE_TRACKER_CREATE_INFO_FB) \ + _avail(XrFaceExpressionInfoFB, XR_TYPE_FACE_EXPRESSION_INFO_FB) \ + _avail(XrFaceExpressionWeightsFB, XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB) \ + _avail(XrEyeTrackerCreateInfoFB, XR_TYPE_EYE_TRACKER_CREATE_INFO_FB) \ + _avail(XrEyeGazesInfoFB, XR_TYPE_EYE_GAZES_INFO_FB) \ + _avail(XrSystemEyeTrackingPropertiesFB, XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB) \ + _avail(XrEyeGazesFB, XR_TYPE_EYE_GAZES_FB) \ + _avail(XrPassthroughKeyboardHandsIntensityFB, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB) \ + _avail(XrCompositionLayerSettingsFB, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB) \ + _avail(XrHapticPcmVibrationFB, XR_TYPE_HAPTIC_PCM_VIBRATION_FB) \ + _avail(XrDevicePcmSampleRateStateFB, XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB) \ + _avail(XrFrameSynthesisInfoEXT, XR_TYPE_FRAME_SYNTHESIS_INFO_EXT) \ + _avail(XrFrameSynthesisConfigViewEXT, XR_TYPE_FRAME_SYNTHESIS_CONFIG_VIEW_EXT) \ + _avail(XrCompositionLayerDepthTestFB, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB) \ + _avail(XrLocalDimmingFrameEndInfoMETA, XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META) \ + _avail(XrPassthroughPreferencesMETA, XR_TYPE_PASSTHROUGH_PREFERENCES_META) \ + _avail(XrSystemVirtualKeyboardPropertiesMETA, XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META) \ + _avail(XrVirtualKeyboardCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META) \ + _avail(XrVirtualKeyboardSpaceCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META) \ + _avail(XrVirtualKeyboardLocationInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META) \ + _avail(XrVirtualKeyboardModelVisibilitySetInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META) \ + _avail(XrVirtualKeyboardAnimationStateMETA, XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META) \ + _avail(XrVirtualKeyboardModelAnimationStatesMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META) \ + _avail(XrVirtualKeyboardTextureDataMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META) \ + _avail(XrVirtualKeyboardInputInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META) \ + _avail(XrVirtualKeyboardTextContextChangeInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META) \ + _avail(XrEventDataVirtualKeyboardCommitTextMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META) \ + _avail(XrEventDataVirtualKeyboardBackspaceMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META) \ + _avail(XrEventDataVirtualKeyboardEnterMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META) \ + _avail(XrEventDataVirtualKeyboardShownMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META) \ + _avail(XrEventDataVirtualKeyboardHiddenMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META) \ + _avail(XrExternalCameraOCULUS, XR_TYPE_EXTERNAL_CAMERA_OCULUS) \ + _avail(XrPerformanceMetricsStateMETA, XR_TYPE_PERFORMANCE_METRICS_STATE_META) \ + _avail(XrPerformanceMetricsCounterMETA, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META) \ + _avail(XrSpaceListSaveInfoFB, XR_TYPE_SPACE_LIST_SAVE_INFO_FB) \ + _avail(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ + _avail(XrSpaceUserCreateInfoFB, XR_TYPE_SPACE_USER_CREATE_INFO_FB) \ + _avail(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _avail(XrSystemSpaceDiscoveryPropertiesMETA, XR_TYPE_SYSTEM_SPACE_DISCOVERY_PROPERTIES_META) \ + _avail(XrSpaceDiscoveryInfoMETA, XR_TYPE_SPACE_DISCOVERY_INFO_META) \ + _avail(XrSpaceFilterUuidMETA, XR_TYPE_SPACE_FILTER_UUID_META) \ + _avail(XrSpaceFilterComponentMETA, XR_TYPE_SPACE_FILTER_COMPONENT_META) \ + _avail(XrSpaceDiscoveryResultsMETA, XR_TYPE_SPACE_DISCOVERY_RESULTS_META) \ + _avail(XrEventDataSpaceDiscoveryResultsAvailableMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META) \ + _avail(XrEventDataSpaceDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META) \ + _avail(XrRecommendedLayerResolutionMETA, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_META) \ + _avail(XrRecommendedLayerResolutionGetInfoMETA, XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_GET_INFO_META) \ + _avail(XrSystemSpacePersistencePropertiesMETA, XR_TYPE_SYSTEM_SPACE_PERSISTENCE_PROPERTIES_META) \ + _avail(XrSpacesSaveInfoMETA, XR_TYPE_SPACES_SAVE_INFO_META) \ + _avail(XrEventDataSpacesSaveResultMETA, XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META) \ + _avail(XrSpacesEraseInfoMETA, XR_TYPE_SPACES_ERASE_INFO_META) \ + _avail(XrEventDataSpacesEraseResultMETA, XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META) \ + _avail(XrPassthroughColorLutCreateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META) \ + _avail(XrPassthroughColorLutUpdateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META) \ + _avail(XrPassthroughColorMapLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META) \ + _avail(XrPassthroughColorMapInterpolatedLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META) \ + _avail(XrSystemPassthroughColorLutPropertiesMETA, XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META) \ + _avail(XrSpaceTriangleMeshGetInfoMETA, XR_TYPE_SPACE_TRIANGLE_MESH_GET_INFO_META) \ + _avail(XrSpaceTriangleMeshMETA, XR_TYPE_SPACE_TRIANGLE_MESH_META) \ + _avail(XrSystemPropertiesBodyTrackingFullBodyMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FULL_BODY_META) \ + _avail(XrEventDataPassthroughLayerResumedMETA, XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META) \ + _avail(XrBodyTrackingCalibrationStatusMETA, XR_TYPE_BODY_TRACKING_CALIBRATION_STATUS_META) \ + _avail(XrBodyTrackingCalibrationInfoMETA, XR_TYPE_BODY_TRACKING_CALIBRATION_INFO_META) \ + _avail(XrSystemPropertiesBodyTrackingCalibrationMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_CALIBRATION_META) \ + _avail(XrSystemPropertiesBodyTrackingFidelityMETA, XR_TYPE_SYSTEM_PROPERTIES_BODY_TRACKING_FIDELITY_META) \ + _avail(XrBodyTrackingFidelityStatusMETA, XR_TYPE_BODY_TRACKING_FIDELITY_STATUS_META) \ + _avail(XrSystemFaceTrackingProperties2FB, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES2_FB) \ + _avail(XrFaceTrackerCreateInfo2FB, XR_TYPE_FACE_TRACKER_CREATE_INFO2_FB) \ + _avail(XrFaceExpressionInfo2FB, XR_TYPE_FACE_EXPRESSION_INFO2_FB) \ + _avail(XrFaceExpressionWeights2FB, XR_TYPE_FACE_EXPRESSION_WEIGHTS2_FB) \ + _avail(XrSystemSpatialEntitySharingPropertiesMETA, XR_TYPE_SYSTEM_SPATIAL_ENTITY_SHARING_PROPERTIES_META) \ + _avail(XrShareSpacesInfoMETA, XR_TYPE_SHARE_SPACES_INFO_META) \ + _avail(XrEventDataShareSpacesCompleteMETA, XR_TYPE_EVENT_DATA_SHARE_SPACES_COMPLETE_META) \ + _avail(XrEnvironmentDepthProviderCreateInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_PROVIDER_CREATE_INFO_META) \ + _avail(XrEnvironmentDepthSwapchainCreateInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_CREATE_INFO_META) \ + _avail(XrEnvironmentDepthSwapchainStateMETA, XR_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_STATE_META) \ + _avail(XrEnvironmentDepthImageAcquireInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_ACQUIRE_INFO_META) \ + _avail(XrEnvironmentDepthImageViewMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_VIEW_META) \ + _avail(XrEnvironmentDepthImageMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_META) \ + _avail(XrEnvironmentDepthImageTimestampMETA, XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_TIMESTAMP_META) \ + _avail(XrEnvironmentDepthHandRemovalSetInfoMETA, XR_TYPE_ENVIRONMENT_DEPTH_HAND_REMOVAL_SET_INFO_META) \ + _avail(XrSystemEnvironmentDepthPropertiesMETA, XR_TYPE_SYSTEM_ENVIRONMENT_DEPTH_PROPERTIES_META) \ + _avail(XrRenderModelCreateInfoEXT, XR_TYPE_RENDER_MODEL_CREATE_INFO_EXT) \ + _avail(XrRenderModelPropertiesGetInfoEXT, XR_TYPE_RENDER_MODEL_PROPERTIES_GET_INFO_EXT) \ + _avail(XrRenderModelPropertiesEXT, XR_TYPE_RENDER_MODEL_PROPERTIES_EXT) \ + _avail(XrRenderModelSpaceCreateInfoEXT, XR_TYPE_RENDER_MODEL_SPACE_CREATE_INFO_EXT) \ + _avail(XrRenderModelStateGetInfoEXT, XR_TYPE_RENDER_MODEL_STATE_GET_INFO_EXT) \ + _avail(XrRenderModelStateEXT, XR_TYPE_RENDER_MODEL_STATE_EXT) \ + _avail(XrRenderModelAssetCreateInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_CREATE_INFO_EXT) \ + _avail(XrRenderModelAssetDataGetInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_DATA_GET_INFO_EXT) \ + _avail(XrRenderModelAssetDataEXT, XR_TYPE_RENDER_MODEL_ASSET_DATA_EXT) \ + _avail(XrRenderModelAssetPropertiesGetInfoEXT, XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_GET_INFO_EXT) \ + _avail(XrRenderModelAssetPropertiesEXT, XR_TYPE_RENDER_MODEL_ASSET_PROPERTIES_EXT) \ + _avail(XrInteractionRenderModelIdsEnumerateInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_IDS_ENUMERATE_INFO_EXT) \ + _avail(XrInteractionRenderModelSubactionPathInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_SUBACTION_PATH_INFO_EXT) \ + _avail(XrInteractionRenderModelTopLevelUserPathGetInfoEXT, XR_TYPE_INTERACTION_RENDER_MODEL_TOP_LEVEL_USER_PATH_GET_INFO_EXT) \ + _avail(XrEventDataInteractionRenderModelsChangedEXT, XR_TYPE_EVENT_DATA_INTERACTION_RENDER_MODELS_CHANGED_EXT) \ + _avail(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ + _avail(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ + _avail(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ + _avail(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \ + _avail(XrFoveationApplyInfoHTC, XR_TYPE_FOVEATION_APPLY_INFO_HTC) \ + _avail(XrFoveationDynamicModeInfoHTC, XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC) \ + _avail(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ + _avail(XrSystemAnchorPropertiesHTC, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC) \ + _avail(XrSpatialAnchorCreateInfoHTC, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC) \ + _avail(XrSystemBodyTrackingPropertiesHTC, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC) \ + _avail(XrBodyTrackerCreateInfoHTC, XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC) \ + _avail(XrBodyJointsLocateInfoHTC, XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC) \ + _avail(XrBodyJointLocationsHTC, XR_TYPE_BODY_JOINT_LOCATIONS_HTC) \ + _avail(XrBodySkeletonHTC, XR_TYPE_BODY_SKELETON_HTC) \ + _avail(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ + _avail(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \ + _avail(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \ + _avail(XrSystemBodyTrackingPropertiesBD, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_BD) \ + _avail(XrBodyTrackerCreateInfoBD, XR_TYPE_BODY_TRACKER_CREATE_INFO_BD) \ + _avail(XrBodyJointsLocateInfoBD, XR_TYPE_BODY_JOINTS_LOCATE_INFO_BD) \ + _avail(XrBodyJointLocationsBD, XR_TYPE_BODY_JOINT_LOCATIONS_BD) \ + _avail(XrSystemFacialSimulationPropertiesBD, XR_TYPE_SYSTEM_FACIAL_SIMULATION_PROPERTIES_BD) \ + _avail(XrFaceTrackerCreateInfoBD, XR_TYPE_FACE_TRACKER_CREATE_INFO_BD) \ + _avail(XrFacialSimulationDataGetInfoBD, XR_TYPE_FACIAL_SIMULATION_DATA_GET_INFO_BD) \ + _avail(XrFacialSimulationDataBD, XR_TYPE_FACIAL_SIMULATION_DATA_BD) \ + _avail(XrLipExpressionDataBD, XR_TYPE_LIP_EXPRESSION_DATA_BD) \ + _avail(XrSystemSpatialSensingPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_SENSING_PROPERTIES_BD) \ + _avail(XrSpatialEntityComponentGetInfoBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_GET_INFO_BD) \ + _avail(XrSpatialEntityLocationGetInfoBD, XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO_BD) \ + _avail(XrSpatialEntityComponentDataLocationBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_LOCATION_BD) \ + _avail(XrSpatialEntityComponentDataSemanticBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_SEMANTIC_BD) \ + _avail(XrSpatialEntityComponentDataBoundingBox2DBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_2D_BD) \ + _avail(XrSpatialEntityComponentDataPolygonBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_POLYGON_BD) \ + _avail(XrSpatialEntityComponentDataBoundingBox3DBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_BOUNDING_BOX_3D_BD) \ + _avail(XrSpatialEntityComponentDataTriangleMeshBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_TRIANGLE_MESH_BD) \ + _avail(XrSenseDataProviderCreateInfoBD, XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_BD) \ + _avail(XrSenseDataProviderStartInfoBD, XR_TYPE_SENSE_DATA_PROVIDER_START_INFO_BD) \ + _avail(XrEventDataSenseDataProviderStateChangedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED_BD) \ + _avail(XrEventDataSenseDataUpdatedBD, XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED_BD) \ + _avail(XrSenseDataQueryInfoBD, XR_TYPE_SENSE_DATA_QUERY_INFO_BD) \ + _avail(XrSenseDataQueryCompletionBD, XR_TYPE_SENSE_DATA_QUERY_COMPLETION_BD) \ + _avail(XrQueriedSenseDataGetInfoBD, XR_TYPE_QUERIED_SENSE_DATA_GET_INFO_BD) \ + _avail(XrSpatialEntityStateBD, XR_TYPE_SPATIAL_ENTITY_STATE_BD) \ + _avail(XrQueriedSenseDataBD, XR_TYPE_QUERIED_SENSE_DATA_BD) \ + _avail(XrSenseDataFilterUuidBD, XR_TYPE_SENSE_DATA_FILTER_UUID_BD) \ + _avail(XrSenseDataFilterSemanticBD, XR_TYPE_SENSE_DATA_FILTER_SEMANTIC_BD) \ + _avail(XrSpatialEntityAnchorCreateInfoBD, XR_TYPE_SPATIAL_ENTITY_ANCHOR_CREATE_INFO_BD) \ + _avail(XrAnchorSpaceCreateInfoBD, XR_TYPE_ANCHOR_SPACE_CREATE_INFO_BD) \ + _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \ + _avail(XrSystemSpatialAnchorPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_ANCHOR_PROPERTIES_BD) \ + _avail(XrSpatialAnchorCreateInfoBD, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_BD) \ + _avail(XrSpatialAnchorCreateCompletionBD, XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION_BD) \ + _avail(XrSpatialAnchorPersistInfoBD, XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO_BD) \ + _avail(XrSpatialAnchorUnpersistInfoBD, XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO_BD) \ + _avail(XrSystemSpatialAnchorSharingPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_ANCHOR_SHARING_PROPERTIES_BD) \ + _avail(XrSpatialAnchorShareInfoBD, XR_TYPE_SPATIAL_ANCHOR_SHARE_INFO_BD) \ + _avail(XrSharedSpatialAnchorDownloadInfoBD, XR_TYPE_SHARED_SPATIAL_ANCHOR_DOWNLOAD_INFO_BD) \ + _avail(XrSystemSpatialScenePropertiesBD, XR_TYPE_SYSTEM_SPATIAL_SCENE_PROPERTIES_BD) \ + _avail(XrSceneCaptureInfoBD, XR_TYPE_SCENE_CAPTURE_INFO_BD) \ + _avail(XrSystemSpatialMeshPropertiesBD, XR_TYPE_SYSTEM_SPATIAL_MESH_PROPERTIES_BD) \ + _avail(XrSenseDataProviderCreateInfoSpatialMeshBD, XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_MESH_BD) \ + _avail(XrFuturePollResultProgressBD, XR_TYPE_FUTURE_POLL_RESULT_PROGRESS_BD) \ + _avail(XrSystemSpatialPlanePropertiesBD, XR_TYPE_SYSTEM_SPATIAL_PLANE_PROPERTIES_BD) \ + _avail(XrSpatialEntityComponentDataPlaneOrientationBD, XR_TYPE_SPATIAL_ENTITY_COMPONENT_DATA_PLANE_ORIENTATION_BD) \ + _avail(XrSenseDataFilterPlaneOrientationBD, XR_TYPE_SENSE_DATA_FILTER_PLANE_ORIENTATION_BD) \ + _avail(XrSpatialAudioRendererCreateInfoBD, XR_TYPE_SPATIAL_AUDIO_RENDERER_CREATE_INFO_BD) \ + _avail(XrAudioBufferBD, XR_TYPE_AUDIO_BUFFER_BD) \ + _avail(XrSoundObjectDirectivityCardioidBD, XR_TYPE_SOUND_OBJECT_DIRECTIVITY_CARDIOID_BD) \ + _avail(XrSoundObjectShapeSphereBD, XR_TYPE_SOUND_OBJECT_SHAPE_SPHERE_BD) \ + _avail(XrSoundObjectDistanceAttenuationCurveBD, XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_CURVE_BD) \ + _avail(XrSoundObjectDistanceAttenuationBD, XR_TYPE_SOUND_OBJECT_DISTANCE_ATTENUATION_BD) \ + _avail(XrSoundObjectConfigBD, XR_TYPE_SOUND_OBJECT_CONFIG_BD) \ + _avail(XrSoundFieldConfigBD, XR_TYPE_SOUND_FIELD_CONFIG_BD) \ + _avail(XrSoundFieldChannelDefinitionSurroundBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_SURROUND_BD) \ + _avail(XrSoundFieldChannelDefinitionAmbixBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_AMBIX_BD) \ + _avail(XrSoundFieldChannelDefinitionFumaBD, XR_TYPE_SOUND_FIELD_CHANNEL_DEFINITION_FUMA_BD) \ + _avail(XrSoundTriangleMeshBD, XR_TYPE_SOUND_TRIANGLE_MESH_BD) \ + _avail(XrSoundObstacleConfigBD, XR_TYPE_SOUND_OBSTACLE_CONFIG_BD) \ + _avail(XrSoundObstacleMaterialConfigBD, XR_TYPE_SOUND_OBSTACLE_MATERIAL_CONFIG_BD) \ + _avail(XrHandTrackingDataSourceInfoEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT) \ + _avail(XrHandTrackingDataSourceStateEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT) \ + _avail(XrSystemPlaneDetectionPropertiesEXT, XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT) \ + _avail(XrPlaneDetectorCreateInfoEXT, XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT) \ + _avail(XrPlaneDetectorBeginInfoEXT, XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT) \ + _avail(XrPlaneDetectorGetInfoEXT, XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT) \ + _avail(XrPlaneDetectorLocationEXT, XR_TYPE_PLANE_DETECTOR_LOCATION_EXT) \ + _avail(XrPlaneDetectorLocationsEXT, XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT) \ + _avail(XrPlaneDetectorPolygonBufferEXT, XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT) \ + _avail(XrTrackableTrackerCreateInfoANDROID, XR_TYPE_TRACKABLE_TRACKER_CREATE_INFO_ANDROID) \ + _avail(XrTrackableGetInfoANDROID, XR_TYPE_TRACKABLE_GET_INFO_ANDROID) \ + _avail(XrTrackablePlaneANDROID, XR_TYPE_TRACKABLE_PLANE_ANDROID) \ + _avail(XrAnchorSpaceCreateInfoANDROID, XR_TYPE_ANCHOR_SPACE_CREATE_INFO_ANDROID) \ + _avail(XrSystemTrackablesPropertiesANDROID, XR_TYPE_SYSTEM_TRACKABLES_PROPERTIES_ANDROID) \ + _avail(XrSystemEyeTrackingPropertiesANDROID, XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_ANDROID) \ + _avail(XrEyesANDROID, XR_TYPE_EYES_ANDROID) \ + _avail(XrEyesGetInfoANDROID, XR_TYPE_EYES_GET_INFO_ANDROID) \ + _avail(XrEyeTrackerCreateInfoANDROID, XR_TYPE_EYE_TRACKER_CREATE_INFO_ANDROID) \ + _avail(XrDeviceAnchorPersistenceCreateInfoANDROID, XR_TYPE_DEVICE_ANCHOR_PERSISTENCE_CREATE_INFO_ANDROID) \ + _avail(XrPersistedAnchorSpaceCreateInfoANDROID, XR_TYPE_PERSISTED_ANCHOR_SPACE_CREATE_INFO_ANDROID) \ + _avail(XrPersistedAnchorSpaceInfoANDROID, XR_TYPE_PERSISTED_ANCHOR_SPACE_INFO_ANDROID) \ + _avail(XrSystemDeviceAnchorPersistencePropertiesANDROID, XR_TYPE_SYSTEM_DEVICE_ANCHOR_PERSISTENCE_PROPERTIES_ANDROID) \ + _avail(XrFaceTrackerCreateInfoANDROID, XR_TYPE_FACE_TRACKER_CREATE_INFO_ANDROID) \ + _avail(XrFaceStateGetInfoANDROID, XR_TYPE_FACE_STATE_GET_INFO_ANDROID) \ + _avail(XrFaceStateANDROID, XR_TYPE_FACE_STATE_ANDROID) \ + _avail(XrSystemFaceTrackingPropertiesANDROID, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_ANDROID) \ + _avail(XrSystemPassthroughCameraStatePropertiesANDROID, XR_TYPE_SYSTEM_PASSTHROUGH_CAMERA_STATE_PROPERTIES_ANDROID) \ + _avail(XrPassthroughCameraStateGetInfoANDROID, XR_TYPE_PASSTHROUGH_CAMERA_STATE_GET_INFO_ANDROID) \ + _avail(XrEventDataRecommendedResolutionChangedANDROID, XR_TYPE_EVENT_DATA_RECOMMENDED_RESOLUTION_CHANGED_ANDROID) \ + _avail(XrPassthroughLayerCreateInfoANDROID, XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_ANDROID) \ + _avail(XrPassthroughLayerMeshANDROID, XR_TYPE_PASSTHROUGH_LAYER_MESH_ANDROID) \ + _avail(XrCompositionLayerPassthroughANDROID, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_ANDROID) \ + _avail(XrSystemPassthroughLayerPropertiesANDROID, XR_TYPE_SYSTEM_PASSTHROUGH_LAYER_PROPERTIES_ANDROID) \ + _avail(XrRaycastInfoANDROID, XR_TYPE_RAYCAST_INFO_ANDROID) \ + _avail(XrRaycastHitResultsANDROID, XR_TYPE_RAYCAST_HIT_RESULTS_ANDROID) \ + _avail(XrPerformanceMetricsStateANDROID, XR_TYPE_PERFORMANCE_METRICS_STATE_ANDROID) \ + _avail(XrPerformanceMetricsCounterANDROID, XR_TYPE_PERFORMANCE_METRICS_COUNTER_ANDROID) \ + _avail(XrTrackableObjectANDROID, XR_TYPE_TRACKABLE_OBJECT_ANDROID) \ + _avail(XrTrackableObjectConfigurationANDROID, XR_TYPE_TRACKABLE_OBJECT_CONFIGURATION_ANDROID) \ + _avail(XrFutureCancelInfoEXT, XR_TYPE_FUTURE_CANCEL_INFO_EXT) \ + _avail(XrFuturePollInfoEXT, XR_TYPE_FUTURE_POLL_INFO_EXT) \ + _avail(XrFuturePollResultEXT, XR_TYPE_FUTURE_POLL_RESULT_EXT) \ + _avail(XrEventDataUserPresenceChangedEXT, XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT) \ + _avail(XrSystemUserPresencePropertiesEXT, XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT) \ + _avail(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \ + _avail(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \ + _avail(XrUserCalibrationEnableEventsInfoML, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML) \ + _avail(XrSystemNotificationsSetInfoML, XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML) \ + _avail(XrWorldMeshDetectorCreateInfoML, XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML) \ + _avail(XrWorldMeshBlockStateML, XR_TYPE_WORLD_MESH_BLOCK_STATE_ML) \ + _avail(XrWorldMeshStateRequestInfoML, XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML) \ + _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \ + _avail(XrWorldMeshBufferRecommendedSizeInfoML, XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML) \ + _avail(XrWorldMeshBufferSizeML, XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML) \ + _avail(XrWorldMeshBufferML, XR_TYPE_WORLD_MESH_BUFFER_ML) \ + _avail(XrWorldMeshBlockRequestML, XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML) \ + _avail(XrWorldMeshGetInfoML, XR_TYPE_WORLD_MESH_GET_INFO_ML) \ + _avail(XrWorldMeshBlockML, XR_TYPE_WORLD_MESH_BLOCK_ML) \ + _avail(XrWorldMeshRequestCompletionInfoML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML) \ + _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \ + _avail(XrSystemFacialExpressionPropertiesML, XR_TYPE_SYSTEM_FACIAL_EXPRESSION_PROPERTIES_ML) \ + _avail(XrFacialExpressionClientCreateInfoML, XR_TYPE_FACIAL_EXPRESSION_CLIENT_CREATE_INFO_ML) \ + _avail(XrFacialExpressionBlendShapeGetInfoML, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_GET_INFO_ML) \ + _avail(XrFacialExpressionBlendShapePropertiesML, XR_TYPE_FACIAL_EXPRESSION_BLEND_SHAPE_PROPERTIES_ML) \ + _avail(XrSystemBoundaryVisibilityPropertiesMETA, XR_TYPE_SYSTEM_BOUNDARY_VISIBILITY_PROPERTIES_META) \ + _avail(XrEventDataBoundaryVisibilityChangedMETA, XR_TYPE_EVENT_DATA_BOUNDARY_VISIBILITY_CHANGED_META) \ + _avail(XrSystemSimultaneousHandsAndControllersPropertiesMETA, XR_TYPE_SYSTEM_SIMULTANEOUS_HANDS_AND_CONTROLLERS_PROPERTIES_META) \ + _avail(XrSimultaneousHandsAndControllersTrackingResumeInfoMETA, XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_RESUME_INFO_META) \ + _avail(XrSimultaneousHandsAndControllersTrackingPauseInfoMETA, XR_TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_PAUSE_INFO_META) \ + _avail(XrFaceTrackingVisemesMETA, XR_TYPE_FACE_TRACKING_VISEMES_META) \ + _avail(XrSystemFaceTrackingVisemesPropertiesMETA, XR_TYPE_SYSTEM_FACE_TRACKING_VISEMES_PROPERTIES_META) \ + _avail(XrRoomMeshFaceIndicesMETA, XR_TYPE_ROOM_MESH_FACE_INDICES_META) \ + _avail(XrSpaceRoomMeshGetInfoMETA, XR_TYPE_SPACE_ROOM_MESH_GET_INFO_META) \ + _avail(XrRoomMeshMETA, XR_TYPE_ROOM_MESH_META) \ + _avail(XrColocationDiscoveryStartInfoMETA, XR_TYPE_COLOCATION_DISCOVERY_START_INFO_META) \ + _avail(XrColocationDiscoveryStopInfoMETA, XR_TYPE_COLOCATION_DISCOVERY_STOP_INFO_META) \ + _avail(XrColocationAdvertisementStartInfoMETA, XR_TYPE_COLOCATION_ADVERTISEMENT_START_INFO_META) \ + _avail(XrColocationAdvertisementStopInfoMETA, XR_TYPE_COLOCATION_ADVERTISEMENT_STOP_INFO_META) \ + _avail(XrEventDataStartColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_START_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataStopColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_STOP_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataColocationAdvertisementCompleteMETA, XR_TYPE_EVENT_DATA_COLOCATION_ADVERTISEMENT_COMPLETE_META) \ + _avail(XrEventDataStartColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_START_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataColocationDiscoveryResultMETA, XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_RESULT_META) \ + _avail(XrEventDataColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrEventDataStopColocationDiscoveryCompleteMETA, XR_TYPE_EVENT_DATA_STOP_COLOCATION_DISCOVERY_COMPLETE_META) \ + _avail(XrSystemColocationDiscoveryPropertiesMETA, XR_TYPE_SYSTEM_COLOCATION_DISCOVERY_PROPERTIES_META) \ + _avail(XrSystemSpatialEntityGroupSharingPropertiesMETA, XR_TYPE_SYSTEM_SPATIAL_ENTITY_GROUP_SHARING_PROPERTIES_META) \ + _avail(XrShareSpacesRecipientGroupsMETA, XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META) \ + _avail(XrSpaceGroupUuidFilterInfoMETA, XR_TYPE_SPACE_GROUP_UUID_FILTER_INFO_META) \ + _avail(XrSystemEnvironmentRaycastPropertiesMETA, XR_TYPE_SYSTEM_ENVIRONMENT_RAYCAST_PROPERTIES_META) \ + _avail(XrEnvironmentRaycasterCreateInfoMETA, XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_INFO_META) \ + _avail(XrEnvironmentRaycasterCreateCompletionMETA, XR_TYPE_ENVIRONMENT_RAYCASTER_CREATE_COMPLETION_META) \ + _avail(XrEnvironmentRaycastHitGetInfoMETA, XR_TYPE_ENVIRONMENT_RAYCAST_HIT_GET_INFO_META) \ + _avail(XrEnvironmentRaycastHitMETA, XR_TYPE_ENVIRONMENT_RAYCAST_HIT_META) \ + _avail(XrEnvironmentRaycastFilterDistanceMETA, XR_TYPE_ENVIRONMENT_RAYCAST_FILTER_DISTANCE_META) \ + _avail(XrTilePropertiesMETA, XR_TYPE_TILE_PROPERTIES_META) \ + _avail(XrTilePropertiesHintMETA, XR_TYPE_TILE_PROPERTIES_HINT_META) \ + _avail(XrSystemLightEstimationPropertiesANDROID, XR_TYPE_SYSTEM_LIGHT_ESTIMATION_PROPERTIES_ANDROID) \ + _avail(XrLightEstimatorCreateInfoANDROID, XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID) \ + _avail(XrLightEstimateGetInfoANDROID, XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID) \ + _avail(XrLightEstimateANDROID, XR_TYPE_LIGHT_ESTIMATE_ANDROID) \ + _avail(XrDirectionalLightANDROID, XR_TYPE_DIRECTIONAL_LIGHT_ANDROID) \ + _avail(XrAmbientLightANDROID, XR_TYPE_AMBIENT_LIGHT_ANDROID) \ + _avail(XrSphericalHarmonicsANDROID, XR_TYPE_SPHERICAL_HARMONICS_ANDROID) \ + _avail(XrSystemMarkerTrackingPropertiesANDROID, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_ANDROID) \ + _avail(XrTrackableMarkerConfigurationANDROID, XR_TYPE_TRACKABLE_MARKER_CONFIGURATION_ANDROID) \ + _avail(XrTrackableMarkerANDROID, XR_TYPE_TRACKABLE_MARKER_ANDROID) \ + _avail(XrSystemQrCodeTrackingPropertiesANDROID, XR_TYPE_SYSTEM_QR_CODE_TRACKING_PROPERTIES_ANDROID) \ + _avail(XrTrackableQrCodeConfigurationANDROID, XR_TYPE_TRACKABLE_QR_CODE_CONFIGURATION_ANDROID) \ + _avail(XrTrackableQrCodeANDROID, XR_TYPE_TRACKABLE_QR_CODE_ANDROID) \ + _avail(XrSystemImageTrackingPropertiesANDROID, XR_TYPE_SYSTEM_IMAGE_TRACKING_PROPERTIES_ANDROID) \ + _avail(XrTrackableImageDatabaseEntryANDROID, XR_TYPE_TRACKABLE_IMAGE_DATABASE_ENTRY_ANDROID) \ + _avail(XrTrackableImageDatabaseCreateInfoANDROID, XR_TYPE_TRACKABLE_IMAGE_DATABASE_CREATE_INFO_ANDROID) \ + _avail(XrCreateTrackableImageDatabaseCompletionANDROID, XR_TYPE_CREATE_TRACKABLE_IMAGE_DATABASE_COMPLETION_ANDROID) \ + _avail(XrTrackableImageConfigurationANDROID, XR_TYPE_TRACKABLE_IMAGE_CONFIGURATION_ANDROID) \ + _avail(XrTrackableImageANDROID, XR_TYPE_TRACKABLE_IMAGE_ANDROID) \ + _avail(XrEventDataImageTrackingLostANDROID, XR_TYPE_EVENT_DATA_IMAGE_TRACKING_LOST_ANDROID) \ + _avail(XrSystemSceneMeshingPropertiesANDROID, XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID) \ + _avail(XrSceneMeshingTrackerCreateInfoANDROID, XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID) \ + _avail(XrSceneMeshSnapshotCreateInfoANDROID, XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID) \ + _avail(XrSceneMeshSnapshotCreationResultANDROID, XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID) \ + _avail(XrSceneSubmeshStateANDROID, XR_TYPE_SCENE_SUBMESH_STATE_ANDROID) \ + _avail(XrSceneSubmeshDataANDROID, XR_TYPE_SCENE_SUBMESH_DATA_ANDROID) \ + _avail(XrSpatialCapabilityComponentTypesEXT, XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT) \ + _avail(XrSpatialContextCreateInfoEXT, XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT) \ + _avail(XrCreateSpatialContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT) \ + _avail(XrSpatialDiscoverySnapshotCreateInfoEXT, XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT) \ + _avail(XrCreateSpatialDiscoverySnapshotCompletionInfoEXT, XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT) \ + _avail(XrCreateSpatialDiscoverySnapshotCompletionEXT, XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT) \ + _avail(XrSpatialComponentDataQueryConditionEXT, XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT) \ + _avail(XrSpatialComponentDataQueryResultEXT, XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT) \ + _avail(XrSpatialBufferGetInfoEXT, XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT) \ + _avail(XrSpatialComponentBounded2DListEXT, XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT) \ + _avail(XrSpatialComponentBounded3DListEXT, XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT) \ + _avail(XrSpatialComponentParentListEXT, XR_TYPE_SPATIAL_COMPONENT_PARENT_LIST_EXT) \ + _avail(XrSpatialComponentMesh3DListEXT, XR_TYPE_SPATIAL_COMPONENT_MESH_3D_LIST_EXT) \ + _avail(XrSpatialEntityFromIdCreateInfoEXT, XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT) \ + _avail(XrSpatialUpdateSnapshotCreateInfoEXT, XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT) \ + _avail(XrEventDataSpatialDiscoveryRecommendedEXT, XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT) \ + _avail(XrSpatialFilterTrackingStateEXT, XR_TYPE_SPATIAL_FILTER_TRACKING_STATE_EXT) \ + _avail(XrSpatialCapabilityConfigurationPlaneTrackingEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT) \ + _avail(XrSpatialComponentPlaneAlignmentListEXT, XR_TYPE_SPATIAL_COMPONENT_PLANE_ALIGNMENT_LIST_EXT) \ + _avail(XrSpatialComponentMesh2DListEXT, XR_TYPE_SPATIAL_COMPONENT_MESH_2D_LIST_EXT) \ + _avail(XrSpatialComponentPolygon2DListEXT, XR_TYPE_SPATIAL_COMPONENT_POLYGON_2D_LIST_EXT) \ + _avail(XrSpatialComponentPlaneSemanticLabelListEXT, XR_TYPE_SPATIAL_COMPONENT_PLANE_SEMANTIC_LABEL_LIST_EXT) \ + _avail(XrStationaryReferenceSpaceGenerationIdGetInfoEXT, XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_GET_INFO_EXT) \ + _avail(XrStationaryReferenceSpaceGenerationIdResultEXT, XR_TYPE_STATIONARY_REFERENCE_SPACE_GENERATION_ID_RESULT_EXT) \ + _avail(XrSpatialCapabilityConfigurationQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT) \ + _avail(XrSpatialCapabilityConfigurationMicroQrCodeEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT) \ + _avail(XrSpatialCapabilityConfigurationArucoMarkerEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT) \ + _avail(XrSpatialCapabilityConfigurationAprilTagEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT) \ + _avail(XrSpatialMarkerSizeEXT, XR_TYPE_SPATIAL_MARKER_SIZE_EXT) \ + _avail(XrSpatialMarkerStaticOptimizationEXT, XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT) \ + _avail(XrSpatialComponentMarkerListEXT, XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT) \ + _avail(XrSpatialCapabilityConfigurationAnchorEXT, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT) \ + _avail(XrSpatialComponentAnchorListEXT, XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT) \ + _avail(XrSpatialAnchorCreateInfoEXT, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT) \ + _avail(XrSpatialPersistenceContextCreateInfoEXT, XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT) \ + _avail(XrCreateSpatialPersistenceContextCompletionEXT, XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT) \ + _avail(XrSpatialContextPersistenceConfigEXT, XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT) \ + _avail(XrSpatialDiscoveryPersistenceUuidFilterEXT, XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT) \ + _avail(XrSpatialComponentPersistenceListEXT, XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT) \ + _avail(XrSpatialEntityPersistInfoEXT, XR_TYPE_SPATIAL_ENTITY_PERSIST_INFO_EXT) \ + _avail(XrPersistSpatialEntityCompletionEXT, XR_TYPE_PERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ + _avail(XrSpatialEntityUnpersistInfoEXT, XR_TYPE_SPATIAL_ENTITY_UNPERSIST_INFO_EXT) \ + _avail(XrUnpersistSpatialEntityCompletionEXT, XR_TYPE_UNPERSIST_SPATIAL_ENTITY_COMPLETION_EXT) \ + _avail(XrSpatialCapabilityConfigurationObjectTrackingANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID) \ + _avail(XrSpatialComponentObjectSemanticLabelListANDROID, XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID) \ + _avail(XrSpatialCapabilityConfigurationDepthRaycastANDROID, XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID) \ + _avail(XrSpatialRaycastInfoANDROID, XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID) \ + _avail(XrSpatialComponentRaycastResultListANDROID, XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID) \ + _avail(XrSpatialRaycastSnapshotCreateInfoANDROID, XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID) \ + _avail(XrSpatialAnchorParentANDROID, XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID) \ + _avail(XrSpatialDiscoveryUniqueEntitiesFilterANDROID, XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID) \ + _avail(XrSpatialComponentSubsumedByListANDROID, XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID) \ + _avail(XrSpatialAnchorSpaceFromIdCreateInfoANDROID, XR_TYPE_SPATIAL_ANCHOR_SPACE_FROM_ID_CREATE_INFO_ANDROID) \ + _avail(XrBatteryStateDisplayEXT, XR_TYPE_BATTERY_STATE_DISPLAY_EXT) \ + _avail(XrLoaderInitInfoPropertiesEXT, XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT) \ + _avail(XrEventDataViewConfigurationViewsChangedEXT, XR_TYPE_EVENT_DATA_VIEW_CONFIGURATION_VIEWS_CHANGED_EXT) \ + + +#if defined(XR_USE_GRAPHICS_API_D3D11) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _avail(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \ + _avail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + _avail(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _unavail(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \ + _unavail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + _unavail(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_D3D12) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _avail(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \ + _avail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + _avail(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _unavail(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \ + _unavail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + _unavail(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_METAL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _avail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \ + _avail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + _avail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \ + _unavail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \ + _unavail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \ + _unavail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + _avail(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + _unavail(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WAYLAND) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WIN32) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XCB) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XLIB) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + _avail(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \ + _avail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + _unavail(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \ + _unavail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) && defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_VULKAN) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _avail(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \ + _avail(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \ + _avail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + _avail(XrGraphicsRequirementsVulkanKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR) \ + _avail(XrVulkanInstanceCreateInfoKHR, XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR) \ + _avail(XrVulkanDeviceCreateInfoKHR, XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR) \ + _avail(XrVulkanGraphicsDeviceGetInfoKHR, XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR) \ + _avail(XrSwapchainImageFoveationVulkanFB, XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB) \ + _avail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + _avail(XrVulkanSwapchainCreateInfoMETA, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _unavail(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \ + _unavail(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \ + _unavail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + _unavail(XrGraphicsRequirementsVulkanKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR) \ + _unavail(XrVulkanInstanceCreateInfoKHR, XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR) \ + _unavail(XrVulkanDeviceCreateInfoKHR, XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR) \ + _unavail(XrVulkanGraphicsDeviceGetInfoKHR, XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR) \ + _unavail(XrSwapchainImageFoveationVulkanFB, XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB) \ + _unavail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + _unavail(XrVulkanSwapchainCreateInfoMETA, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META) \ + +#endif + +#if defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \ + _avail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + _avail(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ + _avail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + _avail(XrAnchorSharingInfoANDROID, XR_TYPE_ANCHOR_SHARING_INFO_ANDROID) \ + _avail(XrAnchorSharingTokenANDROID, XR_TYPE_ANCHOR_SHARING_TOKEN_ANDROID) \ + _avail(XrSystemAnchorSharingExportPropertiesANDROID, XR_TYPE_SYSTEM_ANCHOR_SHARING_EXPORT_PROPERTIES_ANDROID) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \ + _unavail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + _unavail(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ + _unavail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + _unavail(XrAnchorSharingInfoANDROID, XR_TYPE_ANCHOR_SHARING_INFO_ANDROID) \ + _unavail(XrAnchorSharingTokenANDROID, XR_TYPE_ANCHOR_SHARING_TOKEN_ANDROID) \ + _unavail(XrSystemAnchorSharingExportPropertiesANDROID, XR_TYPE_SYSTEM_ANCHOR_SHARING_EXPORT_PROPERTIES_ANDROID) \ + +#endif + +#if defined(XR_USE_PLATFORM_EGL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _avail(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _unavail(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \ + +#endif + +#if defined(XR_USE_PLATFORM_ML) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ + _avail(XrCoordinateSpaceCreateInfoML, XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ + _unavail(XrCoordinateSpaceCreateInfoML, XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML) \ + +#endif + +#if defined(XR_USE_PLATFORM_WIN32) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _avail(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _unavail(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ + +#endif + + + + +#endif + From 34c3fdd35075408e0330533c0c2d710ba497e9bf Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 06:45:33 -0700 Subject: [PATCH 338/407] Added extended internal controller types --- src/joystick/SDL_joystick.c | 30 ++++++++++++------------------ src/joystick/controller_list.h | 24 +++++++++++++++++++----- src/joystick/controller_type.h | 8 ++++++-- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 1d3c32f3e5..f052e2d04a 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3122,6 +3122,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons type = SDL_GAMEPAD_TYPE_XBOX360; break; case k_eControllerType_XBoxOneController: + case k_eControllerType_XBoxEliteController: type = SDL_GAMEPAD_TYPE_XBOXONE; break; case k_eControllerType_PS3Controller: @@ -3131,6 +3132,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons type = SDL_GAMEPAD_TYPE_PS4; break; case k_eControllerType_PS5Controller: + case k_eControllerType_PS5EdgeController: type = SDL_GAMEPAD_TYPE_PS5; break; case k_eControllerType_XInputPS4Controller: @@ -3198,20 +3200,14 @@ bool SDL_JoystickGUIDUsesVersion(SDL_GUID guid) bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id) { EControllerType eType = GuessControllerType(vendor_id, product_id); - return eType == k_eControllerType_XBoxOneController; + return eType == k_eControllerType_XBoxOneController || + eType == k_eControllerType_XBoxEliteController; } bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id) { - if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE) { - return true; - } - } - return false; + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_XBoxEliteController; } bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) @@ -3250,17 +3246,14 @@ bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id) bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id) { EControllerType eType = GuessControllerType(vendor_id, product_id); - return eType == k_eControllerType_PS5Controller; + return eType == k_eControllerType_PS5Controller || + eType == k_eControllerType_PS5EdgeController; } bool SDL_IsJoystickDualSenseEdge(Uint16 vendor_id, Uint16 product_id) { - if (vendor_id == USB_VENDOR_SONY) { - if (product_id == USB_PRODUCT_SONY_DS5_EDGE) { - return true; - } - } - return false; + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_PS5EdgeController; } bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id) @@ -3345,7 +3338,8 @@ bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id) bool SDL_IsJoystickHoriSteamController(Uint16 vendor_id, Uint16 product_id) { - return vendor_id == USB_VENDOR_HORI && (product_id == USB_PRODUCT_HORI_STEAM_CONTROLLER || product_id == USB_PRODUCT_HORI_STEAM_CONTROLLER_BT); + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_HoriSteamController; } bool SDL_IsJoystickSInputController(Uint16 vendor_id, Uint16 product_id) diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index 4c6b54ce02..7b53741a53 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -175,7 +175,6 @@ static const ControllerDescription_t arrControllers[] = { // { MAKE_CONTROLLER_ID( 0x7545, 0x1122 ), k_eControllerType_PS4Controller, NULL }, // Giotek VX4 - trackpad/gyro don't work. Had to not filter on interface info. Light bar is flaky, but works. { MAKE_CONTROLLER_ID( 0x054c, 0x0ce6 ), k_eControllerType_PS5Controller, NULL }, // Sony DualSense Controller - { MAKE_CONTROLLER_ID( 0x054c, 0x0df2 ), k_eControllerType_PS5Controller, NULL }, // Sony DualSense Edge Controller { MAKE_CONTROLLER_ID( 0x054c, 0x0e5f ), k_eControllerType_PS5Controller, NULL }, // Access Controller for PS5 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0209 ), k_eControllerType_PS5Controller, NULL }, // Victrix Pro FS PS4/PS5 (PS5 mode) { MAKE_CONTROLLER_ID( 0x0f0d, 0x0163 ), k_eControllerType_PS5Controller, NULL }, // HORI Fighting Commander OCTA @@ -364,19 +363,15 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft Xbox One Controller { MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft Xbox One Controller (Firmware 2015) { MAKE_CONTROLLER_ID( 0x045e, 0x02e0 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft Xbox One S Controller (Bluetooth) - { MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft Xbox One Elite Controller { MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft Xbox One S Controller { MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft Xbox One S Controller (Bluetooth) { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft Xbox One Controller with XBOXGIP driver on Windows - { MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller - { MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller (Bluetooth) { MAKE_CONTROLLER_ID( 0x045e, 0x0b0a ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft Xbox Adaptive Controller { MAKE_CONTROLLER_ID( 0x045e, 0x0b0c ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft Xbox Adaptive Controller (Bluetooth) { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft Xbox Series X Controller { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft Xbox Series X Controller (BLE) { MAKE_CONTROLLER_ID( 0x045e, 0x0b20 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft Xbox One S Controller (BLE) { MAKE_CONTROLLER_ID( 0x045e, 0x0b21 ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft Xbox Adaptive Controller (BLE) - { MAKE_CONTROLLER_ID( 0x045e, 0x0b22 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller (BLE) { MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One @@ -645,6 +640,22 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x33dd, 0x0003 ), k_eControllerType_SwitchInputOnlyController, NULL }, // ZUIKI MasCon for Nintendo Switch Red { MAKE_CONTROLLER_ID( 0x0f0d, 0x00f0 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Taiko Controller For Switch + { MAKE_CONTROLLER_ID( 0x054c, 0x0df2 ), k_eControllerType_PS5EdgeController, NULL }, // Sony DualSense Edge Controller + + { MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxEliteController, "Xbox One Elite Controller" }, // Microsoft Xbox One Elite Controller + { MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxEliteController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller + { MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxEliteController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b22 ), k_eControllerType_XBoxEliteController, "Xbox One Elite 2 Controller" }, // Microsoft Xbox One Elite Series 2 Controller (BLE) + + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6000 ), k_eControllerType_8BitDoController, "8Bitdo SF30 Controller" }, // 8BitDo SF30 Pro Controller in Steam Mode + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6100 ), k_eControllerType_8BitDoController, "8Bitdo SF30 Controller" }, // 8BitDo SF30 Pro Controller in Steam Mode (Bluetooth) + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6001 ), k_eControllerType_8BitDoController, "8Bitdo SN30 Controller" }, // 8BitDo SN30 Pro Controller in Steam Mode + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6101 ), k_eControllerType_8BitDoController, "8Bitdo SN30 Controller" }, // 8BitDo SN30 Pro Controller in Steam Mode (Bluetooth) + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6003 ), k_eControllerType_8BitDoController, "8Bitdo Pro 2 Controller" }, // 8BitDo Pro 2 Controller in Steam Mode + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6006 ), k_eControllerType_8BitDoController, "8Bitdo Pro 2 Controller" }, // 8BitDo Pro 2 Controller in Steam Mode + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6009 ), k_eControllerType_8BitDoController, "8Bitdo Pro 3 Controller" }, // 8BitDo Pro 3 Controller in Steam Mode (Bluetooth) + { MAKE_CONTROLLER_ID( 0x2dc8, 0x6012 ), k_eControllerType_8BitDoController, "8Bitdo Ultimate 2 Wireless Controller" }, // 8BitDo Ultimate 2 Wireless Controller in Steam Mode (Bluetooth) + // Valve products { MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch, NULL }, // Streaming mobile touch virtual controls { MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController, NULL }, // Valve Legacy Steam Controller (CHELL) @@ -660,4 +671,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x28de, 0x1303 ), k_eControllerType_SteamControllerTriton, NULL }, // Valve Steam Triton Controller (BLE) { MAKE_CONTROLLER_ID( 0x28de, 0x1304 ), k_eControllerType_SteamControllerTriton, NULL }, // Valve Steam Proteus Dongle (Proprietary) { MAKE_CONTROLLER_ID( 0x28de, 0x1305 ), k_eControllerType_SteamControllerTriton, NULL }, // Valve Steam Nereid Dongle (Proprietary) + + { MAKE_CONTROLLER_ID( 0x0f0d, 0x01AB ), k_eControllerType_HoriSteamController, NULL }, // HORI Wireless HORIPAD for Steam + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0196 ), k_eControllerType_HoriSteamController, NULL }, // HORI Wireless HORIPAD for Steam ( BT ) }; diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h index bb94840aff..cc49ae6f3c 100644 --- a/src/joystick/controller_type.h +++ b/src/joystick/controller_type.h @@ -25,7 +25,7 @@ #endif //----------------------------------------------------------------------------- -// Purpose: Steam Controller models +// Purpose: Steam Controller models // WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN A DATABASE //----------------------------------------------------------------------------- typedef enum @@ -58,7 +58,11 @@ typedef enum k_eControllerType_MobileTouch = 43, k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Nintendo Switch style controllers as using XInput instead of the Nintendo Switch protocol k_eControllerType_PS5Controller = 45, - k_eControllerType_XInputPS4Controller = 46, // Client-side only, used to mark DualShock 4 style controllers using XInput instead of the DualShock 4 controller protocol + k_eControllerType_XBoxEliteController = 46, + k_eControllerType_XInputPS4Controller = 47, // Client-side only, used to mark DualShock 4 style controllers using XInput instead of the DualShock 4 controller protocol + k_eControllerType_PS5EdgeController = 48, + k_eControllerType_HoriSteamController = 49, + k_eControllerType_8BitDoController = 50, k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value // Keyboards and Mice From 984fcdaa8a7855516a8b84016c0c253680bec3af Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Sun, 17 May 2026 07:21:08 -0700 Subject: [PATCH 339/407] testcontroller: free/allocate touchpads only when needed --- test/gamepadutils.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/gamepadutils.c b/test/gamepadutils.c index 4da9522d16..6fff0b419b 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -706,6 +706,7 @@ static void FreeTouchpads(GamepadImage *ctx) void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) { int i; + int num_touchpads; if (!ctx) { return; @@ -763,9 +764,12 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) ctx->connection_state = SDL_GetGamepadConnectionState(gamepad); ctx->battery_state = SDL_GetGamepadPowerInfo(gamepad, &ctx->battery_percent); - FreeTouchpads(ctx); - ctx->num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); - ctx->num_touchpads = SDL_min(ctx->num_touchpads, MAX_TOUCHPADS); + num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); + num_touchpads = SDL_min(num_touchpads, MAX_TOUCHPADS); + if (num_touchpads != ctx->num_touchpads) { + FreeTouchpads(ctx); + ctx->num_touchpads = num_touchpads; + } if (ctx->num_touchpads > 0) { ctx->touchpads = (GamepadTouchpad *)SDL_malloc(sizeof(*ctx->touchpads) * ctx->num_touchpads); if (ctx->touchpads) { From 5b98c1cc2f598115906c9c1f2758d3d256913468 Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Sun, 17 May 2026 08:26:29 -0700 Subject: [PATCH 340/407] Add capacitive sense gamepad events (#15627) --- include/SDL3/SDL_events.h | 20 ++++ include/SDL3/SDL_gamepad.h | 48 ++++++++++ src/dynapi/SDL_dynapi.exports | 2 + src/dynapi/SDL_dynapi.sym | 2 + src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 2 + src/events/SDL_categories.c | 4 + src/events/SDL_categories_c.h | 1 + src/events/SDL_events.c | 12 +++ src/joystick/SDL_gamepad.c | 50 +++++++++- src/joystick/SDL_gamepad_db.h | 2 +- src/joystick/SDL_joystick.c | 67 +++++++++++++ src/joystick/SDL_joystick_c.h | 2 + src/joystick/SDL_sysjoystick.h | 9 ++ src/joystick/hidapi/SDL_hidapi_steam_hori.c | 10 +- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 25 ++--- src/joystick/hidapi/SDL_hidapi_steamdeck.c | 13 +-- src/test/SDL_test_common.c | 27 ++++++ test/CMakeLists.txt | 3 +- test/gamepad_grip_sense.h | 73 ++++++++++++++ test/gamepad_grip_sense.png | Bin 0 -> 837 bytes test/gamepadutils.c | 90 ++++++++++++++++++ test/gamepadutils.h | 9 ++ test/testcontroller.c | 10 ++ test/testutils.c | 1 + 25 files changed, 457 insertions(+), 27 deletions(-) create mode 100644 test/gamepad_grip_sense.h create mode 100644 test/gamepad_grip_sense.png diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index ed6950ad3b..dd822ecc71 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -212,6 +212,8 @@ typedef enum SDL_EventType SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */ SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete */ SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED, /**< Gamepad Steam handle has changed */ + SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH, /**< Gamepad capsense was touched */ + SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE, /**< Gamepad capsense was released */ /* Touch events */ SDL_EVENT_FINGER_DOWN = 0x700, @@ -711,6 +713,23 @@ typedef struct SDL_GamepadSensorEvent Uint64 sensor_timestamp; /**< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock */ } SDL_GamepadSensorEvent; +/** + * Gamepad capsense event structure (event.gcapsense.*) + * + * \since This struct is available since SDL 3.6.0. + */ +typedef struct SDL_GamepadCapSenseEvent +{ + SDL_EventType type; /**< SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH or SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE */ + Uint32 reserved; + Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 capsense; /**< The capsense type (SDL_GamepadCapSenseType) */ + bool down; /**< true if the capsense is touched */ + Uint8 padding1; + Uint8 padding2; +} SDL_GamepadCapSenseEvent; + /** * Audio device event structure (event.adevice.*) * @@ -1040,6 +1059,7 @@ typedef union SDL_Event SDL_GamepadButtonEvent gbutton; /**< Gamepad button event data */ SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */ SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor event data */ + SDL_GamepadCapSenseEvent gcapsense; /**< Gamepad capsense event data */ SDL_AudioDeviceEvent adevice; /**< Audio device event data */ SDL_CameraDeviceEvent cdevice; /**< Camera device event data */ SDL_SensorEvent sensor; /**< Sensor event data */ diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index 9c88a770ae..2d0e83440a 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -231,6 +231,24 @@ typedef enum SDL_GamepadAxis SDL_GAMEPAD_AXIS_COUNT } SDL_GamepadAxis; +/** + * The list of capsense types on a gamepad + * + * \since This enum is available since SDL 3.6.0. + * + * \sa SDL_GamepadHasCapSense + * \sa SDL_GetGamepadCapSense + */ +typedef enum SDL_GamepadCapSenseType +{ + SDL_GAMEPAD_CAPSENSE_INVALID = -1, + SDL_GAMEPAD_CAPSENSE_LEFT_STICK, /**< Activated by touching the top of the left thumbstick */ + SDL_GAMEPAD_CAPSENSE_RIGHT_STICK, /**< Activated by touching the top of the right thumbstick */ + SDL_GAMEPAD_CAPSENSE_LEFT_GRIP, /**< Activated by gripping the left handle of the controller */ + SDL_GAMEPAD_CAPSENSE_RIGHT_GRIP, /**< Activated by gripping the right handle of the controller */ + SDL_GAMEPAD_CAPSENSE_COUNT +} SDL_GamepadCapSenseType; + /** * Types of gamepad control bindings. * @@ -1510,6 +1528,36 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetGamepadSensorDataRate(SDL_Gamepad *game */ extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadSensorData(SDL_Gamepad *gamepad, SDL_SensorType type, float *data, int num_values); +/** + * Return whether a gamepad has a particular capsense. + * + * \param gamepad the gamepad to query. + * \param type the type of capsense to query. + * \returns true if the capsense exists, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.6.0. + * + * \sa SDL_GetGamepadCapSense + */ +extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasCapSense(SDL_Gamepad *gamepad, SDL_GamepadCapSenseType type); + +/** + * Get the current state of a capsense on a gamepad. + * + * \param gamepad a gamepad. + * \param type the type of capsense to query. + * \returns true if the capsense is touched, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.6.0. + * + * \sa SDL_GamepadHasCapSense + */ +extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadCapSense(SDL_Gamepad *gamepad, SDL_GamepadCapSenseType type); + /** * Start a rumble effect on a gamepad. * diff --git a/src/dynapi/SDL_dynapi.exports b/src/dynapi/SDL_dynapi.exports index 32e9fbff86..9864557071 100644 --- a/src/dynapi/SDL_dynapi.exports +++ b/src/dynapi/SDL_dynapi.exports @@ -1288,3 +1288,5 @@ _SDL_IsPhone _SDL_LoadJPG_IO _SDL_LoadJPG _SDL_HasSVE2 +_SDL_GamepadHasCapSense +_SDL_GetGamepadCapSense diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index ca1a1c97d9..3958a52aa6 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1289,6 +1289,8 @@ SDL3_0.0.0 { SDL_LoadJPG_IO; SDL_LoadJPG; SDL_HasSVE2; + SDL_GamepadHasCapSense; + SDL_GetGamepadCapSense; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 677768ff2f..b54d32ae6d 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1315,3 +1315,5 @@ #define SDL_LoadJPG_IO SDL_LoadJPG_IO_REAL #define SDL_LoadJPG SDL_LoadJPG_REAL #define SDL_HasSVE2 SDL_HasSVE2_REAL +#define SDL_GamepadHasCapSense SDL_GamepadHasCapSense_REAL +#define SDL_GetGamepadCapSense SDL_GetGamepadCapSense_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 99899b346e..4f8ac0ba0c 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1323,3 +1323,5 @@ SDL_DYNAPI_PROC(bool,SDL_IsPhone,(void),(),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG_IO,(SDL_IOStream *a,bool b),(a,b),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG,(const char *a),(a),return) SDL_DYNAPI_PROC(bool,SDL_HasSVE2,(void),(),return) +SDL_DYNAPI_PROC(bool,SDL_GamepadHasCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return) +SDL_DYNAPI_PROC(bool,SDL_GetGamepadCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return) diff --git a/src/events/SDL_categories.c b/src/events/SDL_categories.c index fa120775b2..9d7722923b 100644 --- a/src/events/SDL_categories.c +++ b/src/events/SDL_categories.c @@ -134,6 +134,10 @@ SDL_EventCategory SDL_GetEventCategory(Uint32 type) case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: return SDL_EVENTCATEGORY_GSENSOR; + case SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH: + case SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE: + return SDL_EVENTCATEGORY_GCAPSENSE; + case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_CANCELED: diff --git a/src/events/SDL_categories_c.h b/src/events/SDL_categories_c.h index a1259e0e90..a3762746d5 100644 --- a/src/events/SDL_categories_c.h +++ b/src/events/SDL_categories_c.h @@ -49,6 +49,7 @@ typedef enum SDL_EventCategory SDL_EVENTCATEGORY_GBUTTON, SDL_EVENTCATEGORY_GTOUCHPAD, SDL_EVENTCATEGORY_GSENSOR, + SDL_EVENTCATEGORY_GCAPSENSE, SDL_EVENTCATEGORY_ADEVICE, SDL_EVENTCATEGORY_CDEVICE, SDL_EVENTCATEGORY_SENSOR, diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 315a8b6d90..19f5a85adc 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -758,6 +758,18 @@ int SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen) event->gsensor.data[0], event->gsensor.data[1], event->gsensor.data[2]); break; +#define PRINT_CAPSENSE_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " which=%d capsense=%u state=%s)", \ + event->gcapsense.timestamp, (int)event->gcapsense.which, \ + event->gcapsense.capsense, event->gcapsense.down ? "touch" : "release") + SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH) + PRINT_CAPSENSE_EVENT(event); + break; + SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE) + PRINT_CAPSENSE_EVENT(event); + break; +#undef PRINT_CAPSENSE_EVENT + #define PRINT_FINGER_EVENT(event) \ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " touchid=%" SDL_PRIu64 " fingerid=%" SDL_PRIu64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \ event->tfinger.timestamp, event->tfinger.touchID, \ diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 3b0b86fdfb..b9c3ade4f0 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1254,10 +1254,10 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b12,", sizeof(mapping_string)); } else if (SDL_IsJoystickSteamDeck(vendor, product)) { // The Steam Deck's built-in controller has QAM, 4 back buttons, L/R trackpads, and L/R capacitive touch sticks - SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16", sizeof(mapping_string)); } else if (SDL_IsJoystickSteamTriton(vendor, product)) { // Second generation Steam controllers have 4 back paddle buttons - SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18,misc5:b21,misc6:b20", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16", sizeof(mapping_string)); } else if (SDL_IsJoystickNintendoSwitchPro(vendor, product) || SDL_IsJoystickNintendoSwitchProInputOnly(vendor, product)) { // Nintendo Switch Pro controllers have a screenshot button @@ -1281,7 +1281,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) } } else if (SDL_IsJoystickHoriSteamController(vendor, product)) { /* The Wireless HORIPad for Steam has QAM, Steam, Capsense L/R Sticks, 2 rear buttons, and 2 misc buttons */ - SDL_strlcat(mapping_string, "paddle1:b13,paddle2:b12,paddle3:b15,paddle4:b14,misc1:b11,misc3:b16,misc4:b17", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "paddle1:b13,paddle2:b12,paddle3:b15,paddle4:b14,misc1:b11", sizeof(mapping_string)); } else if (SDL_IsJoystickFlydigiController(vendor, product)) { SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b12,paddle3:b13,paddle4:b14,", sizeof(mapping_string)); if (guid.data[15] >= SDL_FLYDIGI_VADER2) { @@ -3952,6 +3952,48 @@ bool SDL_GetGamepadSensorData(SDL_Gamepad *gamepad, SDL_SensorType type, float * return SDL_Unsupported(); } +bool SDL_GamepadHasCapSense(SDL_Gamepad *gamepad, SDL_GamepadCapSenseType type) +{ + bool result = false; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad); + if (joystick) { + for (int i = 0; i < joystick->ncapsenses; ++i) { + if (joystick->capsenses[i].type == type) { + result = true; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return result; +} + +bool SDL_GetGamepadCapSense(SDL_Gamepad *gamepad, SDL_GamepadCapSenseType type) +{ + bool result = false; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad); + if (joystick) { + for (int i = 0; i < joystick->ncapsenses; ++i) { + if (joystick->capsenses[i].type == type) { + result = joystick->capsenses[i].down; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return result; +} + SDL_JoystickID SDL_GetGamepadID(SDL_Gamepad *gamepad) { SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad); @@ -4470,6 +4512,8 @@ static const Uint32 SDL_gamepad_event_list[] = { SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, SDL_EVENT_GAMEPAD_TOUCHPAD_UP, SDL_EVENT_GAMEPAD_SENSOR_UPDATE, + SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH, + SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE, }; void SDL_SetGamepadEventsEnabled(bool enabled) diff --git a/src/joystick/SDL_gamepad_db.h b/src/joystick/SDL_gamepad_db.h index 5859e6d373..6b1a954098 100644 --- a/src/joystick/SDL_gamepad_db.h +++ b/src/joystick/SDL_gamepad_db.h @@ -723,7 +723,7 @@ static const char *s_GamepadMappings[] = { "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", - "03000000de2800000512000000016800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,misc3:b19,misc4:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000de2800000512000000016800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,touchpad:b17,misc2:b16,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,", "03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index f052e2d04a..746cb04690 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -2441,6 +2441,26 @@ void SDL_PrivateJoystickSensorRate(SDL_Joystick *joystick, SDL_SensorType type, } } +void SDL_PrivateJoystickAddCapSense(SDL_Joystick *joystick, SDL_GamepadCapSenseType type) +{ + int ncapsenses; + SDL_JoystickCapSenseInfo *capsenses; + + SDL_AssertJoysticksLocked(); + + ncapsenses = joystick->ncapsenses + 1; + capsenses = (SDL_JoystickCapSenseInfo *)SDL_realloc(joystick->capsenses, (ncapsenses * sizeof(SDL_JoystickCapSenseInfo))); + if (capsenses) { + SDL_JoystickCapSenseInfo *capsense = &capsenses[ncapsenses - 1]; + + capsense->type = type; + capsense->down = false; + + joystick->ncapsenses = ncapsenses; + joystick->capsenses = capsenses; + } +} + void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id) { SDL_JoystickDriver *driver; @@ -3952,6 +3972,53 @@ void SDL_SendJoystickSensor(Uint64 timestamp, SDL_Joystick *joystick, SDL_Sensor } } +void SDL_SendJoystickCapSense(Uint64 timestamp, SDL_Joystick *joystick, SDL_GamepadCapSenseType type, bool down) +{ + SDL_AssertJoysticksLocked(); + + // We ignore events if we don't have keyboard focus, except for button + // (capsense) release + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (down) { + return; + } + } + + for (int i = 0; i < joystick->ncapsenses; ++i) { + SDL_JoystickCapSenseInfo *capsense = &joystick->capsenses[i]; + + if (capsense->type == type) { + SDL_Event event; + + // Ignore duplicate events + if (down == capsense->down) { + return; + } + + // Update internal joystick state + capsense->down = down; + joystick->update_complete = timestamp; + + if (down) { + event.type = SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH; + } else { + event.type = SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE; + } + + // Post the event, if desired + if (SDL_EventEnabled(event.type)) { + event.common.timestamp = timestamp; + event.gcapsense.which = joystick->instance_id; + event.gcapsense.capsense = type; + event.gcapsense.down = down; + SDL_PushEvent(&event); + } + + break; + } + } +} + static void SDL_LoadVIDPIDListFromHint(const char *hint, int *num_entries, int *max_entries, Uint32 **entries) { Uint32 entry; diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 62e1f9f865..b80fb6b651 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -181,6 +181,7 @@ extern bool SDL_ShouldIgnoreJoystick(Uint16 vendor_id, Uint16 product_id, Uint16 extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers); extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate); extern void SDL_PrivateJoystickSensorRate(SDL_Joystick *joystick, SDL_SensorType type, float rate); +extern void SDL_PrivateJoystickAddCapSense(SDL_Joystick *joystick, SDL_GamepadCapSenseType type); extern void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id); extern bool SDL_IsJoystickBeingAdded(void); extern void SDL_PrivateJoystickRemoved(SDL_JoystickID instance_id); @@ -191,6 +192,7 @@ extern void SDL_SendJoystickHat(Uint64 timestamp, SDL_Joystick *joystick, Uint8 extern void SDL_SendJoystickButton(Uint64 timestamp, SDL_Joystick *joystick, Uint8 button, bool down); extern void SDL_SendJoystickTouchpad(Uint64 timestamp, SDL_Joystick *joystick, int touchpad, int finger, bool down, float x, float y, float pressure); extern void SDL_SendJoystickSensor(Uint64 timestamp, SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values); +extern void SDL_SendJoystickCapSense(Uint64 timestamp, SDL_Joystick *joystick, SDL_GamepadCapSenseType type, bool down); extern void SDL_SendJoystickPowerInfo(SDL_Joystick *joystick, SDL_PowerState state, int percent); // Function to get the Steam virtual gamepad info for a joystick diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 15659b8cc0..76bce9006d 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -72,6 +72,12 @@ typedef struct SDL_JoystickSensorInfo float data[3]; // If this needs to expand, update SDL_GamepadSensorEvent } SDL_JoystickSensorInfo; +typedef struct SDL_JoystickCapSenseInfo +{ + SDL_GamepadCapSenseType type; + bool down; +} SDL_JoystickCapSenseInfo; + #define _guarded SDL_GUARDED_BY(SDL_joystick_lock) struct SDL_Joystick @@ -105,6 +111,9 @@ struct SDL_Joystick int nsensors_enabled _guarded; SDL_JoystickSensorInfo *sensors _guarded; + int ncapsenses _guarded; // Number of capsense sources on the joystick + SDL_JoystickCapSenseInfo *capsenses _guarded; // Current capsense states + Uint16 low_frequency_rumble _guarded; Uint16 high_frequency_rumble _guarded; Uint64 rumble_expiration _guarded; diff --git a/src/joystick/hidapi/SDL_hidapi_steam_hori.c b/src/joystick/hidapi/SDL_hidapi_steam_hori.c index c30b7cef0c..c24602f7fe 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_hori.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_hori.c @@ -39,8 +39,6 @@ enum SDL_GAMEPAD_BUTTON_HORI_FL, SDL_GAMEPAD_BUTTON_HORI_M1, SDL_GAMEPAD_BUTTON_HORI_M2, - SDL_GAMEPAD_BUTTON_HORI_JOYSTICK_TOUCH_L, - SDL_GAMEPAD_BUTTON_HORI_JOYSTICK_TOUCH_R, SDL_GAMEPAD_NUM_HORI_BUTTONS }; @@ -133,6 +131,10 @@ static bool HIDAPI_DriverSteamHori_OpenJoystick(SDL_HIDAPI_Device *device, SDL_J const Uint64 sensorupdatestep_ms = ctx->wireless ? 8333 : 4000; // Equivalent to 120hz / 250hz respectively ctx->simulated_sensor_step_ns = SDL_US_TO_NS(sensorupdatestep_ms); + + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK); + return true; } @@ -273,8 +275,8 @@ static void HIDAPI_DriverSteamHori_HandleStatePacket(SDL_Joystick *joystick, SDL SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[7] & 0x02) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[7] & 0x04) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_HORI_M2, ((data[7] & 0x08) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_HORI_JOYSTICK_TOUCH_L, ((data[7] & 0x10) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_HORI_JOYSTICK_TOUCH_R, ((data[7] & 0x20) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK, ((data[7] & 0x10) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK, ((data[7] & 0x20) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_HORI_FR, ((data[7] & 0x40) != 0)); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_HORI_FL, ((data[7] & 0x80) != 0)); } diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index f1c5881229..97152d359c 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -47,10 +47,6 @@ enum SDL_GAMEPAD_BUTTON_TRITON_LEFT_PADDLE2, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_TOUCHPAD, SDL_GAMEPAD_BUTTON_TRITON_LEFT_TOUCHPAD, - SDL_GAMEPAD_BUTTON_TRITON_RIGHT_JOYSTICK_TOUCH, - SDL_GAMEPAD_BUTTON_TRITON_LEFT_JOYSTICK_TOUCH, - SDL_GAMEPAD_BUTTON_TRITON_RIGHT_GRIP_TOUCH, - SDL_GAMEPAD_BUTTON_TRITON_LEFT_GRIP_TOUCH, SDL_GAMEPAD_NUM_TRITON_BUTTONS, }; @@ -187,15 +183,15 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_TOUCHPAD, ((pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_CLICK) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_JOYSTICK_TOUCH, - ((pTritonReport->buttons & TRITON_RIGHT_JOYSTICK_TOUCH) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_JOYSTICK_TOUCH, - ((pTritonReport->buttons & TRITON_LEFT_JOYSTICK_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK, + ((pTritonReport->buttons & TRITON_RIGHT_JOYSTICK_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK, + ((pTritonReport->buttons & TRITON_LEFT_JOYSTICK_TOUCH) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_RIGHT_GRIP_TOUCH, - ((pTritonReport->buttons & TRITON_RIGHT_GRIP_TOUCH) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_TRITON_LEFT_GRIP_TOUCH, - ((pTritonReport->buttons & TRITON_LEFT_GRIP_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_GRIP, + ((pTritonReport->buttons & TRITON_RIGHT_GRIP_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_LEFT_GRIP, + ((pTritonReport->buttons & TRITON_LEFT_GRIP_TOUCH) != 0)); if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_UP) { hat |= SDL_HAT_UP; @@ -480,6 +476,11 @@ static bool HIDAPI_DriverSteamTriton_OpenJoystick(SDL_HIDAPI_Device *device, SDL SDL_PrivateJoystickAddTouchpad(joystick, 1); SDL_PrivateJoystickAddTouchpad(joystick, 1); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_LEFT_GRIP); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_GRIP); + return true; } diff --git a/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/src/joystick/hidapi/SDL_hidapi_steamdeck.c index 92ca8402a9..286b7c97ea 100644 --- a/src/joystick/hidapi/SDL_hidapi_steamdeck.c +++ b/src/joystick/hidapi/SDL_hidapi_steamdeck.c @@ -41,8 +41,6 @@ enum SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_TOUCHPAD, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_TOUCHPAD, - SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_JOYSTICK_TOUCH, - SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_JOYSTICK_TOUCH, SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS, }; @@ -202,10 +200,10 @@ static void HIDAPI_DriverSteamDeck_HandleState(SDL_HIDAPI_Device *device, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_TOUCHPAD, ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_LEFT_PAD) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_JOYSTICK_TOUCH, - ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_RSTICK_TOUCH) != 0)); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_JOYSTICK_TOUCH, - ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_LSTICK_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK, + ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_RSTICK_TOUCH) != 0)); + SDL_SendJoystickCapSense(timestamp, joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK, + ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_LSTICK_TOUCH) != 0)); if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) { hat |= SDL_HAT_UP; @@ -397,6 +395,9 @@ static bool HIDAPI_DriverSteamDeck_OpenJoystick(SDL_HIDAPI_Device *device, SDL_J SDL_PrivateJoystickAddTouchpad(joystick, 1); SDL_PrivateJoystickAddTouchpad(joystick, 1); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_LEFT_STICK); + SDL_PrivateJoystickAddCapSense(joystick, SDL_GAMEPAD_CAPSENSE_RIGHT_STICK); + return true; } diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 460d05d027..ee324a7a35 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -1582,6 +1582,23 @@ static const char *GamepadButtonName(const SDL_GamepadButton button) } } +static const char *CapSenseName(const SDL_GamepadCapSenseType type) +{ + switch (type) { +#define CAPSENSE_CASE(cap) \ + case SDL_GAMEPAD_CAPSENSE_##cap: \ + return #cap + CAPSENSE_CASE(INVALID); + CAPSENSE_CASE(LEFT_STICK); + CAPSENSE_CASE(RIGHT_STICK); + CAPSENSE_CASE(LEFT_GRIP); + CAPSENSE_CASE(RIGHT_GRIP); +#undef CAPSENSE_CASE + default: + return "???"; + } +} + void SDLTest_PrintEvent(const SDL_Event *event) { switch (event->type) { @@ -1878,6 +1895,16 @@ void SDLTest_PrintEvent(const SDL_Event *event) event->gbutton.which, event->gbutton.button, GamepadButtonName((SDL_GamepadButton)event->gbutton.button)); break; + case SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH: + SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 "capsense %u ('%s') touch", + event->gcapsense.which, event->gcapsense.capsense, + CapSenseName((SDL_GamepadCapSenseType)event->gcapsense.capsense)); + break; + case SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE: + SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " capsense %u ('%s') release", + event->gcapsense.which, event->gcapsense.capsense, + CapSenseName((SDL_GamepadCapSenseType)event->gcapsense.capsense)); + break; case SDL_EVENT_CLIPBOARD_UPDATE: SDL_Log("SDL EVENT: Clipboard updated"); break; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5166688ae9..42f1d58aa3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -102,7 +102,7 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.20) endif() if(DOS) - set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_dual_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") + set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_dual_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;gamepad_grip_sense.png;sdl-test_round.png") set(DOS83_SHORT "UNIFONT.HEX;UNIFONTL.TXT;PHYSADEV.PNG;LOGADEV.PNG;AUDIOFIL.PNG;SNDBRD.PNG;SNDLVL.PNG;TRASHCAN.PNG;MSDFFONT.PNG;MSDFFONT.CSV;GP_FRONT.PNG;GP_BACK.PNG;GP_FABXY.PNG;GP_FAXBY.PNG;GP_FBAYX.PNG;GP_FSONY.PNG;GP_BATT.PNG;GP_BATTX.PNG;GP_BATTW.PNG;GP_TOUCH.PNG;GP_BTN.PNG;GP_BTNSM.PNG;GP_BTNBG.PNG;GP_AXIS.PNG;GP_AXARW.PNG;GP_WIRED.PNG;GP_WLESS.PNG;SDLROUND.PNG") endif() @@ -315,6 +315,7 @@ files2headers(gamepad_image_headers gamepad_face_bayx.png gamepad_face_sony.png gamepad_front.png + gamepad_grip_sense.png gamepad_touchpad.png gamepad_wired.png gamepad_wireless.png diff --git a/test/gamepad_grip_sense.h b/test/gamepad_grip_sense.h new file mode 100644 index 0000000000..225e797896 --- /dev/null +++ b/test/gamepad_grip_sense.h @@ -0,0 +1,73 @@ +unsigned char gamepad_grip_sense_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3c, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x66, 0x76, 0x9a, 0x56, 0x00, 0x00, 0x00, + 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, + 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, + 0x02, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x94, 0x58, 0xcb, 0xb1, + 0xea, 0x30, 0x0c, 0x75, 0x8c, 0x0b, 0xa0, 0x24, 0x06, 0x8a, 0xa0, 0x04, + 0xd6, 0x54, 0xc2, 0x16, 0xe8, 0x20, 0x1b, 0x86, 0x02, 0x20, 0x30, 0x43, + 0x41, 0xc0, 0x9a, 0x4f, 0x2e, 0xf2, 0x7b, 0xca, 0x55, 0x94, 0x23, 0xe1, + 0xeb, 0x19, 0x26, 0x21, 0xb1, 0x64, 0x49, 0xe7, 0x48, 0x72, 0x5c, 0xd5, + 0x75, 0x1d, 0xe4, 0xd8, 0x6e, 0xb7, 0xed, 0xf1, 0x78, 0x0c, 0x25, 0x63, + 0x36, 0x9b, 0x85, 0xc3, 0xe1, 0x50, 0xc9, 0x67, 0x89, 0x6f, 0xd6, 0xeb, + 0x75, 0x7b, 0x3a, 0x9d, 0xf2, 0xfd, 0x6a, 0xb5, 0x0a, 0xa3, 0xd1, 0x28, + 0xc4, 0x18, 0x4d, 0x65, 0x8f, 0xc7, 0x23, 0x2c, 0x97, 0xcb, 0x50, 0x55, + 0x55, 0x3b, 0x9d, 0x4e, 0xc3, 0xc7, 0x88, 0xac, 0xb8, 0x22, 0x0b, 0x37, + 0x9b, 0x4d, 0xdb, 0x34, 0x4d, 0x56, 0x94, 0x52, 0xa2, 0x49, 0x9d, 0x60, + 0xdb, 0xb6, 0xf9, 0xa7, 0x9f, 0xd1, 0x62, 0x74, 0x7d, 0x3e, 0x9f, 0x59, + 0x31, 0x5b, 0x9b, 0x4d, 0x60, 0x65, 0x64, 0x95, 0x54, 0xc2, 0xf7, 0x52, + 0x59, 0xb6, 0xe2, 0xf3, 0x9f, 0x9f, 0x93, 0x0c, 0xc9, 0x72, 0x98, 0xaa, + 0x8f, 0xb9, 0xed, 0x78, 0x3c, 0x0e, 0x93, 0xc9, 0xa4, 0x13, 0x64, 0x01, + 0xad, 0x40, 0x2a, 0xa7, 0xeb, 0xfb, 0xfd, 0xee, 0xae, 0xe7, 0xf3, 0x39, + 0xdc, 0xef, 0xf7, 0x40, 0x6f, 0x5b, 0x69, 0x1d, 0xb9, 0x42, 0x13, 0xf8, + 0xca, 0x83, 0x5d, 0xb4, 0xac, 0x66, 0xd7, 0x93, 0xb4, 0x42, 0xba, 0x82, + 0xe2, 0x86, 0xe6, 0xea, 0xd1, 0x83, 0x51, 0x4f, 0xd0, 0x21, 0x90, 0xb1, + 0x45, 0xf3, 0x07, 0x0a, 0xb5, 0x22, 0x1d, 0x4f, 0x72, 0x9b, 0xdf, 0x31, + 0xd2, 0x7a, 0x7e, 0x44, 0xab, 0x49, 0xb7, 0xf9, 0xb9, 0x0e, 0x87, 0x66, + 0xc3, 0x40, 0x21, 0xc7, 0x45, 0x2f, 0x80, 0xe2, 0x29, 0x95, 0x6a, 0x70, + 0xa2, 0x14, 0x46, 0x28, 0x4a, 0x12, 0xcb, 0x77, 0xda, 0x83, 0x5e, 0xea, + 0x79, 0xe8, 0x5a, 0x68, 0x5a, 0x0c, 0x88, 0xa5, 0x80, 0x94, 0x8e, 0x58, + 0xa2, 0x48, 0xff, 0xf7, 0x16, 0x89, 0x88, 0xac, 0x5a, 0x40, 0x52, 0xc4, + 0x22, 0xfa, 0x00, 0x14, 0x99, 0xab, 0x9a, 0x1a, 0x12, 0x20, 0xc4, 0x00, + 0xa9, 0x3c, 0x21, 0xe8, 0x39, 0xe9, 0x35, 0xef, 0x64, 0xe6, 0x58, 0x39, + 0x0d, 0x63, 0x58, 0x12, 0x3b, 0x97, 0x87, 0x9e, 0xa2, 0x5e, 0x7c, 0x44, + 0x1c, 0x91, 0x01, 0x03, 0x85, 0x56, 0xac, 0x3c, 0x20, 0xb4, 0xdb, 0x83, + 0x5c, 0x46, 0x88, 0xa2, 0x85, 0xac, 0x45, 0x93, 0xb6, 0x80, 0x2b, 0xb0, + 0x17, 0x0a, 0x04, 0x0e, 0x54, 0x88, 0x5c, 0x40, 0x55, 0xc8, 0x23, 0x37, + 0x4c, 0x3d, 0x9d, 0x35, 0x50, 0xf0, 0x7f, 0x58, 0x60, 0xf9, 0xd2, 0x24, + 0x46, 0xad, 0xd3, 0x8a, 0x27, 0xa4, 0x4d, 0x09, 0x07, 0x65, 0x03, 0x2b, + 0x72, 0x19, 0x35, 0x1e, 0xbd, 0x10, 0x02, 0xc4, 0xb4, 0x50, 0xe6, 0xf1, + 0xb7, 0xe1, 0x55, 0x9e, 0x64, 0xf5, 0x86, 0x12, 0x62, 0xa3, 0x38, 0x26, + 0x24, 0x60, 0x21, 0x68, 0xd1, 0x89, 0xe2, 0xda, 0xc9, 0x6a, 0xaa, 0x68, + 0x94, 0x4b, 0x38, 0x29, 0xe7, 0x45, 0x44, 0x01, 0xa4, 0x04, 0x29, 0xe0, + 0x32, 0x07, 0x73, 0x59, 0xc6, 0x84, 0x27, 0x7a, 0x80, 0x58, 0x00, 0x26, + 0xe4, 0x82, 0x6c, 0x9b, 0x88, 0x36, 0x1e, 0xca, 0x70, 0x6f, 0x83, 0xc0, + 0xb0, 0x2c, 0xd6, 0xcf, 0x93, 0x95, 0xf8, 0xf2, 0xde, 0x4a, 0x33, 0x94, + 0x04, 0xd1, 0x2a, 0x98, 0x12, 0x65, 0xf9, 0xeb, 0x35, 0x75, 0x51, 0x37, + 0x7b, 0xb4, 0x29, 0x71, 0x0d, 0x29, 0x41, 0x79, 0x9d, 0x4a, 0x33, 0xc3, + 0xab, 0x30, 0x66, 0xa6, 0x78, 0xd5, 0x59, 0x7f, 0x15, 0x68, 0xaf, 0x78, + 0x5e, 0xf2, 0xaa, 0x09, 0x2a, 0x61, 0x52, 0x18, 0xed, 0x23, 0xa3, 0x45, + 0x5c, 0xab, 0x60, 0xf0, 0x3b, 0xab, 0x2e, 0x42, 0x50, 0xac, 0x6d, 0x5d, + 0xf1, 0xee, 0xeb, 0xdb, 0xc7, 0x0d, 0xb4, 0xc4, 0xf8, 0x6c, 0x8b, 0x96, + 0x30, 0xda, 0x08, 0xe9, 0x4d, 0x92, 0xd9, 0xe8, 0xf9, 0x81, 0xec, 0xc7, + 0xb2, 0x40, 0x58, 0x19, 0x82, 0x72, 0xbb, 0xe7, 0xb2, 0x55, 0x58, 0x75, + 0xe3, 0x2f, 0xda, 0x39, 0xa0, 0xf2, 0x6e, 0x71, 0x11, 0xed, 0x78, 0xe1, + 0xde, 0xc6, 0x2b, 0x61, 0xba, 0xaa, 0x5b, 0x19, 0x65, 0xb6, 0x51, 0xcf, + 0x6d, 0xaf, 0x4b, 0xc6, 0x6f, 0x3c, 0x43, 0x9f, 0x65, 0x72, 0x87, 0x6b, + 0x12, 0xdb, 0xfa, 0x16, 0xf1, 0xea, 0x22, 0xf2, 0x28, 0x95, 0xb0, 0x5f, + 0xb7, 0x57, 0xaf, 0x72, 0x47, 0x44, 0x07, 0x64, 0x15, 0x83, 0x84, 0x8e, + 0x0f, 0x7a, 0x88, 0xf3, 0x11, 0x01, 0x9d, 0x6c, 0xc8, 0xb6, 0xc8, 0x20, + 0x7c, 0xa3, 0x0c, 0x2f, 0x40, 0x27, 0x2a, 0xb7, 0xdb, 0x2d, 0xc4, 0xc5, + 0x62, 0x51, 0x5d, 0xaf, 0xd7, 0x7c, 0x6c, 0xe2, 0x7d, 0x65, 0xea, 0x2a, + 0x24, 0xbd, 0x79, 0xbd, 0x5e, 0xf9, 0xbc, 0xa1, 0x69, 0x9a, 0x7f, 0xa7, + 0x22, 0xa4, 0xfd, 0x72, 0xb9, 0xf4, 0xb6, 0xc4, 0x3a, 0x73, 0xac, 0xbe, + 0x42, 0x73, 0x49, 0x96, 0x4e, 0x56, 0xba, 0x18, 0xd6, 0x75, 0x5d, 0xed, + 0x76, 0xbb, 0xb0, 0xdf, 0xef, 0xf3, 0x61, 0x84, 0x26, 0xb5, 0x4e, 0x49, + 0x56, 0x4c, 0x73, 0x49, 0x86, 0x64, 0x3f, 0xef, 0x7e, 0x0f, 0x82, 0xe4, + 0x98, 0xcf, 0xe7, 0x7f, 0xfa, 0xfc, 0x64, 0x45, 0x3c, 0x7e, 0x04, 0x18, + 0x00, 0x80, 0xe2, 0x32, 0x3a, 0xb2, 0xea, 0x1b, 0xdf, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +unsigned int gamepad_grip_sense_png_len = 837; diff --git a/test/gamepad_grip_sense.png b/test/gamepad_grip_sense.png new file mode 100644 index 0000000000000000000000000000000000000000..1703d507e5881c63e1d788cc45e549bd2b3e1fc6 GIT binary patch literal 837 zcmV-L1G@Z)P)ew^@b8+qc|ocU?FJHiQ?MHYN}|IOE@X#MMMFl z1S#M$2Xk4*geQ7{SO6yEf^3_JHXh1wZ-cu)@~R0cVNw|FBcnxJt6=aut1d!NtZiNK?(5sf z4Yb7gY>SpK+6d`QlG*6_f$Yb!Kv)@qa=YiURakZ7FWNbv@@{bv?Reqd#w%gEs#_Ul zwo%V*uS>>nJVT#la))aY+xiyq>LT(em9Ss8SFdtMLF&*y*o{A5Kuegqf*fZ{Sbvg#Y( P00000NkvXXu0mjfWu$`S literal 0 HcmV?d00001 diff --git a/test/gamepadutils.c b/test/gamepadutils.c index 6fff0b419b..d7fa1c5a45 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -30,6 +30,7 @@ #include "gamepad_button_background.h" #include "gamepad_wired.h" #include "gamepad_wireless.h" +#include "gamepad_grip_sense.h" #include @@ -305,6 +306,17 @@ static const struct { 355, 200 }, /* SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 */ }; +static const struct +{ + int x; + int y; +} capsense_positions[] = { + { 97, 194 }, /* SDL_GAMEPAD_CAPSENSE_LEFT_STICK */ + { 330, 270 }, /* SDL_GAMEPAD_CAPSENSE_RIGHT_STICK */ + { 50, 260 }, /* SDL_GAMEPAD_CAPSENSE_LEFT_GRIP */ + { 462, 260 }, /* SDL_GAMEPAD_CAPSENSE_RIGHT_GRIP */ +}; + /* This is indexed by gamepad element */ static const struct { @@ -366,6 +378,7 @@ struct GamepadImage SDL_Texture *dual_touchpad_texture; SDL_Texture *button_texture; SDL_Texture *axis_texture; + SDL_Texture *grip_sense_texture; float gamepad_width; float gamepad_height; float face_width; @@ -382,6 +395,8 @@ struct GamepadImage float button_height; float axis_width; float axis_height; + float grip_sense_width; + float grip_sense_height; float x; float y; @@ -392,6 +407,7 @@ struct GamepadImage ControllerDisplayMode display_mode; bool elements[SDL_GAMEPAD_ELEMENT_MAX]; + bool capsense_elements[SDL_GAMEPAD_CAPSENSE_ELEMENT_MAX]; SDL_JoystickConnectionState connection_state; SDL_PowerState battery_state; @@ -453,6 +469,10 @@ GamepadImage *CreateGamepadImage(SDL_Renderer *renderer) SDL_GetTextureSize(ctx->axis_texture, &ctx->axis_width, &ctx->axis_height); SDL_SetTextureColorMod(ctx->axis_texture, 10, 255, 21); + ctx->grip_sense_texture = CreateTexture(renderer, gamepad_grip_sense_png, gamepad_grip_sense_png_len); + SDL_GetTextureSize(ctx->grip_sense_texture, &ctx->grip_sense_width, &ctx->grip_sense_height); + SDL_SetTextureColorMod(ctx->grip_sense_texture, 10, 255, 21); + ctx->showing_front = true; } return ctx; @@ -680,6 +700,7 @@ void ClearGamepadImage(GamepadImage *ctx) } SDL_zeroa(ctx->elements); + SDL_zeroa(ctx->capsense_elements); } void SetGamepadImageElement(GamepadImage *ctx, int element, bool active) @@ -691,6 +712,15 @@ void SetGamepadImageElement(GamepadImage *ctx, int element, bool active) ctx->elements[element] = active; } +static void SetGamepadCapSenseImageElement(GamepadImage *ctx, int capsense_element, bool active) +{ + if (!ctx) { + return; + } + + ctx->capsense_elements[capsense_element] = active; +} + static void FreeTouchpads(GamepadImage *ctx) { if (ctx->touchpads) { @@ -729,6 +759,11 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) SetGamepadImageElement(ctx, button, SDL_GetGamepadButton(gamepad, button)); } + for (i = 0; i < SDL_GAMEPAD_CAPSENSE_COUNT; ++i) { + const SDL_GamepadCapSenseType capsense = (SDL_GamepadCapSenseType)i; + SetGamepadCapSenseImageElement(ctx, capsense, SDL_GetGamepadCapSense(gamepad, capsense)); + } + for (i = 0; i < SDL_GAMEPAD_AXIS_COUNT; ++i) { const SDL_GamepadAxis axis = (SDL_GamepadAxis)i; const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */ @@ -968,6 +1003,31 @@ void RenderGamepadImage(GamepadImage *ctx) } } } + + if (ctx->display_mode == CONTROLLER_MODE_TESTING && ctx->showing_front) { + SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE / 2); + for (i = 0; i < 2; ++i) { + if (ctx->capsense_elements[i]) { + dst.w = ctx->button_width / 2; + dst.h = ctx->button_height / 2; + dst.x = ctx->x + capsense_positions[i].x - dst.w / 2; + dst.y = ctx->y + capsense_positions[i].y - dst.h / 2; + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + } + } + SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE); + SDL_SetTextureAlphaMod(ctx->grip_sense_texture, SDL_ALPHA_OPAQUE / 2); + for (i = 2; i < SDL_arraysize(capsense_positions); ++i) { + if (ctx->capsense_elements[i]) { + dst.w = ctx->grip_sense_width; + dst.h = ctx->grip_sense_height; + dst.x = ctx->x + capsense_positions[i].x - dst.w / 2; + dst.y = ctx->y + capsense_positions[i].y - dst.h / 2; + SDL_RenderTexture(ctx->renderer, ctx->grip_sense_texture, NULL, &dst); + } + } + SDL_SetTextureAlphaMod(ctx->grip_sense_texture, SDL_ALPHA_OPAQUE); + } } void DestroyGamepadImage(GamepadImage *ctx) @@ -1033,6 +1093,14 @@ static const char *gamepad_axis_names[] = { }; SDL_COMPILE_TIME_ASSERT(gamepad_axis_names, SDL_arraysize(gamepad_axis_names) == SDL_GAMEPAD_AXIS_COUNT); +static const char *capsense_names[] = { + "L.Stick Touch", + "R.Stick Touch", + "L.Grip Sense", + "R.Grip Sense", +}; +SDL_COMPILE_TIME_ASSERT(capsense_names, SDL_arraysize(capsense_names) == SDL_GAMEPAD_CAPSENSE_COUNT); + struct GamepadDisplay { SDL_Renderer *renderer; @@ -1714,6 +1782,28 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad) } } + for (i = 0; i < SDL_GAMEPAD_CAPSENSE_COUNT; i++) { + const SDL_GamepadCapSenseType capsense = (SDL_GamepadCapSenseType)i; + if (SDL_GamepadHasCapSense(gamepad, capsense)) { + SDL_snprintf(text, sizeof(text), "%s:", capsense_names[i]); + SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text); + + if (SDL_GetGamepadCapSense(gamepad, capsense)) { + SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); + } else { + SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255); + } + + dst.x = x + center + 2.0f; + dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2; + dst.w = ctx->button_width; + dst.h = ctx->button_height; + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + + y += ctx->button_height + 2.0f; + }; + } + has_accel = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_ACCEL); has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO); diff --git a/test/gamepadutils.h b/test/gamepadutils.h index 503238afe1..77b6026957 100644 --- a/test/gamepadutils.h +++ b/test/gamepadutils.h @@ -46,6 +46,15 @@ enum SDL_GAMEPAD_ELEMENT_MAX, }; +enum +{ + SDL_GAMEPAD_CAPSENSE_ELEMENT_LEFT_STICK, + SDL_GAMEPAD_CAPSENSE_ELEMENT_RIGHT_STICK, + SDL_GAMEPAD_CAPSENSE_ELEMENT_LEFT_GRIP, + SDL_GAMEPAD_CAPSENSE_ELEMENT_RIGHT_GRIP, + SDL_GAMEPAD_CAPSENSE_ELEMENT_MAX +}; + #define HIGHLIGHT_COLOR 224, 255, 255, SDL_ALPHA_OPAQUE #define HIGHLIGHT_TEXTURE_MOD 224, 255, 255 #define PRESSED_COLOR 175, 238, 238, SDL_ALPHA_OPAQUE diff --git a/test/testcontroller.c b/test/testcontroller.c index d6276d97e7..f0d3dd4867 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -2213,6 +2213,16 @@ SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, SDL_Event *event) } break; + case SDL_EVENT_GAMEPAD_CAPSENSE_TOUCH: + case SDL_EVENT_GAMEPAD_CAPSENSE_RELEASE: +#ifdef VERBOSE_CAPSENSE + SDL_Log("Gamepad %" SDL_PRIu32 " capsense %u %s", + event->gcapsense.which, + event->gcapsense.capsense, + event->gcapsense.down ? "touch" : "release"); +#endif /* VERBOSE_CAPSENSE */ + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: if (virtual_joystick && controller && controller->joystick == virtual_joystick) { VirtualGamepadMouseDown(event->button.x, event->button.y); diff --git a/test/testutils.c b/test/testutils.c index 99f18831e9..79d5abfeca 100644 --- a/test/testutils.c +++ b/test/testutils.c @@ -47,6 +47,7 @@ static const struct { "gamepad_axis_arrow.png", "GP_AXARW.PNG" }, { "gamepad_wired.png", "GP_WIRED.PNG" }, { "gamepad_wireless.png", "GP_WLESS.PNG" }, + { "gamepad_grip_sense.png", "GP_GRIPS.PNG" }, { "sdl-test_round.png", "SDLROUND.PNG" }, { NULL, NULL } }; From 63d2635719d0431802e2e1c933c23c3c1c2a2d5e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 08:47:36 -0700 Subject: [PATCH 341/407] Added SDL_HINT_AUDIO_DUCK_OTHERS Previously default audio on Apple platforms would duck other audio streams. This is unexpected, so by default we won't do that and you can use the hint SDL_HINT_AUDIO_DUCK_OTHERS to re-enable that behavior. --- include/SDL3/SDL_hints.h | 20 ++++++++++++++++++-- src/audio/coreaudio/SDL_coreaudio.m | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 82f04e6d85..160b89f89c 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -294,9 +294,9 @@ extern "C" { * * The variable can be set to the following values: * + * - "playback": Use the AVAudioSessionCategoryPlayback category. (default) * - "ambient": Use the AVAudioSessionCategoryAmbient audio category, will be - * muted by the phone mute switch (default) - * - "playback": Use the AVAudioSessionCategoryPlayback category. + * muted by the phone mute switch. * * For more information, see Apple's documentation: * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html @@ -506,6 +506,22 @@ extern "C" { */ #define SDL_HINT_AUDIO_DRIVER "SDL_AUDIO_DRIVER" +/** + * Specify whether this audio stream should duck other audio. + * + * On Apple platforms, this hint controls whether other audio streams are ducked (reduced in volume) while your application is in the foreground. + * + * The variable can be set to the following values: + * + * - "0": Other audio will not be ducked. (default) + * - "1": Other audio will be ducked. + * + * This hint should be set before an audio device is opened. + * + * \since This hint is available since SDL 3.6.0. + */ +#define SDL_HINT_AUDIO_DUCK_OTHERS "SDL_AUDIO_DUCK_OTHERS" + /** * A variable controlling the audio rate when using the dummy audio driver. * diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 5342d3d28d..5fb3cb74cb 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -464,7 +464,9 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl } if (category == AVAudioSessionCategoryPlayback || category == AVAudioSessionCategoryPlayAndRecord) { - options |= AVAudioSessionCategoryOptionDuckOthers; + if (SDL_GetHintBoolean(SDL_HINT_AUDIO_DUCK_OTHERS, false)) { + options |= AVAudioSessionCategoryOptionDuckOthers; + } } if (![session.category isEqualToString:category] || session.categoryOptions != options) { From 31d6acef64e32f154eba639bbb466cbbe8bf45eb Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Sun, 17 May 2026 15:51:20 +0000 Subject: [PATCH 342/407] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_hints.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 160b89f89c..d23577fa8c 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -509,7 +509,8 @@ extern "C" { /** * Specify whether this audio stream should duck other audio. * - * On Apple platforms, this hint controls whether other audio streams are ducked (reduced in volume) while your application is in the foreground. + * On Apple platforms, this hint controls whether other audio streams are + * ducked (reduced in volume) while your application is in the foreground. * * The variable can be set to the following values: * From 336d07c2b78c1f08ff0505ce8184dfeb47ce9d62 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 15 May 2026 13:51:14 -0400 Subject: [PATCH 343/407] wayland: Implement Wayland_AcceptDragAndDrop() This simply toggles a flag that rejects DnD offers if false. Events were previously dropped silently, but rejecting the offer makes some desktops display a proper icon when the drop will not work. --- src/video/wayland/SDL_waylandevents.c | 73 ++++++++++++++------------- src/video/wayland/SDL_waylandvideo.c | 1 + src/video/wayland/SDL_waylandwindow.c | 5 ++ src/video/wayland/SDL_waylandwindow.h | 2 + 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index d2d492afbc..7d0fef62dc 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -2798,15 +2798,18 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_ wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id) { SDL_WaylandDataDevice *data_device = data; + SDL_WindowData *window = surface ? Wayland_GetWindowDataForOwnedSurface(surface) : NULL; data_device->has_mime_file = false; data_device->has_mime_text = false; - uint32_t dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; data_device->drag_serial = serial; + // Save the drag offer so it can be freed later. if (id) { data_device->drag_offer = wl_data_offer_get_user_data(id); + } + if (data_device->drag_offer && window && window->accepts_drag_and_drop) { // TODO: SDL Support more mime types #ifdef SDL_USE_LIBDBUS if (Wayland_data_offer_has_mime(data_device->drag_offer, FILE_PORTAL_MIME)) { @@ -2832,48 +2835,46 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_ } } - // SDL only supports "copy" style drag and drop if (data_device->has_mime_file || data_device->has_mime_text) { - dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; - } else { - // drag_mime is NULL this will decline the offer - wl_data_offer_accept(id, serial, NULL); - } - if (wl_data_offer_get_version(data_device->drag_offer->offer) >= - WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { - wl_data_offer_set_actions(data_device->drag_offer->offer, - dnd_action, dnd_action); - } - - // find the current window - if (surface) { - SDL_WindowData *window = Wayland_GetWindowDataForOwnedSurface(surface); - if (window) { - data_device->dnd_window = window->sdlwindow; - const float dx = (float)wl_fixed_to_double(x); - const float dy = (float)wl_fixed_to_double(y); - SDL_SendDropPosition(data_device->dnd_window, dx, dy); - SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d into window %d for serial %d", - WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), - wl_fixed_to_int(x), wl_fixed_to_int(y), SDL_GetWindowID(data_device->dnd_window), serial); - } else { - data_device->dnd_window = NULL; - SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, - ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d for serial %d", - WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), - wl_fixed_to_int(x), wl_fixed_to_int(y), serial); + // SDL only supports "copy" style drag and drop + if (wl_data_offer_get_version(data_device->drag_offer->offer) >= WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { + wl_data_offer_set_actions(data_device->drag_offer->offer, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); } + + // Set the destination window and send the initial position. + data_device->dnd_window = window->sdlwindow; + const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x); + const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y); + SDL_SendDropPosition(data_device->dnd_window, dx, dy); + SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, + ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d into window %d for serial %d", + WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), + wl_fixed_to_int(x), wl_fixed_to_int(y), SDL_GetWindowID(data_device->dnd_window), serial); } else { + // Decline the offer. + wl_data_offer_accept(id, serial, NULL); + if (wl_data_offer_get_version(data_device->drag_offer->offer) >= WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { + wl_data_offer_set_actions(data_device->drag_offer->offer, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE); + } + SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d for serial %d", - WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), - wl_fixed_to_int(x), wl_fixed_to_int(y), serial); + WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), wl_fixed_to_int(x), wl_fixed_to_int(y), serial); } } else { + data_device->dnd_window = NULL; + + // Decline the offer. + if (id) { + wl_data_offer_accept(id, serial, NULL); + if (wl_data_offer_get_version(data_device->drag_offer->offer) >= WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { + wl_data_offer_set_actions(data_device->drag_offer->offer, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE); + } + } SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d for serial %d", - -1, wl_fixed_to_int(x), wl_fixed_to_int(y), serial); + id ? WAYLAND_wl_proxy_get_id((struct wl_proxy *)id) : -1, + wl_fixed_to_int(x), wl_fixed_to_int(y), serial); } } @@ -2911,8 +2912,8 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_data SDL_WaylandDataDevice *data_device = data; if (data_device->drag_offer && data_device->dnd_window && (data_device->has_mime_file || data_device->has_mime_text)) { - const float dx = (float)wl_fixed_to_double(x); - const float dy = (float)wl_fixed_to_double(y); + const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x); + const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y); /* XXX: Send the filename here if the event system ever starts passing it though. * Any future implementation should cache the filenames, as otherwise this could diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 2a29d632c9..f3facbd7f0 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -732,6 +732,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) device->SyncWindow = Wayland_SyncWindow; device->SetWindowFocusable = Wayland_SetWindowFocusable; device->ReconfigureWindow = Wayland_ReconfigureWindow; + device->AcceptDragAndDrop = Wayland_AcceptDragAndDrop; #ifdef SDL_USE_LIBDBUS if (SDL_SystemTheme_Init()) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 10d4524fa2..d7e70c63c4 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -3426,6 +3426,11 @@ bool Wayland_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window) return true; } +void Wayland_AcceptDragAndDrop(SDL_Window *window, bool accept) +{ + window->internal->accepts_drag_and_drop = accept; +} + bool Wayland_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable) { if (window->flags & SDL_WINDOW_POPUP_MENU) { diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index e061855352..b9d0a257e2 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -234,6 +234,7 @@ struct SDL_WindowData bool scale_to_display; bool reparenting_required; bool double_buffer; + bool accepts_drag_and_drop; SDL_HitTestResult hit_test_result; @@ -271,6 +272,7 @@ extern bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SD extern bool Wayland_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable); extern float Wayland_GetWindowContentScale(SDL_VideoDevice *_this, SDL_Window *window); extern void *Wayland_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size); +extern void Wayland_AcceptDragAndDrop(SDL_Window *window, bool accept); extern bool Wayland_SetWindowHitTest(SDL_Window *window, bool enabled); extern bool Wayland_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation); From 9aae258aeb3271fbd1e571fc0da799473f90ff57 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 15 May 2026 14:02:18 -0400 Subject: [PATCH 344/407] wayland: Adjust DnD coordinates when dragging over a mask subsurface --- src/video/wayland/SDL_waylanddatamanager.h | 1 + src/video/wayland/SDL_waylandevents.c | 34 ++++++++++++++++++---- src/video/wayland/SDL_waylandwindow.c | 10 ++++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/video/wayland/SDL_waylanddatamanager.h b/src/video/wayland/SDL_waylanddatamanager.h index 1ac0dbfc2f..c9bc93d1f9 100644 --- a/src/video/wayland/SDL_waylanddatamanager.h +++ b/src/video/wayland/SDL_waylanddatamanager.h @@ -98,6 +98,7 @@ struct SDL_WaylandDataDevice const char *mime_type; bool has_mime_file, has_mime_text; SDL_Window *dnd_window; + struct wl_surface *dnd_surface; // Clipboard and Primary Selection uint32_t selection_serial; diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 7d0fef62dc..b38ef441db 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -2843,9 +2843,20 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_ // Set the destination window and send the initial position. data_device->dnd_window = window->sdlwindow; - const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x); - const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y); - SDL_SendDropPosition(data_device->dnd_window, dx, dy); + data_device->dnd_surface = surface; + double dx = wl_fixed_to_double(x); + double dy = wl_fixed_to_double(y); + + // If over the mask, adjust the offset. + if (surface == window->mask.surface) { + dx += (double)window->mask.offset_x; + dy += (double)window->mask.offset_y; + } + + dx *= window->pointer_scale.x; + dy *= window->pointer_scale.y; + + SDL_SendDropPosition(data_device->dnd_window, (float)dx, (float)dy); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, ". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d into window %d for serial %d", WAYLAND_wl_proxy_get_id((struct wl_proxy *)id), @@ -2863,6 +2874,7 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_ } } else { data_device->dnd_window = NULL; + data_device->dnd_surface = NULL; // Decline the offer. if (id) { @@ -2912,14 +2924,24 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_data SDL_WaylandDataDevice *data_device = data; if (data_device->drag_offer && data_device->dnd_window && (data_device->has_mime_file || data_device->has_mime_text)) { - const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x); - const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y); + SDL_WindowData *window_data = data_device->dnd_window->internal; + double dx = wl_fixed_to_double(x); + double dy = wl_fixed_to_double(y); + + // If over the mask, adjust the offset. + if (data_device->dnd_surface == window_data->mask.surface) { + dx += (double)window_data->mask.offset_x; + dy += (double)window_data->mask.offset_y; + } + + dx *= window_data->pointer_scale.x; + dy *= window_data->pointer_scale.y; /* XXX: Send the filename here if the event system ever starts passing it though. * Any future implementation should cache the filenames, as otherwise this could * hammer the DBus interface hundreds or even thousands of times per second. */ - SDL_SendDropPosition(data_device->dnd_window, dx, dy); + SDL_SendDropPosition(data_device->dnd_window, (float)dx, (float)dy); SDL_LogTrace(SDL_LOG_CATEGORY_INPUT, ". In wl_data_device_listener . data_device_handle_motion on data_offer 0x%08x at %d x %d in window %d serial %d", WAYLAND_wl_proxy_get_id((struct wl_proxy *)data_device->drag_offer->offer), diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index d7e70c63c4..dda72ce311 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -543,14 +543,16 @@ static void ConfigureWindowGeometry(SDL_Window *window) SetSurfaceOpaqueRegion(data->mask.surface, 0, 0); } - data->mask.offset_x = -(data->current.logical_width - viewport_width) / 2; - data->mask.offset_y = -(data->current.logical_height - viewport_height) / 2; - // Can't use an offset subsurface with libdecor (yet), or the decorations won't line up properly. if (data->shell_surface_type != WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) { - wl_subsurface_set_position(data->mask.subsurface, data->mask.offset_x, data->mask.offset_y); + data->mask.offset_x = -(data->current.logical_width - viewport_width) / 2; + data->mask.offset_y = -(data->current.logical_height - viewport_height) / 2; + } else { + data->mask.offset_x = 0; + data->mask.offset_y = 0; } + wl_subsurface_set_position(data->mask.subsurface, data->mask.offset_x, data->mask.offset_y); wl_surface_commit(data->mask.surface); if (old_buffer) { From ae25abeb0daab3b33c94227e339e622bfa72769c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 07:28:36 -0700 Subject: [PATCH 345/407] Don't log game controller buttons in the keyboard handler on Android --- src/video/android/SDL_androidkeyboard.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video/android/SDL_androidkeyboard.c b/src/video/android/SDL_androidkeyboard.c index 82c87a7305..d7ead29c8a 100644 --- a/src/video/android/SDL_androidkeyboard.c +++ b/src/video/android/SDL_androidkeyboard.c @@ -361,7 +361,11 @@ static SDL_Scancode TranslateKeycode(int keycode) scancode = Android_Keycodes[keycode]; } if (scancode == SDL_SCANCODE_UNKNOWN) { - __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode); + if (keycode >= 96 /* AKEYCODE_BUTTON_A */ && keycode < 111 /* AKEYCODE_ESCAPE */) { + // Ignore game controller buttons + } else { + __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode); + } } return scancode; } From f76b736e287f5056ff0d586febe00ef1b7a8a37f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 20:28:56 +0300 Subject: [PATCH 346/407] SDL_render_d3d12.c: revert an unintended change from commit d70578b9aac --- src/render/direct3d12/SDL_render_d3d12.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index 3330a558a2..d88903c6f6 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -905,7 +905,7 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer) D3D_GUID(SDL_IID_IDXGIAdapter4), (void **)&data->dxgiAdapter); if (FAILED(result)) { - WIN_SetErrorFromHRESULT("IDXGIFactory6::EnumAdapterByGPUPreference", result); + WIN_SetErrorFromHRESULT("IDXGIFactory6::EnumAdapterByGpuPreference", result); goto done; } From 6d3404e4bbdfa02da56bca4ed21f0426da764bfc Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 16 May 2026 16:29:07 -0500 Subject: [PATCH 347/407] gamepad: Add SDL_GAMEPAD_TYPE_STEAM for Steam Controllers --- include/SDL3/SDL_gamepad.h | 1 + src/SDL_utils.c | 3 +++ src/joystick/SDL_gamepad.c | 3 ++- src/joystick/SDL_joystick.c | 8 ++++++++ test/gamepadutils.c | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index 2d0e83440a..363ec7dbe6 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -122,6 +122,7 @@ typedef enum SDL_GamepadType SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT, SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR, SDL_GAMEPAD_TYPE_GAMECUBE, + SDL_GAMEPAD_TYPE_STEAM, SDL_GAMEPAD_TYPE_COUNT } SDL_GamepadType; diff --git a/src/SDL_utils.c b/src/SDL_utils.c index a4a0d77614..153803adc1 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -548,6 +548,9 @@ char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_nam case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO: name = SDL_strdup("Nintendo Switch Pro Controller"); break; + case SDL_GAMEPAD_TYPE_STEAM: + name = SDL_strdup("Steam Controller"); + break; default: len = (6 + 1 + 6 + 1); name = (char *)SDL_malloc(len); diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index b9c3ade4f0..6dab310b80 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1494,7 +1494,8 @@ static const char *map_StringForGamepadType[] = { "joyconleft", "joyconright", "joyconpair", - "gamecube" + "gamecube", + "steam" }; SDL_COMPILE_TIME_ASSERT(map_StringForGamepadType, SDL_arraysize(map_StringForGamepadType) == SDL_GAMEPAD_TYPE_COUNT); diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 746cb04690..3e3fb95d5b 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3173,6 +3173,14 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons type = SDL_GAMEPAD_TYPE_STANDARD; } break; + case k_eControllerType_SteamController: + case k_eControllerType_SteamControllerV2: + case k_eControllerType_SteamControllerNeptune: + case k_eControllerType_SteamControllerTriton: + case k_eControllerType_HoriSteamController: + case k_eControllerType_UnknownSteamController: + type = SDL_GAMEPAD_TYPE_STEAM; + break; default: break; } diff --git a/test/gamepadutils.c b/test/gamepadutils.c index d7fa1c5a45..0d61596b0e 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -3643,6 +3643,8 @@ const char *GetGamepadTypeString(SDL_GamepadType type) return "Joy-Con Pair"; case SDL_GAMEPAD_TYPE_GAMECUBE: return "GameCube"; + case SDL_GAMEPAD_TYPE_STEAM: + return "Steam"; default: return ""; } From 33e237eb6779ecfda70c781caa656827ee9d70f8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 11:05:43 -0700 Subject: [PATCH 348/407] visionos: persist all configurable window settings Save the gaze indicator and dimmed mode setting as well as curvature --- include/SDL3/SDL_events.h | 4 +- include/SDL3/SDL_video.h | 15 +--- src/events/SDL_events.c | 2 +- .../uikit/SDL_CurvedContentHosting.swift | 82 ++++++++++++++++--- src/video/uikit/SDL_UIKitBridge-swift.h | 8 +- src/video/uikit/SDL_UIKitBridge.m | 18 ++-- src/video/uikit/SDL_uikitviewcontroller.m | 2 +- src/video/uikit/SDL_uikitwindow.h | 2 +- src/video/uikit/SDL_uikitwindow.m | 13 +-- 9 files changed, 98 insertions(+), 48 deletions(-) diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index dd822ecc71..0a3827571f 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -163,9 +163,9 @@ typedef enum SDL_EventType associated with the window. Otherwise, the handle has already been destroyed and all resources associated with it are invalid */ SDL_EVENT_WINDOW_HDR_STATE_CHANGED, /**< Window HDR properties have changed */ - SDL_EVENT_WINDOW_CURVATURE_CHANGED, /**< Window curvature has changed to data1 (on visionOS) */ + SDL_EVENT_WINDOW_SETTINGS_CHANGED, /**< Window settings have changed (on visionOS) */ SDL_EVENT_WINDOW_FIRST = SDL_EVENT_WINDOW_SHOWN, - SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_CURVATURE_CHANGED, + SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_SETTINGS_CHANGED, /* Keyboard events */ SDL_EVENT_KEY_DOWN = 0x300, /**< Key pressed */ diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 821c176101..1eeb7db6cd 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -1386,11 +1386,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren * * These are additional supported properties with visionOS: * - * - `SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT`: the curvature of the window on - * visionOS. Curved windows have square corners and additional controls for - * more immersive gaming. This can be -1 (disabled), which is the default, 0 - * (no curve), or set to a specific curvature radius in millimeters. A - * common value for a gaming monitor is 1000. + * - `SDL_PROP_WINDOW_CREATE_VISIONOS_SETTINGS_STRING`: the settings of the window in JSON format. If this isn't set, the window will have standard UIKit behavior. If this is set to "" or a valid setting string then the window is created with enhanced features allowing curved display. The curvature in the settings is defined as a radius in millimeters. A common value for a gaming monitor is 1000 and a setting string for that would be "{\"curvatureRadius\":1000}". * * If this window is being created to be used with an SDL_Renderer, you should * not add a graphics API specific property @@ -1454,7 +1450,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop #define SDL_PROP_WINDOW_CREATE_X11_WINDOW_NUMBER "SDL.window.create.x11.window" #define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.create.emscripten.canvas_id" #define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.create.emscripten.keyboard_element" -#define SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT "SDL.window.create.curvature" +#define SDL_PROP_WINDOW_CREATE_VISIONOS_SETTINGS_STRING "SDL.window.create.visionos.settings" /** * Get the numeric ID of a window. @@ -1635,10 +1631,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window) * * On visionOS: * - * - `SDL_PROP_WINDOW_CURVATURE_FLOAT`: the curvature of the window in curved - * mode on visionOS. This value is updated dynamically when changed via the - * screen ornaments. This can be 0 (no curve), or a specific curvature - * radius in millimeters. A common value for a gaming monitor is 1000. + * - `SDL_PROP_WINDOW_VISIONOS_SETTINGS_STRING`: the current settings of the window in JSON format, or NULL if the window has standard UIKit behavior. SDL_EVENT_WINDOW_SETTINGS_CHANGED is sent when this value changes. * * \param window the window to query. * \returns a valid property ID on success or 0 on failure; call @@ -1689,7 +1682,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetWindowProperties(SDL_Window #define SDL_PROP_WINDOW_X11_WINDOW_NUMBER "SDL.window.x11.window" #define SDL_PROP_WINDOW_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.emscripten.canvas_id" #define SDL_PROP_WINDOW_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.emscripten.keyboard_element" -#define SDL_PROP_WINDOW_CURVATURE_FLOAT "SDL.window.curvature" +#define SDL_PROP_WINDOW_VISIONOS_SETTINGS_STRING "SDL.window.visionos.settings" /** * Get the window flags. diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 19f5a85adc..e2ef1a35f3 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -565,7 +565,7 @@ int SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen) SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN); SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED); SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_HDR_STATE_CHANGED); - SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_CURVATURE_CHANGED); + SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_SETTINGS_CHANGED); #undef SDL_WINDOWEVENT_CASE #define PRINT_KEYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " which=%u)", event->kdevice.timestamp, (uint)event->kdevice.which) diff --git a/src/video/uikit/SDL_CurvedContentHosting.swift b/src/video/uikit/SDL_CurvedContentHosting.swift index d88b43680e..d8dccaf3bd 100644 --- a/src/video/uikit/SDL_CurvedContentHosting.swift +++ b/src/video/uikit/SDL_CurvedContentHosting.swift @@ -93,7 +93,7 @@ internal class SDL_ClearHostingController: UIHostingController SDL_CurvedContentSettings { + let settings = SDL_CurvedContentSettings() + if let json = SDL_VisionOS_GetWindowSettings() { + if json != "", let data = json.data(using: .utf8) { + do { + let values = try JSONDecoder().decode(SDL_CurvedContentPersistentSettings.self, from:data) + if let inputType = values.inputType { + settings.inputType = inputType + } + if let showHover = values.showHover { + settings.showHover = showHover + } + if let isDimmed = values.isDimmed { + settings.isDimmed = isDimmed + } + if let curvatureRadius = values.curvatureRadius { + settings.curvatureRadius = curvatureRadius + } + } catch { + NSLog("Couldn't parse window settings: %@", error.localizedDescription) + } + } + } + return settings } - enum InputType { - case eyes - case pointer + func save() { + let values = SDL_CurvedContentPersistentSettings() + values.inputType = inputType + values.showHover = showHover + values.isDimmed = isDimmed + values.curvatureRadius = curvatureRadius + + do { + let data = try JSONEncoder().encode(values) + let json = String(data: data, encoding: String.Encoding.utf8) + SDL_VisionOS_SendWindowSettings(json) + } catch { + NSLog("Couldn't encode window settings: %@", error.localizedDescription) + } } var inputType: InputType = .eyes var showHover: Bool = true var isDimmed: Bool = false - var curvatureRadius: Float = SDL_VisionOS_GetCurvature() + var curvatureRadius: Float = 0.0 var sceneState: SceneState = .interactive var isSnapped: Bool = false var settingsExpanded: Bool = false @@ -330,6 +380,9 @@ struct SDL_SettingsPanelView: View { Toggle(isOn: $settings.showHover) { } + .onChange(of: settings.showHover) { + settings.save() + } .labelsHidden() .tint(.secondary) @@ -341,6 +394,9 @@ struct SDL_SettingsPanelView: View { Toggle(isOn: $settings.isDimmed) { } + .onChange(of: settings.isDimmed) { + settings.save() + } .labelsHidden() .tint(.secondary) @@ -383,7 +439,7 @@ struct SDL_SettingsPanelView: View { + (1.0 - curvatureSlider) * Self.maximumCurvatureRadius) settings.curvatureRadius = radius } - SDL_VisionOS_SendCurvatureChanged(settings.curvatureRadius) + settings.save() } CurviestButtonIcon() diff --git a/src/video/uikit/SDL_UIKitBridge-swift.h b/src/video/uikit/SDL_UIKitBridge-swift.h index e63dc6c42b..a59414b4d3 100644 --- a/src/video/uikit/SDL_UIKitBridge-swift.h +++ b/src/video/uikit/SDL_UIKitBridge-swift.h @@ -23,11 +23,11 @@ // Called from Swift scene delegates when window size changes void SDL_VisionOS_SendSizeChanged(long width, long height); -// Called from Swift scene delegates to get the initial curvature -float SDL_VisionOS_GetCurvature(); +// Called from Swift scene delegates to get the initial window settings +NSString *SDL_VisionOS_GetWindowSettings(); -// Called from Swift scene delegates when window curvature changes -void SDL_VisionOS_SendCurvatureChanged(float curvature); +// Called from Swift scene delegates when window settings change +void SDL_VisionOS_SendWindowSettings(NSString *settings); // Called from Swift scene delegates when pointer mode changes void SDL_VisionOS_SendPointerMode(bool enabled); diff --git a/src/video/uikit/SDL_UIKitBridge.m b/src/video/uikit/SDL_UIKitBridge.m index b5c552f51a..e869d4b22c 100644 --- a/src/video/uikit/SDL_UIKitBridge.m +++ b/src/video/uikit/SDL_UIKitBridge.m @@ -57,27 +57,27 @@ void SDL_VisionOS_SendSizeChanged(long width, long height) } } -// Called from Swift scene delegates to get the initial curvature -float SDL_VisionOS_GetCurvature() +// Called from Swift scene delegates to get the initial window settings +NSString *SDL_VisionOS_GetWindowSettings() { SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); if (window) { SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - return data.curvature; + return data.settings; } - return 0.0f; + return nil; } // Called from Swift scene delegates when window curvature changes -void SDL_VisionOS_SendCurvatureChanged(float curvature) +void SDL_VisionOS_SendWindowSettings(NSString *settings) { SDL_Window *window = SDL_GetToplevelForKeyboardFocus(); if (window) { SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - if (curvature != data.curvature) { - data.curvature = curvature; - SDL_SetFloatProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_CURVATURE_FLOAT, curvature); - SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_CURVATURE_CHANGED, (int)curvature, 0); + if (![settings isEqualToString:data.settings]) { + data.settings = settings; + SDL_SetStringProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_VISIONOS_SETTINGS_STRING, settings.UTF8String); + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SETTINGS_CHANGED, 0, 0); } } } diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index dc776741d9..7da8731699 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -127,7 +127,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #ifdef SDL_PLATFORM_VISIONOS if (@available(visionOS 26.0, *)) { SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)self.window->internal; - if (data.curvature >= 0.0f) { + if (data.settings != nil) { [self initializeVisionOSCurvedUI]; } } diff --git a/src/video/uikit/SDL_uikitwindow.h b/src/video/uikit/SDL_uikitwindow.h index b9077ad36d..42a531cd65 100644 --- a/src/video/uikit/SDL_uikitwindow.h +++ b/src/video/uikit/SDL_uikitwindow.h @@ -55,7 +55,7 @@ extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window *window); #ifdef SDL_PLATFORM_VISIONOS // Hosting controller for curved content mode (UIHostingController-based) @property(nonatomic, strong) id curvedContentHosting; -@property(nonatomic, assign) CGFloat curvature; +@property(nonatomic, strong) NSString *settings; #endif @end diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 3c3b4fd926..5523d6c55f 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -106,18 +106,19 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow #endif window->w = width; window->h = height; - + SDL_PropertiesID props = SDL_GetWindowProperties(window); SDL_SetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, (__bridge void *)data.uiwindow); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_METAL_VIEW_TAG_NUMBER, SDL_METALVIEW_TAG); #ifdef SDL_PLATFORM_VISIONOS - float curvature = SDL_GetFloatProperty(create_props, SDL_PROP_WINDOW_CREATE_CURVATURE_FLOAT, -1.0f); - if (curvature > 0.0f && curvature <= 1.0f) { - curvature = 0.0f; + const char *settings = SDL_GetStringProperty(create_props, SDL_PROP_WINDOW_CREATE_VISIONOS_SETTINGS_STRING, NULL); + if (settings) { + data.settings = [NSString stringWithUTF8String:settings]; + } else { + data.settings = nil; } - data.curvature = curvature; - SDL_SetFloatProperty(props, SDL_PROP_WINDOW_CURVATURE_FLOAT, curvature); + SDL_SetStringProperty(props, SDL_PROP_WINDOW_VISIONOS_SETTINGS_STRING, settings); #endif /* The View Controller will handle rotating the view when the device From cbd2917324ab24c18d5afeeb435f7cf23c883403 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 17 May 2026 21:36:20 +0300 Subject: [PATCH 349/407] SDL_render_d3d11.c: fix another bad use of SDL_FUNCTION --- src/render/direct3d11/SDL_render_d3d11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 131a770251..edb0be613a 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -898,7 +898,7 @@ static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h) IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, hwnd, DXGI_MWA_NO_WINDOW_CHANGES); #else - SDL_SetError(SDL_FUNCTION ", Unable to find something to attach a swap chain to"); + SDL_SetError("%s, Unable to find something to attach a swap chain to", SDL_FUNCTION); goto done; #endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) / else } From 02975994c12582aef918bccb3825592e7ea36d10 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 12:04:11 -0700 Subject: [PATCH 350/407] Revert "Change controller sensor state on the main UI thread on Android" This reverts commit c362f1341f2e2e6abf34ae05d6068ad89bebd00d. It turns out this change causes a deadlock: The main UI thread calls synchronized handleMotionEvent() which then calls SDL_LockJoysticks() The main app thread calls SDL_LockJoysticks() and then synchronized pollInputDevices() --- .../main/java/org/libsdl/app/SDLControllerManager.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 2a0296eb0c..31b07b0ac0 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -91,13 +91,7 @@ public class SDLControllerManager * This method is called by SDL using JNI. */ static void joystickSetSensorsEnabled(int device_id, boolean enabled) { - // Run this on the UI thread so we don't race with enableSensor() in SDLSurface.java - SDL.getContext().runOnUiThread(new Runnable() { - @Override - public void run() { - mJoystickHandler.setSensorsEnabled(device_id, enabled); - } - }); + mJoystickHandler.setSensorsEnabled(device_id, enabled); } /** From b19ecb40327333d147bc8be5850d5fe398e54c86 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 12:15:48 -0700 Subject: [PATCH 351/407] Reapply "Change controller sensor state on the main UI thread on Android" This reverts commit 02975994c12582aef918bccb3825592e7ea36d10. Accidentally reverted the wrong commit --- .../main/java/org/libsdl/app/SDLControllerManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 31b07b0ac0..2a0296eb0c 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -91,7 +91,13 @@ public class SDLControllerManager * This method is called by SDL using JNI. */ static void joystickSetSensorsEnabled(int device_id, boolean enabled) { - mJoystickHandler.setSensorsEnabled(device_id, enabled); + // Run this on the UI thread so we don't race with enableSensor() in SDLSurface.java + SDL.getContext().runOnUiThread(new Runnable() { + @Override + public void run() { + mJoystickHandler.setSensorsEnabled(device_id, enabled); + } + }); } /** From 8c89a076a7b8c70ef2ec9af8c8169c4d6775d68e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 12:17:26 -0700 Subject: [PATCH 352/407] Fixed deadlock introduced by 7222c04fbf2b904e815f5ac9c8623ef8030fd261 It turns out this change causes a deadlock: The main UI thread calls synchronized handleMotionEvent() which then calls SDL_LockJoysticks() The main app thread calls SDL_LockJoysticks() and then synchronized pollInputDevices() --- .../main/java/org/libsdl/app/SDLControllerManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 2a0296eb0c..bce15e9de2 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -346,7 +346,7 @@ class SDLJoystickHandler { } } - protected SDLJoystick getJoystick(int device_id) { + synchronized protected SDLJoystick getJoystick(int device_id) { for (SDLJoystick joystick : mJoysticks) { if (joystick.device_id == device_id) { return joystick; @@ -360,7 +360,7 @@ class SDLJoystickHandler { * @param event the event to be handled. * @return if given event was processed. */ - synchronized boolean handleMotionEvent(MotionEvent event) { + boolean handleMotionEvent(MotionEvent event) { int actionPointerIndex = event.getActionIndex(); int action = event.getActionMasked(); if (action == MotionEvent.ACTION_MOVE) { @@ -530,7 +530,7 @@ class SDLJoystickHandler { return button_mask; } - synchronized void setLED(int device_id, int red, int green, int blue) { + void setLED(int device_id, int red, int green, int blue) { if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) { return; } @@ -548,7 +548,7 @@ class SDLJoystickHandler { joystick.lightsSession.requestLights(lightsRequest.build()); } - synchronized void setSensorsEnabled(int device_id, boolean enabled) { + void setSensorsEnabled(int device_id, boolean enabled) { if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) { return; } From d8b2434047f5a74798cb567b38432e166f4d3361 Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Sun, 17 May 2026 17:22:56 -0700 Subject: [PATCH 353/407] testcontroller: correct fix for touchpad free/allocate --- test/gamepadutils.c | 51 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/test/gamepadutils.c b/test/gamepadutils.c index 0d61596b0e..f458961007 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -804,37 +804,40 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) if (num_touchpads != ctx->num_touchpads) { FreeTouchpads(ctx); ctx->num_touchpads = num_touchpads; - } - if (ctx->num_touchpads > 0) { - ctx->touchpads = (GamepadTouchpad *)SDL_malloc(sizeof(*ctx->touchpads) * ctx->num_touchpads); - if (ctx->touchpads) { - for (i = 0; i < ctx->num_touchpads; ++i) { - GamepadTouchpad *touchpad = &ctx->touchpads[i]; - touchpad->num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); - touchpad->num_fingers = SDL_min(touchpad->num_fingers, MAX_FINGERS); - if (touchpad->num_fingers > 0) { - touchpad->fingers = (GamepadTouchpadFinger *)SDL_malloc(sizeof(*touchpad->fingers) * touchpad->num_fingers); - if (touchpad->fingers) { - for (int j = 0; j < touchpad->num_fingers; ++j) { - GamepadTouchpadFinger *finger = &touchpad->fingers[j]; - SDL_GetGamepadTouchpadFinger(gamepad, i, j, &finger->down, &finger->x, &finger->y, &finger->pressure); + if (ctx->num_touchpads > 0) { + ctx->touchpads = (GamepadTouchpad *)SDL_malloc(sizeof(*ctx->touchpads) * ctx->num_touchpads); + if (ctx->touchpads) { + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + touchpad->num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); + touchpad->num_fingers = SDL_min(touchpad->num_fingers, MAX_FINGERS); + if (touchpad->num_fingers > 0) { + touchpad->fingers = (GamepadTouchpadFinger *)SDL_malloc(sizeof(*touchpad->fingers) * touchpad->num_fingers); + if (touchpad->fingers == NULL) { + touchpad->num_fingers = 0; } - } else { - touchpad->num_fingers = 0; } } - } - if (ctx->num_touchpads == 1) { - SDL_memcpy(&ctx->touchpads[0].area, &touchpad_area, sizeof(SDL_FRect)); + if (ctx->num_touchpads == 1) { + SDL_memcpy(&ctx->touchpads[0].area, &touchpad_area, sizeof(SDL_FRect)); + } else { + SDL_memcpy(&ctx->touchpads[0].area, &dual_touchpad_area[0], sizeof(SDL_FRect)); + SDL_memcpy(&ctx->touchpads[1].area, &dual_touchpad_area[1], sizeof(SDL_FRect)); + } } else { - SDL_memcpy(&ctx->touchpads[0].area, &dual_touchpad_area[0], sizeof(SDL_FRect)); - SDL_memcpy(&ctx->touchpads[1].area, &dual_touchpad_area[1], sizeof(SDL_FRect)); + ctx->num_touchpads = 0; } - } else { - ctx->num_touchpads = 0; + } + ctx->showing_touchpad = (ctx->num_touchpads > 0); + } + + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + for (int j = 0; j < touchpad->num_fingers; ++j) { + GamepadTouchpadFinger *finger = &touchpad->fingers[j]; + SDL_GetGamepadTouchpadFinger(gamepad, i, j, &finger->down, &finger->x, &finger->y, &finger->pressure); } } - ctx->showing_touchpad = (ctx->num_touchpads > 0); } void RenderGamepadImage(GamepadImage *ctx) From 14c31ee12a6456db78ad3ff2f100391416ee38a0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 17:56:33 -0700 Subject: [PATCH 354/407] Fixed reading the controller accelerometer on Apple platforms DualShock and DualSense controllers no longer have hasGravityAndUserAcceleration set, but we can still get the combined user + gravity acceleration values from those controllers, which is what we want. --- src/joystick/apple/SDL_mfijoystick.m | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m index 758da44482..ea38169dce 100644 --- a/src/joystick/apple/SDL_mfijoystick.m +++ b/src/joystick/apple/SDL_mfijoystick.m @@ -946,8 +946,6 @@ static bool IOS_JoystickOpen(SDL_Joystick *joystick, int device_index) GCMotion *motion = controller.motion; if (motion && motion.hasRotationRate) { SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f); - } - if (motion && motion.hasGravityAndUserAcceleration) { SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f); } } @@ -1198,20 +1196,17 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) if (motion && motion.sensorsActive) { float data[3]; - if (motion.hasRotationRate) { - GCRotationRate rate = motion.rotationRate; - data[0] = rate.x; - data[1] = rate.z; - data[2] = -rate.y; - SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, timestamp, data, 3); - } - if (motion.hasGravityAndUserAcceleration) { - GCAcceleration accel = motion.acceleration; - data[0] = -accel.x * SDL_STANDARD_GRAVITY; - data[1] = -accel.y * SDL_STANDARD_GRAVITY; - data[2] = -accel.z * SDL_STANDARD_GRAVITY; - SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, timestamp, data, 3); - } + GCRotationRate rate = motion.rotationRate; + data[0] = rate.x; + data[1] = rate.z; + data[2] = -rate.y; + SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, timestamp, data, 3); + + GCAcceleration accel = motion.acceleration; + data[0] = -accel.x * SDL_STANDARD_GRAVITY; + data[1] = -accel.y * SDL_STANDARD_GRAVITY; + data[2] = -accel.z * SDL_STANDARD_GRAVITY; + SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, timestamp, data, 3); } } From 8b49bff35387e44e7b49784c8a315d376c06e775 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 17 May 2026 21:42:49 -0700 Subject: [PATCH 355/407] Fixed Nintendo Switch Pro controller sensors on Android --- src/joystick/android/SDL_sysjoystick.c | 28 +++++++++++++++++++----- src/joystick/android/SDL_sysjoystick_c.h | 2 ++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 265c32e391..16992e8255 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -344,7 +344,6 @@ void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp Uint64 timestamp = SDL_GetTicksNS(); SDL_joylist_item *item; SDL_SensorType sensor; - float data[3]; if (sensor_type == 1) { // Sensor.TYPE_ACCELEROMETER sensor = SDL_SENSOR_ACCEL; @@ -355,14 +354,29 @@ void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp return; } - // The axes of sensor events and their signs are the same as SDL's, so no conversion required - data[0] = x; - data[1] = y; - data[2] = z; - SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { + float data[3]; + + if (item->vendor_id == USB_VENDOR_NINTENDO) { + // The Nintendo driver uses a different axis order than SDL + data[0] = -y; + data[1] = z; + data[2] = -x; + + if (sensor == SDL_SENSOR_GYRO) { + // The values are experimentally 3x what they should be + data[0] /= 3; + data[1] /= 3; + data[2] /= 3; + } + } else { + // The axes of sensor events and their signs are the same as SDL's, so no conversion required + data[0] = x; + data[1] = y; + data[2] = z; + } SDL_SendJoystickSensor(timestamp, item->joystick, sensor, sensor_timestamp, data, 3); } SDL_UnlockJoysticks(); @@ -427,6 +441,8 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int SDL_zerop(item); item->guid = guid; item->device_id = device_id; + item->vendor_id = vendor_id; + item->product_id = product_id; item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name); if (!item->name) { SDL_free(item); diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h index f99abb5e61..027071a2bb 100644 --- a/src/joystick/android/SDL_sysjoystick_c.h +++ b/src/joystick/android/SDL_sysjoystick_c.h @@ -42,6 +42,8 @@ typedef struct SDL_joylist_item { int device_instance; int device_id; // Android's device id + Uint16 vendor_id; + Uint16 product_id; char *name; // "SideWinder 3D Pro" or whatever SDL_GUID guid; SDL_Joystick *joystick; From 8e6fed2cbf464344b13d5dbc86a2beb2bb53f851 Mon Sep 17 00:00:00 2001 From: 7aGiven Date: Mon, 18 May 2026 17:19:02 +0800 Subject: [PATCH 356/407] fix Korean caret position --- src/video/windows/SDL_windowskeyboard.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index 9c03df7a49..dbf9bb4b66 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -802,12 +802,14 @@ static void IME_ClearComposition(SDL_VideoData *videodata) IME_SendClearComposition(videodata); } -static void IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) +static void IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, LPARAM *lParam, DWORD string) { LONG length; DWORD dwLang = ((DWORD_PTR)videodata->ime_hkl & 0xffff); - videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); + if (*lParam & GCS_CURSORPOS) { + videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); + } videodata->ime_selected_start = 0; videodata->ime_selected_length = 0; SDL_DebugIMELog("Cursor = %d", videodata->ime_cursor); @@ -887,7 +889,7 @@ static void IME_SendInputEvent(SDL_VideoData *videodata) videodata->ime_composition[0] = 0; videodata->ime_readingstring[0] = 0; - videodata->ime_cursor = 0; + videodata->ime_cursor = 1; // Korean IME cursor } static void IME_SendEditingEvent(SDL_VideoData *videodata) @@ -1074,6 +1076,7 @@ bool WIN_HandleIMEMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SD } else if (msg == WM_IME_STARTCOMPOSITION) { SDL_DebugIMELog("WM_IME_STARTCOMPOSITION"); if (videodata->ime_internal_composition) { + videodata->ime_cursor = 1; // Korean IME cursor // Windows may still display a composition dialog even with // ISC_SHOWUICOMPOSITIONWINDOW cleared, so trap the message // here to prevent that (even when the IME is disabled). @@ -1113,14 +1116,14 @@ bool WIN_HandleIMEMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SD himc = ImmGetContext(hwnd); if (*lParam & GCS_RESULTSTR) { SDL_DebugIMELog("GCS_RESULTSTR"); - IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); + IME_GetCompositionString(videodata, himc, lParam, GCS_RESULTSTR); IME_SendClearComposition(videodata); IME_SendInputEvent(videodata); } if (*lParam & GCS_COMPSTR) { SDL_DebugIMELog("GCS_COMPSTR"); videodata->ime_readingstring[0] = 0; - IME_GetCompositionString(videodata, himc, GCS_COMPSTR); + IME_GetCompositionString(videodata, himc, lParam, GCS_COMPSTR); IME_SendEditingEvent(videodata); } ImmReleaseContext(hwnd, himc); From a20530cf15e1edf9d1444263a03e1fe44731c691 Mon Sep 17 00:00:00 2001 From: Kuratius <47481645+Kuratius@users.noreply.github.com> Date: Mon, 18 May 2026 16:03:56 +0200 Subject: [PATCH 357/407] Fix Steam Controller 2 touchpad finger detection (#15644) --- src/joystick/hidapi/SDL_hidapi_steam_triton.c | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index 97152d359c..9339bcb4aa 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -103,6 +103,13 @@ typedef struct Uint16 low_frequency_rumble; Uint16 high_frequency_rumble; Uint64 last_rumble_time; + + bool left_touch_down; + float left_touch_x; + float left_touch_y; + bool right_touch_down; + float right_touch_x; + float right_touch_y; } SDL_DriverSteamTriton_Context; static bool IsProteusDongle(Uint16 product_id) @@ -243,17 +250,33 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, ctx->last_sensor_tick = pTritonReport->imu.timestamp; } - SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, - pTritonReport->sPressureLeft > 0, - pTritonReport->sLeftPadX / 65536.0f + 0.5f, - -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f, - pTritonReport->sPressureLeft / 32768.0f); + bool left_touch_down = (pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_TOUCH) ? true : false; + bool right_touch_down = (pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_TOUCH) ? true : false; + if (left_touch_down || ctx->left_touch_down) { + if (left_touch_down) { + ctx->left_touch_x = pTritonReport->sLeftPadX / 65536.0f + 0.5f; + ctx->left_touch_y = -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f; - SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, - pTritonReport->sPressureRight > 0, - pTritonReport->sRightPadX / 65536.0f + 0.5f, - -(float)pTritonReport->sRightPadY / 65536.0f + 0.5f, - pTritonReport->sPressureRight / 32768.0f); + } + SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, + left_touch_down, + ctx->left_touch_x, + ctx->left_touch_y, + pTritonReport->sPressureLeft / 32768.0f); + ctx->left_touch_down = left_touch_down; + } + if (right_touch_down || ctx->right_touch_down) { + if (right_touch_down) { + ctx->right_touch_x = pTritonReport->sRightPadX / 65536.0f + 0.5f; + ctx->right_touch_y = -(float)pTritonReport->sRightPadY / 65536.0f + 0.5f; + } + SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, + right_touch_down, + ctx->right_touch_x, + ctx->right_touch_y, + pTritonReport->sPressureRight / 32768.0f); + ctx->right_touch_down = right_touch_down; + } } static void HIDAPI_DriverSteamTriton_HandleBatteryStatus(SDL_HIDAPI_Device *device, From 296231e999a5fc44841ad16c207a12067f0d6af8 Mon Sep 17 00:00:00 2001 From: 7aGiven Date: Mon, 18 May 2026 12:46:06 +0800 Subject: [PATCH 358/407] WM_IME_SETCONTEXT not set 0 --- src/video/windows/SDL_windowskeyboard.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index dbf9bb4b66..6d8cd52458 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -1059,16 +1059,12 @@ bool WIN_HandleIMEMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SD SDL_DebugIMELog("WM_IME_SETCONTEXT"); LPARAM element_mask; - if (videodata->ime_internal_composition && videodata->ime_internal_candidates) { - element_mask = 0; - } else { - element_mask = ISC_SHOWUIALL; - if (videodata->ime_internal_composition) { - element_mask &= ~ISC_SHOWUICOMPOSITIONWINDOW; - } - if (videodata->ime_internal_candidates) { - element_mask &= ~ISC_SHOWUIALLCANDIDATEWINDOW; - } + element_mask = ISC_SHOWUIALL; + if (videodata->ime_internal_composition) { + element_mask &= ~ISC_SHOWUICOMPOSITIONWINDOW; + } + if (videodata->ime_internal_candidates) { + element_mask &= ~ISC_SHOWUIALLCANDIDATEWINDOW; } *lParam &= element_mask; From 8d9d6b1b2b04343e3bacab6ef48cecfd16ca598b Mon Sep 17 00:00:00 2001 From: Gabriel Wang Date: Mon, 18 May 2026 14:16:22 +0800 Subject: [PATCH 359/407] apply simplified sve2 macro protection --- src/video/SDL_blit_A.c | 8 ++++---- src/video/SDL_blit_N.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index ea94d6affc..60e48e71d9 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -25,7 +25,7 @@ #include "SDL_pixels_c.h" #include "SDL_surface_c.h" -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS #include "./arm/SDL_sve2_blit_A.h" #endif @@ -1481,7 +1481,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) } case 2: -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS if (SDL_HasSVE2()) { if (sf->bytes_per_pixel == 4 && df->bytes_per_pixel == 2 && @@ -1519,11 +1519,11 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) return Blit8888to8888PixelAlphaSwizzleLSX; } #endif -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS if (SDL_HasSVE2() /* NEON is faster than SVE2 when vector size is 128bit */ #if defined(SDL_NEON_INTRINSICS) - && SDL_GetSVEVectorSize() > 128 + && (SDL_GetSVEVectorSize() > 128 || !SDL_HasNEON()) #endif ) { // To prevent "unused function" compiler warnings/errors diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 5958374c8f..67ef65bb6c 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -26,7 +26,7 @@ #include "SDL_surface_c.h" #include "SDL_blit_copy.h" -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS #include "./arm/SDL_sve2_blit_N.h" #endif @@ -3121,7 +3121,7 @@ SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface) return Blit8888to8888PixelSwizzleSSE41; } #endif -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS if (SDL_HasSVE2()) { return Blit8888to8888PixelSwizzleSVE2; } @@ -3132,7 +3132,7 @@ SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface) } #endif } -#if defined(SDL_SVE2_INTRINSICS) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) +#ifdef SDL_SVE2_INTRINSICS if (SDL_HasSVE2()) { /* RGBA8888/ARGB8888/XRGB8888 -> RGB565 */ if (srcfmt->bytes_per_pixel == 4 && From e07cfdff2ccf2fb3a6abf5d3093c30fbd594af9b Mon Sep 17 00:00:00 2001 From: Gabriel Wang Date: Mon, 18 May 2026 14:32:10 +0800 Subject: [PATCH 360/407] adds sdl_sve_chn_blend_with_mask_fast for RGB565 alpha-blending --- src/video/arm/SDL_sve2_blit_A.c | 12 ++++++------ src/video/arm/SDL_sve2_extension.h | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/video/arm/SDL_sve2_blit_A.c b/src/video/arm/SDL_sve2_blit_A.c index be029bcc70..606df3b060 100644 --- a/src/video/arm/SDL_sve2_blit_A.c +++ b/src/video/arm/SDL_sve2_blit_A.c @@ -51,12 +51,12 @@ } #undef sdl_sve_rgb32_blend_to_rgb565_op -#define sdl_sve_rgb32_blend_to_rgb565_op(ma_alpha_chn_idx) \ - do { \ - svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ - sve_target_u16 = sdl_sve_chn_blend_with_mask(sve_source_u16, \ - sve_target_u16, \ - vMask); \ +#define sdl_sve_rgb32_blend_to_rgb565_op(ma_alpha_chn_idx) \ + do { \ + svuint16_t vMask = svget4(sve_source_u16x4, (ma_alpha_chn_idx)); \ + sve_target_u16 = sdl_sve_chn_blend_with_mask_fast(sve_source_u16, \ + sve_target_u16, \ + vMask); \ } while (0) #include "SDL_sve2_swizzle.h" diff --git a/src/video/arm/SDL_sve2_extension.h b/src/video/arm/SDL_sve2_extension.h index 2f5a74a12b..3e2327a79c 100644 --- a/src/video/arm/SDL_sve2_extension.h +++ b/src/video/arm/SDL_sve2_extension.h @@ -902,7 +902,9 @@ static inline void svst4ub_u16(svbool_t vPredu8, /*! \note the Element range of vMask is [0, 0xFF] */ SDL_TARGETING("arch=armv8-a+sve2") -static inline svuint16_t sdl_sve_chn_blend_with_mask(svuint16_t vSource, svuint16_t vTarget, svuint16_t vMask) +static inline svuint16_t sdl_sve_chn_blend_with_mask(svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask) { // vTarget = vSource * vMask + vTarget * (255 - vMask); svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); @@ -924,6 +926,25 @@ static inline svuint16_t sdl_sve_chn_blend_with_mask(svuint16_t vSource, svuint1 return svlsr_n_u16_m(svptrue_b16(), vTemp0, 8); // vTarget >> 8; } +/*! \note the Element range of vMask is [0, 0xFF] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_mask_fast(svuint16_t vSource, + svuint16_t vTarget, + svuint16_t vMask) +{ + // vTarget = vSource * vMask + vTarget * (255 - vMask); + svuint16_t vTemp0 = svmul_u16_m(svptrue_b16(), vSource, vMask); + vTemp0 = svmla_u16_m(svptrue_b16(), + vTemp0, + vTarget, + svsub_u16_m(svptrue_b16(), + svdup_u16(255), + vMask)); + + return svlsr_n_u16_m(svptrue_b16(), vTemp0, 8); // vTarget >> 8; +} + /*! \note the hwOpacity range [0, 0x100] */ SDL_TARGETING("arch=armv8-a+sve2") From 508450e9c05405e306a26dbe7972e6ba60656e15 Mon Sep 17 00:00:00 2001 From: Gabriel Wang Date: Mon, 18 May 2026 15:31:22 +0800 Subject: [PATCH 361/407] adds Blit565to565SurfaceAlphaSVE2 --- src/video/SDL_blit_A.c | 5 ++ src/video/arm/SDL_sve2_blit_A.c | 97 ++++++++++++++++++++++++++++++ src/video/arm/SDL_sve2_blit_A.h | 2 + src/video/arm/SDL_sve2_extension.h | 17 ++++++ 4 files changed, 121 insertions(+) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 60e48e71d9..1057493e63 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1570,6 +1570,11 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) if (SDL_HasMMX()) { return Blit565to565SurfaceAlphaMMX; } else +#endif +#ifdef SDL_SVE2_INTRINSICS + if (SDL_HasSVE2()) { + return Blit565to565SurfaceAlphaSVE2; + } else #endif { return Blit565to565SurfaceAlpha; diff --git a/src/video/arm/SDL_sve2_blit_A.c b/src/video/arm/SDL_sve2_blit_A.c index 606df3b060..ef4dd5fff5 100644 --- a/src/video/arm/SDL_sve2_blit_A.c +++ b/src/video/arm/SDL_sve2_blit_A.c @@ -86,4 +86,101 @@ size_t SDL_GetSVEVectorSize(void) return svlen(svundef_u8()) * 8; } +/*-----------------------------------------------------------------------------* + * RGB565 Blend with Surface Alpha * + *-----------------------------------------------------------------------------*/ +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 2) +static inline void sdl_sve_rgb565_stride_blend_with_opacity(uint16_t *SDL_RESTRICT phwSource, + uint16_t *SDL_RESTRICT phwTarget, + size_t uStride, + uint16_t hwOpacity) +{ + sdl_sve_stride_loop_rgb16(uStride, vTailPred) + { + + svuint16x3_t vSource16x3 = + sdl_sve_rgb565_unpack(svld1_u16(vTailPred, phwSource)); + + svuint16x3_t vTarget16x3 = + sdl_sve_rgb565_unpack(svld1_u16(vTailPred, phwTarget)); + + sdl_sve_pixel_ccc_foreach_chn( + vSource16x3, + vTarget16x3, + { + sve_target_u16 = sdl_sve_chn_blend_with_opacity_fast( + sve_source_u16, + sve_target_u16, + hwOpacity); + }); + + svst1_u16(vTailPred, phwTarget, sdl_sve_rgb565_pack(vTarget16x3)); + + phwSource += sve_iteration_advance; + phwTarget += sve_iteration_advance; + } +} + +SDL_TARGETING("arch=armv8-a+sve2") +ARM_NONNULL(1, 3) +static inline void sdl_sve_rgb565_blend_with_opacity(uint8_t *SDL_RESTRICT pchSource, + size_t uSourceStride, + uint8_t *SDL_RESTRICT pchTarget, + size_t uTargetStride, + int nWidth, + int nHeight, + uint16_t hwOpacity) +{ + hwOpacity += hwOpacity == 255; + assert(0 == ((uintptr_t)pchSource & 0x01)); + assert(0 == ((uintptr_t)pchTarget & 0x01)); + + while (nHeight--) { + + sdl_sve_rgb565_stride_blend_with_opacity((uint16_t *)pchSource, + (uint16_t *)pchTarget, + nWidth, + hwOpacity); + + pchSource += uSourceStride; + pchTarget += uTargetStride; + } +} + +// fast RGB565->RGB565 blending with surface alpha +SDL_TARGETING("arch=armv8-a+sve2") +void Blit565to565SurfaceAlphaSVE2(SDL_BlitInfo *info) +{ + uint16_t alpha = info->a; + + int width = info->dst_w; + int height = info->dst_h; + uint8_t *src = info->src; + int srcskip = info->src_skip; + uint8_t *dst = info->dst; + int dstskip = info->dst_skip; + + const SDL_PixelFormatDetails *srcfmt = info->src_fmt; + const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; + + // Set up some basic variables + int srcbpp = srcfmt->bytes_per_pixel; + int dstbpp = dstfmt->bytes_per_pixel; + + assert(srcbpp == 2); + assert(dstbpp == 2); + + int srcstride = srcskip + srcbpp * width; + int dststride = dstskip + dstbpp * width; + + sdl_sve_rgb565_blend_with_opacity(src, + srcstride, + dst, + dststride, + width, + height, + alpha); +} + #endif /* SDL_SVE2_INTRINSICS */ \ No newline at end of file diff --git a/src/video/arm/SDL_sve2_blit_A.h b/src/video/arm/SDL_sve2_blit_A.h index 2a7e2b8149..2a86295566 100644 --- a/src/video/arm/SDL_sve2_blit_A.h +++ b/src/video/arm/SDL_sve2_blit_A.h @@ -30,6 +30,8 @@ void Blit8888to8888PixelAlphaSwizzleSVE2(SDL_BlitInfo *info); void Blit8888to565PixelAlphaSwizzleSVE2(SDL_BlitInfo *info); +void Blit565to565SurfaceAlphaSVE2(SDL_BlitInfo *info); + size_t SDL_GetSVEVectorSize(void); #endif /* SDL_SVE2_INTRINSICS */ diff --git a/src/video/arm/SDL_sve2_extension.h b/src/video/arm/SDL_sve2_extension.h index 3e2327a79c..b9db084bba 100644 --- a/src/video/arm/SDL_sve2_extension.h +++ b/src/video/arm/SDL_sve2_extension.h @@ -964,6 +964,23 @@ static inline svuint16_t sdl_sve_chn_blend_with_opacity(svuint16_t vSource, return svlsr_n_u16_m(svptrue_b16(), vTarget, 8); // vTarget >> 8; } +/*! \note the hwOpacity range [0, 0x100] + */ +SDL_TARGETING("arch=armv8-a+sve2") +static inline svuint16_t sdl_sve_chn_blend_with_opacity_fast(svuint16_t vSource, + svuint16_t vTarget, + uint16_t hwOpacity) +{ + // vTarget = vSource * vMask + vTarget * (255 - vMask); + svuint16_t vTemp0 = svmul_n_u16_m(svptrue_b16(), vSource, hwOpacity); + vTemp0 = svmla_n_u16_m(svptrue_b16(), + vTemp0, + vTarget, + 256 - hwOpacity); + + return svlsr_n_u16_m(svptrue_b16(), vTemp0, 8); // vTarget >> 8; +} + /*! \note the Element range of vMask is [0, 0xFF] * \note the hwOpacity range [0, 0x100] */ From bf03728873547aa82a19ea624a7f05d698edabc3 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 18 May 2026 17:40:20 +0300 Subject: [PATCH 362/407] wasapi: workaround that AudioClientProperties->Options not being available in old SDKs Closes: https://github.com/libsdl-org/SDL/issues/15641. --- src/audio/wasapi/SDL_wasapi.c | 36 ++++++++++++++++++++++++---------- src/core/windows/SDL_windows.c | 5 +++++ src/core/windows/SDL_windows.h | 3 +++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index 2ef4de82fe..bdbbf81772 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -64,6 +64,19 @@ static const IID SDL_IID_IAudioClient3 = { 0x7ed4ee07, 0x8e67, 0x4cd4, { 0x8c, 0 static bool immdevice_initialized = false; static bool supports_recording_on_playback_devices = false; +#ifdef __IAudioClient2_INTERFACE_DEFINED__ +#define SDL_AUDCLNT_STREAMOPTIONS_RAW 0x1 +typedef union SDL_AudioClientProperties { + AudioClientProperties a; + struct _SDL_AudioClientProperties { + UINT32 cbSize; + BOOL bIsOffload; + AUDIO_STREAM_CATEGORY eCategory; + int Options; // AUDCLNT_STREAMOPTIONS + } s; +} SDL_AudioClientProperties; +#endif // + // WASAPI is _really_ particular about various things happening on the same thread, for COM and such, // so we proxy various stuff to a single background thread to manage. @@ -741,10 +754,10 @@ static bool mgmtthrtask_PrepDevice(void *userdata) IAudioClient2 *client2 = NULL; ret = IAudioClient_QueryInterface(client, &SDL_IID_IAudioClient2, (void **)&client2); if (SUCCEEDED(ret)) { - AudioClientProperties audioProps; + SDL_AudioClientProperties audioProps; SDL_zero(audioProps); - audioProps.cbSize = sizeof(audioProps); + audioProps.a.cbSize = sizeof(audioProps); // Setting AudioCategory_GameChat breaks audio on several devices, including Behringer U-PHORIA UM2 and RODE NT-USB Mini. // We'll disable this for now until we understand more about what's happening. @@ -752,25 +765,28 @@ static bool mgmtthrtask_PrepDevice(void *userdata) const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE); if (hint && *hint) { if (SDL_strcasecmp(hint, "Communications") == 0) { - audioProps.eCategory = AudioCategory_Communications; + audioProps.a.eCategory = AudioCategory_Communications; } else if (SDL_strcasecmp(hint, "Game") == 0) { // We'll add support for GameEffects as distinct from GameMedia later when we add stream roles - audioProps.eCategory = AudioCategory_GameEffects; + audioProps.a.eCategory = AudioCategory_GameEffects; } else if (SDL_strcasecmp(hint, "GameChat") == 0) { - audioProps.eCategory = AudioCategory_GameChat; + audioProps.a.eCategory = AudioCategory_GameChat; } else if (SDL_strcasecmp(hint, "Movie") == 0) { - audioProps.eCategory = AudioCategory_Movie; + audioProps.a.eCategory = AudioCategory_Movie; } else if (SDL_strcasecmp(hint, "Media") == 0) { - audioProps.eCategory = AudioCategory_Media; + audioProps.a.eCategory = AudioCategory_Media; } } #endif - if (SDL_GetHintBoolean(SDL_HINT_AUDIO_DEVICE_RAW_STREAM, false)) { - audioProps.Options = AUDCLNT_STREAMOPTIONS_RAW; + if (WIN_IsWindows81OrGreater() && + SDL_GetHintBoolean(SDL_HINT_AUDIO_DEVICE_RAW_STREAM, false)) { + audioProps.s.Options = SDL_AUDCLNT_STREAMOPTIONS_RAW; + } else { + audioProps.a.cbSize = sizeof (AudioClientProperties); } - ret = IAudioClient2_SetClientProperties(client2, &audioProps); + ret = IAudioClient2_SetClientProperties(client2, (AudioClientProperties *)&audioProps); if (FAILED(ret)) { // This isn't fatal, let's log it instead of failing SDL_LogWarn(SDL_LOG_CATEGORY_AUDIO, "IAudioClient2_SetClientProperties failed: 0x%" SDL_PRIxSLONG, ret); diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index eaedd59e96..0be19bd2ec 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -374,6 +374,11 @@ BOOL WIN_IsWindows8OrGreater(void) CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0)); } +BOOL WIN_IsWindows81OrGreater(void) +{ + CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0)); +} + BOOL WIN_IsWindows11OrGreater(void) { return IsWindowsBuildVersionAtLeast(22000); diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index 62c1c3a9af..0a7c785493 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -193,6 +193,9 @@ extern BOOL WIN_IsWindows7OrGreater(void); // Returns true if we're running on Windows 8 and newer extern BOOL WIN_IsWindows8OrGreater(void); +// Returns true if we're running on Windows 8.1 and newer +extern BOOL WIN_IsWindows81OrGreater(void); + // Returns true if we're running on Windows 11 and newer extern BOOL WIN_IsWindows11OrGreater(void); From b5ac64137206088287c25f7cb78c40cf12d4fcdf Mon Sep 17 00:00:00 2001 From: Ahmed Date: Mon, 18 May 2026 15:46:31 +0100 Subject: [PATCH 363/407] examples: Fix float division --- examples/demo/02-woodeneye-008/woodeneye-008.c | 2 +- examples/renderer/05-rectangles/rectangles.c | 2 +- examples/renderer/18-debug-text/debug-text.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/demo/02-woodeneye-008/woodeneye-008.c b/examples/demo/02-woodeneye-008/woodeneye-008.c index 9a53323d94..cac676c5ce 100644 --- a/examples/demo/02-woodeneye-008/woodeneye-008.c +++ b/examples/demo/02-woodeneye-008/woodeneye-008.c @@ -206,7 +206,7 @@ static void draw(SDL_Renderer *renderer, const float (*edges)[6], const Player p for (i = 0; i < players_len; i++) { const Player *player = &players[i]; float mod_x = (float)(i % part_hor); - float mod_y = (float)(i / part_hor); + float mod_y = (float)i / part_hor; float hor_origin = (mod_x + 0.5f) * size_hor; float ver_origin = (mod_y + 0.5f) * size_ver; float cam_origin = (float)(0.5 * SDL_sqrt(size_hor * size_hor + size_ver * size_ver)); diff --git a/examples/renderer/05-rectangles/rectangles.c b/examples/renderer/05-rectangles/rectangles.c index e326a40e7e..ad00b60790 100644 --- a/examples/renderer/05-rectangles/rectangles.c +++ b/examples/renderer/05-rectangles/rectangles.c @@ -90,7 +90,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) /* ...and also fill a bunch of rectangles at once... */ for (i = 0; i < SDL_arraysize(rects); i++) { - const float w = (float) (WINDOW_WIDTH / SDL_arraysize(rects)); + const float w = ((float) WINDOW_WIDTH / SDL_arraysize(rects)); const float h = i * 8.0f; rects[i].x = i * w; rects[i].y = WINDOW_HEIGHT - h; diff --git a/examples/renderer/18-debug-text/debug-text.c b/examples/renderer/18-debug-text/debug-text.c index f5150d210b..7207698342 100644 --- a/examples/renderer/18-debug-text/debug-text.c +++ b/examples/renderer/18-debug-text/debug-text.c @@ -66,7 +66,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) SDL_SetRenderScale(renderer, 1.0f, 1.0f); SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣"); - SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000); + SDL_RenderDebugTextFormat(renderer, ((float) (WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000); SDL_RenderPresent(renderer); /* put it all on the screen! */ From b608108593ce3770426bc45be5a48db649d41e79 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Mon, 18 May 2026 17:28:31 +0200 Subject: [PATCH 364/407] Properly fix cursor position in Korean IME --- src/video/windows/SDL_windowskeyboard.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index 6d8cd52458..b114772d85 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -828,6 +828,11 @@ static void IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, LPARAM } length /= sizeof(WCHAR); + if (!(*lParam & GCS_CURSORPOS)) { + // If the IME doesn't support GCS_CURSORPOS, default the cursor to the end of the composition. + videodata->ime_cursor = length; + } + if ((dwLang == LANG_CHT || dwLang == LANG_CHS) && videodata->ime_cursor > 0 && videodata->ime_cursor < (int)(videodata->ime_composition_length / sizeof(WCHAR)) && @@ -889,7 +894,7 @@ static void IME_SendInputEvent(SDL_VideoData *videodata) videodata->ime_composition[0] = 0; videodata->ime_readingstring[0] = 0; - videodata->ime_cursor = 1; // Korean IME cursor + videodata->ime_cursor = 0; } static void IME_SendEditingEvent(SDL_VideoData *videodata) @@ -1072,7 +1077,7 @@ bool WIN_HandleIMEMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SD } else if (msg == WM_IME_STARTCOMPOSITION) { SDL_DebugIMELog("WM_IME_STARTCOMPOSITION"); if (videodata->ime_internal_composition) { - videodata->ime_cursor = 1; // Korean IME cursor + videodata->ime_cursor = 0; // Windows may still display a composition dialog even with // ISC_SHOWUICOMPOSITIONWINDOW cleared, so trap the message // here to prevent that (even when the IME is disabled). From f31ca02723f57f84dc03fd19b2f5a3e4b8a15bda Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 17 May 2026 10:45:32 -0400 Subject: [PATCH 365/407] video: Windows keep any position set when in fullscreen after leaving fullscreen Adds an automated test for the behavior as well. --- src/video/SDL_video.c | 8 +++ src/video/cocoa/SDL_cocoawindow.m | 12 +++-- src/video/x11/SDL_x11window.c | 3 ++ src/video/x11/SDL_x11window.h | 1 + test/testautomation_video.c | 90 +++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 318f05b1df..36f3dc89f5 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3051,6 +3051,14 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y) window->pending.x = x; window->pending.y = y; + + /* Windows are placed at the coordinates received while in fullscreen after leaving fullscreen. + * Asynchronous backends need special handling in this case. + */ + if (!_this->SyncWindow && (window->flags & SDL_WINDOW_FULLSCREEN)) { + window->floating.x = window->windowed.x = x; + window->floating.y = window->windowed.y = y; + } window->undefined_x = false; window->undefined_y = false; window->last_position_pending = true; diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 79c17713eb..5b8ffcdc96 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1461,7 +1461,6 @@ static NSCursor *Cocoa_GetDesiredCursor(void) } SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0); - _data.pending_position = NO; _data.pending_size = NO; /* Force the size change event in case it was delivered earlier @@ -2605,7 +2604,7 @@ bool Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window) BOOL fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO; int x, y; - if ([windata.listener isInFullscreenSpaceTransition]) { + if (fullscreen || [windata.listener isInFullscreenSpaceTransition]) { windata.pending_position = YES; return true; } @@ -3030,8 +3029,13 @@ SDL_FullscreenResult Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Windo SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0); - rect.origin.x = data.was_zoomed ? window->windowed.x : window->floating.x; - rect.origin.y = data.was_zoomed ? window->windowed.y : window->floating.y; + if (data.pending_position) { + rect.origin.x = window->pending.x; + rect.origin.y = window->pending.y; + } else { + rect.origin.x = data.was_zoomed ? window->windowed.x : window->floating.x; + rect.origin.y = data.was_zoomed ? window->windowed.y : window->floating.y; + } rect.size.width = data.was_zoomed ? window->windowed.w : window->floating.w; rect.size.height = data.was_zoomed ? window->windowed.h : window->floating.h; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index b1f982a32e..a0864d71b4 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1200,6 +1200,7 @@ bool X11_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window) } X11_UpdateWindowPosition(window, false); } else { + window->internal->fs_repositioned = true; SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, true); } return true; @@ -1921,6 +1922,8 @@ static SDL_FullscreenResult X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, } } else { SDL_zero(data->requested_fullscreen_mode); + data->pending_position = data->fs_repositioned; + data->fs_repositioned = false; /* Fullscreen windows sometimes end up being marked maximized by * window managers. Force it back to how we expect it to be. diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 5335ae8001..1ba725b9bd 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -111,6 +111,7 @@ struct SDL_WindowData bool pending_size; bool pending_position; + bool fs_repositioned; bool window_was_maximized; bool previous_borders_nonzero; bool toggle_borders; diff --git a/test/testautomation_video.c b/test/testautomation_video.c index ad1e3b1c8d..8a784353cf 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -843,6 +843,7 @@ static int SDLCALL video_getSetWindowPosition(void *arg) { const char *title = "video_getSetWindowPosition Test Window"; SDL_Window *window; + SDL_WindowFlags flags; int result; int maxxVariation, maxyVariation; int xVariation, yVariation; @@ -974,6 +975,95 @@ static int SDLCALL video_getSetWindowPosition(void *arg) } } + /* Fullscreen test */ + desiredX = 100; + desiredY = 100; + SDL_SetWindowPosition(window, desiredX, desiredY); + SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY); + + result = SDL_SyncWindow(window); + SDLTest_AssertPass("SDL_SyncWindow()"); + SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result); + + /* Get position */ + currentX = desiredX + 1; + currentY = desiredY + 1; + SDL_GetWindowPosition(window, ¤tX, ¤tY); + SDLTest_AssertPass("Call to SDL_GetWindowPosition()"); + + if (desiredX == currentX && desiredY == currentY) { + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); + } else { + bool hasEvent; + /* SDL_SetWindowPosition() and SDL_SetWindowSize() will make requests of the window manager and set the internal position and size, + * and then we get events signaling what actually happened, and they get passed on to the application if they're not what we expect. */ + currentX = desiredX + 1; + currentY = desiredY + 1; + hasEvent = getPositionFromEvent(¤tX, ¤tY); + SDLTest_AssertCheck(hasEvent == true, "Changing position was not honored by WM, checking present of SDL_EVENT_WINDOW_MOVED"); + if (hasEvent) { + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position is the position from SDL event; expected: %d, got: %d", desiredX, currentX); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position is the position from SDL event; expected: %d, got: %d", desiredY, currentY); + } + } + + /* Test setting position while fullscreen */ + result = SDL_SetWindowFullscreen(window, true); + SDLTest_AssertPass("SDL_SetWindowFullscreen()"); + SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result); + + result = SDL_SyncWindow(window); + SDLTest_AssertPass("SDL_SyncWindow()"); + SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result); + + /* Verify that window is in fullscreen */ + flags = SDL_GetWindowFlags(window); + SDLTest_AssertPass("SDL_GetWindowFlags()"); + SDLTest_AssertCheck(flags & SDL_WINDOW_FULLSCREEN, "Verify the `SDL_WINDOW_FULLSCREEN` flag is set: %s", (flags & SDL_WINDOW_FULLSCREEN) ? "true" : "false"); + + /* Set the fullscreen window position */ + desiredX = desiredX + 10; + desiredY = desiredY + 10; + SDL_SetWindowPosition(window, desiredX, desiredY); + SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY); + + result = SDL_SetWindowFullscreen(window, false); + SDLTest_AssertPass("SDL_SetWindowFullscreen()"); + SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result); + + result = SDL_SyncWindow(window); + SDLTest_AssertPass("SDL_SyncWindow()"); + SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result); + + /* Verify that window left fullscreen */ + flags = SDL_GetWindowFlags(window); + SDLTest_AssertPass("SDL_GetWindowFlags()"); + SDLTest_AssertCheck(!(flags & SDL_WINDOW_FULLSCREEN), "Verify the `SDL_WINDOW_FULLSCREEN` flag is not set: %s", !(flags & SDL_WINDOW_FULLSCREEN) ? "true" : "false"); + + /* Get position */ + currentX = desiredX + 1; + currentY = desiredY + 1; + SDL_GetWindowPosition(window, ¤tX, ¤tY); + SDLTest_AssertPass("Call to SDL_GetWindowPosition()"); + + if (desiredX == currentX && desiredY == currentY) { + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); + } else { + bool hasEvent; + /* SDL_SetWindowPosition() and SDL_SetWindowSize() will make requests of the window manager and set the internal position and size, + * and then we get events signaling what actually happened, and they get passed on to the application if they're not what we expect. */ + currentX = desiredX + 1; + currentY = desiredY + 1; + hasEvent = getPositionFromEvent(¤tX, ¤tY); + SDLTest_AssertCheck(hasEvent == true, "Changing position was not honored by WM, checking present of SDL_EVENT_WINDOW_MOVED"); + if (hasEvent) { + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position is the position from SDL event; expected: %d, got: %d", desiredX, currentX); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position is the position from SDL event; expected: %d, got: %d", desiredY, currentY); + } + } + null_tests: /* Dummy call with both pointers NULL */ From e759cc850e29d8aa8e13e0cdec66fe285f54ba89 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 May 2026 09:23:38 -0700 Subject: [PATCH 366/407] Added an internal type for the Nintendo Switch 2 Pro controller --- src/joystick/SDL_joystick.c | 5 ++++- src/joystick/controller_list.h | 2 +- src/joystick/controller_type.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 3e3fb95d5b..1b8278fc12 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3163,6 +3163,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons } break; case k_eControllerType_SwitchProController: + case k_eControllerType_Switch2ProController: case k_eControllerType_SwitchInputOnlyController: type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO; break; @@ -3287,7 +3288,9 @@ bool SDL_IsJoystickDualSenseEdge(Uint16 vendor_id, Uint16 product_id) bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id) { EControllerType eType = GuessControllerType(vendor_id, product_id); - return eType == k_eControllerType_SwitchProController || eType == k_eControllerType_SwitchInputOnlyController; + return eType == k_eControllerType_SwitchProController || + eType == k_eControllerType_Switch2ProController || + eType == k_eControllerType_SwitchInputOnlyController; } bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id) diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index 7b53741a53..428035427e 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -601,7 +601,7 @@ static const ControllerDescription_t arrControllers[] = { // * ZhiXu Gamepad Wireless // * Sunwaytek Wireless Motion Controller for Nintendo Switch { MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch Pro Controller - { MAKE_CONTROLLER_ID( 0x057e, 0x2069 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch 2 Pro Controller + { MAKE_CONTROLLER_ID( 0x057e, 0x2069 ), k_eControllerType_Switch2ProController, NULL }, // Nintendo Switch 2 Pro Controller //{ MAKE_CONTROLLER_ID( 0x057e, 0x2017 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SNES Controller //{ MAKE_CONTROLLER_ID( 0x057e, 0x2019 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online N64 Controller //{ MAKE_CONTROLLER_ID( 0x057e, 0x201e ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SEGA Genesis Controller diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h index cc49ae6f3c..028a83dfac 100644 --- a/src/joystick/controller_type.h +++ b/src/joystick/controller_type.h @@ -63,6 +63,7 @@ typedef enum k_eControllerType_PS5EdgeController = 48, k_eControllerType_HoriSteamController = 49, k_eControllerType_8BitDoController = 50, + k_eControllerType_Switch2ProController = 51, k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value // Keyboards and Mice From b4ebf70e0c6cc857a99dff9b9532910afd25ae1d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 May 2026 12:54:57 -0700 Subject: [PATCH 367/407] visionOS: dimming doesn't seem to be reliable, so disable it for now --- .../uikit/SDL_CurvedContentHosting.swift | 37 +++++++++++-------- src/video/uikit/SDL_CurvedContentView.swift | 2 +- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/video/uikit/SDL_CurvedContentHosting.swift b/src/video/uikit/SDL_CurvedContentHosting.swift index d8dccaf3bd..3648c391e8 100644 --- a/src/video/uikit/SDL_CurvedContentHosting.swift +++ b/src/video/uikit/SDL_CurvedContentHosting.swift @@ -263,6 +263,7 @@ internal class SDL_CurvedContentSettings { var inputType: InputType = .eyes var showHover: Bool = true + var enableDimming: Bool = false // Doesn't seem to be reliable at the moment var isDimmed: Bool = false var curvatureRadius: Float = 0.0 var sceneState: SceneState = .interactive @@ -319,8 +320,10 @@ struct SDL_SettingsPanelView: View { HStack(spacing: 12) { Image(systemName: settings.showHover ? "eye" : "eye.slash") - Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") - .foregroundStyle(settings.isDimmed ? .primary : .secondary) + if settings.enableDimming { + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) + } Divider().frame(height: 8) @@ -341,8 +344,10 @@ struct SDL_SettingsPanelView: View { VStack(spacing: 12) { Image(systemName: settings.showHover ? "eye" : "eye.slash") - Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") - .foregroundStyle(settings.isDimmed ? .primary : .secondary) + if settings.enableDimming { + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) + } Divider().frame(height: 8) @@ -389,19 +394,21 @@ struct SDL_SettingsPanelView: View { Image(systemName: "eye") Spacer() - Spacer() - Image(systemName: "sun.max") + if settings.enableDimming { + Spacer() + Image(systemName: "sun.max") - Toggle(isOn: $settings.isDimmed) { - } - .onChange(of: settings.isDimmed) { - settings.save() - } - .labelsHidden() - .tint(.secondary) + Toggle(isOn: $settings.isDimmed) { + } + .onChange(of: settings.isDimmed) { + settings.save() + } + .labelsHidden() + .tint(.secondary) - Image(systemName: "moon.fill") - Spacer() + Image(systemName: "moon.fill") + Spacer() + } } // Curvature slider diff --git a/src/video/uikit/SDL_CurvedContentView.swift b/src/video/uikit/SDL_CurvedContentView.swift index 36317e71db..bbb7328093 100644 --- a/src/video/uikit/SDL_CurvedContentView.swift +++ b/src/video/uikit/SDL_CurvedContentView.swift @@ -273,7 +273,7 @@ internal struct SDL_CurvedContentView: View { settings.isSnapped = snappedStatus.isSnapped helper.updateSnappedStatus(snapped: snappedStatus.isSnapped) } - .preferredSurroundingsEffect(settings.isDimmed ? .dark : nil) + .preferredSurroundingsEffect(settings.enableDimming && settings.isDimmed ? .dark : nil) .frame(depth: 0) .ignoresSafeArea() .persistentSystemOverlays(settings.sceneState == .cinematic ? .hidden : .automatic) From 7f7c1628cb38c9cc6936d88740cca709b754f016 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 May 2026 13:00:00 -0700 Subject: [PATCH 368/407] visionOS: use black instead of white for the mouse overlay White is easier to see and people notice the overlay showing up when mouse input is enabled --- src/video/uikit/SDL_CurvedContentView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/uikit/SDL_CurvedContentView.swift b/src/video/uikit/SDL_CurvedContentView.swift index bbb7328093..275a85f562 100644 --- a/src/video/uikit/SDL_CurvedContentView.swift +++ b/src/video/uikit/SDL_CurvedContentView.swift @@ -167,7 +167,7 @@ internal struct SDL_CurvedContentView: View { .overlay { if mouseInputEnabled { // This enables mouse motion events, but blocks hover location - Color.white + Color.black .opacity(0.001) .pointerStyle(.shape(Circle(), size: .zero)) } From 0e480bee307430f641d554c3a716f20748518974 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 May 2026 16:13:41 -0700 Subject: [PATCH 369/407] visionOS: re-enable dimming mode --- .../uikit/SDL_CurvedContentHosting.swift | 48 ++++++++++--------- src/video/uikit/SDL_CurvedContentView.swift | 13 ++++- src/video/uikit/SDL_UIKitBridge-objc.h | 5 ++ src/video/uikit/SDL_UIKitBridge.m | 22 +++++++++ src/video/uikit/SDL_uikitwindow.m | 4 ++ 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/video/uikit/SDL_CurvedContentHosting.swift b/src/video/uikit/SDL_CurvedContentHosting.swift index 3648c391e8..88d95499ed 100644 --- a/src/video/uikit/SDL_CurvedContentHosting.swift +++ b/src/video/uikit/SDL_CurvedContentHosting.swift @@ -151,6 +151,16 @@ internal class SDL_CurvedContentHosting: NSObject { //NSLog("SDL_CurvedContentHosting: Bootstrapping RealityView as hidden child") } + @objc public func dismiss() { + guard let hc = self.hostingController else { return } + + settings.dimmingReady = false + + hc.dismiss(animated: false) + + hostingController = nil + } + private func updateOrnaments() { guard let hostingController else { return } let settings = self.settings @@ -263,8 +273,8 @@ internal class SDL_CurvedContentSettings { var inputType: InputType = .eyes var showHover: Bool = true - var enableDimming: Bool = false // Doesn't seem to be reliable at the moment var isDimmed: Bool = false + var dimmingReady: Bool = false var curvatureRadius: Float = 0.0 var sceneState: SceneState = .interactive var isSnapped: Bool = false @@ -320,10 +330,8 @@ struct SDL_SettingsPanelView: View { HStack(spacing: 12) { Image(systemName: settings.showHover ? "eye" : "eye.slash") - if settings.enableDimming { - Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") - .foregroundStyle(settings.isDimmed ? .primary : .secondary) - } + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) Divider().frame(height: 8) @@ -344,10 +352,8 @@ struct SDL_SettingsPanelView: View { VStack(spacing: 12) { Image(systemName: settings.showHover ? "eye" : "eye.slash") - if settings.enableDimming { - Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") - .foregroundStyle(settings.isDimmed ? .primary : .secondary) - } + Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max") + .foregroundStyle(settings.isDimmed ? .primary : .secondary) Divider().frame(height: 8) @@ -394,21 +400,19 @@ struct SDL_SettingsPanelView: View { Image(systemName: "eye") Spacer() - if settings.enableDimming { - Spacer() - Image(systemName: "sun.max") + Spacer() + Image(systemName: "sun.max") - Toggle(isOn: $settings.isDimmed) { - } - .onChange(of: settings.isDimmed) { - settings.save() - } - .labelsHidden() - .tint(.secondary) - - Image(systemName: "moon.fill") - Spacer() + Toggle(isOn: $settings.isDimmed) { } + .onChange(of: settings.isDimmed) { + settings.save() + } + .labelsHidden() + .tint(.secondary) + + Image(systemName: "moon.fill") + Spacer() } // Curvature slider diff --git a/src/video/uikit/SDL_CurvedContentView.swift b/src/video/uikit/SDL_CurvedContentView.swift index 275a85f562..d7c0abdac6 100644 --- a/src/video/uikit/SDL_CurvedContentView.swift +++ b/src/video/uikit/SDL_CurvedContentView.swift @@ -71,6 +71,10 @@ internal struct SDL_CurvedContentView: View { return curvedUIEntity != nil && helper.collisionShape != nil && !mouseInputEnabled } + private var shouldEnableDimming: Bool { + return settings.isDimmed && settings.dimmingReady + } + /// Value use to animate the screen radius @State private var animatedScreenRadius: Float = 1010 @@ -265,6 +269,13 @@ internal struct SDL_CurvedContentView: View { guard let curvedUIEntity else { return } if let shape = helper.collisionShape, shouldPopulateCollisionShape { curvedUIEntity.components.set(CollisionComponent(shapes: [shape])) + + // Dimming is possible now that we have a collision component + Task { + try await Task.sleep(nanoseconds: 1_000_000_000 / 4) + + settings.dimmingReady = true + } } else { curvedUIEntity.components.set(CollisionComponent(shapes: [])) } @@ -273,7 +284,7 @@ internal struct SDL_CurvedContentView: View { settings.isSnapped = snappedStatus.isSnapped helper.updateSnappedStatus(snapped: snappedStatus.isSnapped) } - .preferredSurroundingsEffect(settings.enableDimming && settings.isDimmed ? .dark : nil) + .preferredSurroundingsEffect(shouldEnableDimming ? .dark : nil) .frame(depth: 0) .ignoresSafeArea() .persistentSystemOverlays(settings.sceneState == .cinematic ? .hidden : .automatic) diff --git a/src/video/uikit/SDL_UIKitBridge-objc.h b/src/video/uikit/SDL_UIKitBridge-objc.h index db80a8cb5d..676e19a6bc 100644 --- a/src/video/uikit/SDL_UIKitBridge-objc.h +++ b/src/video/uikit/SDL_UIKitBridge-objc.h @@ -42,6 +42,11 @@ bool SDL_UIKit_HasCurvedWindow(); */ bool SDL_UIKit_IsCurvedWindow(SDL_Window *window); +/** + * Dismiss the curved content view + */ +void SDL_UIKit_HideCurvedWindow(SDL_Window *window); + /** * Get the curved content display texture. */ diff --git a/src/video/uikit/SDL_UIKitBridge.m b/src/video/uikit/SDL_UIKitBridge.m index e869d4b22c..a7f30aa30c 100644 --- a/src/video/uikit/SDL_UIKitBridge.m +++ b/src/video/uikit/SDL_UIKitBridge.m @@ -152,6 +152,28 @@ bool SDL_UIKit_IsCurvedWindow(SDL_Window *window) return data && data.curvedContentHosting; } +void SDL_UIKit_HideCurvedWindow(SDL_Window *window) +{ + SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; + if (!data || !data.curvedContentHosting) { + return nil; + } + + id hosting = data.curvedContentHosting; + SEL dismissSelector = NSSelectorFromString(@"dismiss"); + if (![hosting respondsToSelector:dismissSelector]) { + return nil; + } + + NSMethodSignature *signature = [hosting methodSignatureForSelector:dismissSelector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setSelector:dismissSelector]; + [invocation setTarget:hosting]; + [invocation invoke]; + + data.curvedContentHosting = nil; +} + id SDL_UIKit_GetCurvedDisplayTexture(SDL_Window *window, id commandBuffer, int width, int height, MTLPixelFormat pixelFormat) { SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 5523d6c55f..43076e8a40 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -33,6 +33,7 @@ #include "SDL_uikitappdelegate.h" #include "SDL_uikitview.h" #include "SDL_uikitopenglview.h" +#include "SDL_UIKitBridge-objc.h" #include @@ -386,6 +387,9 @@ void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) [data.viewcontroller stopAnimation]; +#ifdef SDL_PLATFORM_VISIONOS + SDL_UIKit_HideCurvedWindow(window); +#endif /* Detach all views from this window. We use a copy of the array * because setSDLWindow will remove the object from the original * array, which would be undesirable if we were iterating over it. */ From 48fe7b7d6a9275a1cd7d785c9a9d600445c571f4 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 19 May 2026 11:21:04 +0300 Subject: [PATCH 370/407] SDL_wasapi.c: added comment about SDL_AudioClientProperties workaround --- src/audio/wasapi/SDL_wasapi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index bdbbf81772..54957f4990 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -65,6 +65,9 @@ static bool immdevice_initialized = false; static bool supports_recording_on_playback_devices = false; #ifdef __IAudioClient2_INTERFACE_DEFINED__ +// AUDCLNT_STREAMOPTIONS and AudioClientProperties->Options were +// added in Windows 8.1: This ugliness is here to make sure that +// we can build against older SDK versions. #define SDL_AUDCLNT_STREAMOPTIONS_RAW 0x1 typedef union SDL_AudioClientProperties { AudioClientProperties a; From 6ed1de089c35ab283924c2fec96794909fc0df85 Mon Sep 17 00:00:00 2001 From: Kuratius Date: Tue, 19 May 2026 15:34:02 +0200 Subject: [PATCH 371/407] Fix touchpad finger detection on Steam Deck --- src/joystick/hidapi/SDL_hidapi_steamdeck.c | 45 +++++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/src/joystick/hidapi/SDL_hidapi_steamdeck.c index 286b7c97ea..d847abb946 100644 --- a/src/joystick/hidapi/SDL_hidapi_steamdeck.c +++ b/src/joystick/hidapi/SDL_hidapi_steamdeck.c @@ -65,6 +65,8 @@ typedef enum STEAMDECK_LBUTTON_R5 = 0x00010000, STEAMDECK_LBUTTON_LEFT_PAD = 0x00020000, STEAMDECK_LBUTTON_RIGHT_PAD = 0x00040000, + STEAMDECK_LBUTTON_LEFT_TOUCHPAD_TOUCH = 0x00080000, + STEAMDECK_LBUTTON_RIGHT_TOUCHPAD_TOUCH = 0x00100000, STEAMDECK_LBUTTON_L3 = 0x00400000, STEAMDECK_LBUTTON_R3 = 0x04000000, @@ -81,6 +83,13 @@ typedef struct Uint64 sensor_timestamp_ns; Uint64 last_button_state; Uint8 watchdog_counter; + + bool left_touch_down; + float left_touch_x; + float left_touch_y; + bool right_touch_down; + float right_touch_x; + float right_touch_y; } SDL_DriverSteamDeck_Context; static bool DisableDeckLizardMode(SDL_hid_device *dev) @@ -248,17 +257,33 @@ static void HIDAPI_DriverSteamDeck_HandleState(SDL_HIDAPI_Device *device, values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3); - SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, - pInReport->payload.deckState.sPressurePadLeft > 0, - pInReport->payload.deckState.sLeftPadX / 65536.0f + 0.5f, - pInReport->payload.deckState.sLeftPadY / 65536.0f + 0.5f, - pInReport->payload.deckState.sPressurePadLeft / 32768.0f); + bool left_touch_down = (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_LEFT_TOUCHPAD_TOUCH) ? true : false; + bool right_touch_down = (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_RIGHT_TOUCHPAD_TOUCH) ? true : false; + if (left_touch_down || ctx->left_touch_down) { + if (left_touch_down) { + ctx->left_touch_x = pInReport->payload.deckState.sLeftPadX / 65536.0f + 0.5f; + ctx->left_touch_y = -(float)pInReport->payload.deckState.sLeftPadY / 65536.0f + 0.5f; - SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, - pInReport->payload.deckState.sPressurePadRight > 0, - pInReport->payload.deckState.sRightPadX / 65536.0f + 0.5f, - pInReport->payload.deckState.sRightPadY / 65536.0f + 0.5f, - pInReport->payload.deckState.sPressurePadRight / 32768.0f); + } + SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, + left_touch_down, + ctx->left_touch_x, + ctx->left_touch_y, + pInReport->payload.deckState.sPressurePadLeft / 32768.0f); + ctx->left_touch_down = left_touch_down; + } + if (right_touch_down || ctx->right_touch_down) { + if (right_touch_down) { + ctx->right_touch_x = pInReport->payload.deckState.sRightPadX / 65536.0f + 0.5f; + ctx->right_touch_y = -(float)pInReport->payload.deckState.sRightPadY / 65536.0f + 0.5f; + } + SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, + right_touch_down, + ctx->right_touch_x, + ctx->right_touch_y, + pInReport->payload.deckState.sPressurePadRight / 32768.0f); + ctx->right_touch_down = right_touch_down; + } } /*****************************************************************************************************/ From 169480a352463eee65e825b1a934d7bebeb7967a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 19 May 2026 17:22:50 +0300 Subject: [PATCH 372/407] hidapi/netbsd: import mainstream commit 7e994d8671: https://github.com/libusb/hidapi/commit/7e994d8671 - authored by Izumi Tsutsui: netbsd: check not only addr 0 but also addr 1 to find root hubs On NetBSD xhci(4) uses 'addr 0' for the root hub but all drivers for other host controllers use 'addr 1' for the root hub. https://gnats.netbsd.org/60073 --- src/hidapi/netbsd/hid.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/hidapi/netbsd/hid.c b/src/hidapi/netbsd/hid.c index d88630db87..5f5858504d 100644 --- a/src/hidapi/netbsd/hid.c +++ b/src/hidapi/netbsd/hid.c @@ -711,6 +711,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor for (size_t i = 0; i < len; i++) { char devpath[USB_MAX_DEVNAMELEN]; int bus; + struct hid_device_info *prev_end; strlcpy(devpath, "/dev/", sizeof(devpath)); strlcat(devpath, arr[i], sizeof(devpath)); @@ -719,7 +720,17 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor if (bus == -1) continue; + /* + * ehci/ohci/uhci/dwctwo etc. use 'addr 1' for root hubs + * but xhci uses 'addr 0' on NetBSD. + * Check addr 0 (that would be unused on other than xhci) + * and then check addr 1 if there is no device at addr 0. + */ + prev_end = hed.end; enumerate_usb_devices(bus, 0, hid_enumerate_callback, &hed); + if (hed.end == prev_end) + enumerate_usb_devices(bus, 1, + hid_enumerate_callback, &hed); close(bus); } From 42c4a0e30f04150f0b5223340a7e50b8095ce72b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 19 May 2026 17:25:56 +0300 Subject: [PATCH 373/407] SDL_windows_gaming_input.c: work-around to build against old SDKs. Fixes https://github.com/libsdl-org/SDL/issues/15646 --- src/joystick/windows/SDL_windows_gaming_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index e08f568d91..2201115257 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -62,7 +62,7 @@ typedef struct WindowsGamingInputControllerState int steam_virtual_gamepad_slot; } WindowsGamingInputControllerState; -typedef HRESULT(WINAPI *CoIncrementMTAUsage_t)(CO_MTA_USAGE_COOKIE *pCookie); +typedef HRESULT(WINAPI *CoIncrementMTAUsage_t)(HANDLE* pCookie); // CO_MTA_USAGE_COOKIE* typedef HRESULT(WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void **factory); typedef HRESULT(WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING *string); typedef HRESULT(WINAPI *WindowsDeleteString_t)(HSTRING string); @@ -611,7 +611,7 @@ static bool WGI_JoystickInit(void) * As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later. * See https://github.com/libsdl-org/SDL/issues/5552 for more details. */ - static CO_MTA_USAGE_COOKIE cookie = NULL; + static HANDLE cookie = NULL; // CO_MTA_USAGE_COOKIE* if (!cookie) { hr = wgi.CoIncrementMTAUsage(&cookie); if (FAILED(hr)) { From f19dca3ca0c10f6417ac503288120ccd064cd4f4 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 19 May 2026 18:55:20 +0300 Subject: [PATCH 374/407] SDL_rawinputjoystick.c: fixed a type redefinition error --- src/joystick/windows/SDL_rawinputjoystick.c | 4 ++-- src/joystick/windows/SDL_windows_gaming_input.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 8c660c3d23..4066a7f8d9 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -57,7 +57,7 @@ #ifdef SDL_JOYSTICK_RAWINPUT_WGI #include "../../core/windows/SDL_windows.h" -typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; +struct WindowsGamingInputGamepadState; #define GamepadButtons_GUIDE 0x40000000 #define COBJMACROS #include "windows.gaming.input.h" @@ -158,7 +158,7 @@ struct joystick_hwdata Uint8 wgi_correlation_id; Uint8 wgi_correlation_count; Uint8 wgi_uncorrelate_count; - WindowsGamingInputGamepadState *wgi_slot; + struct WindowsGamingInputGamepadState *wgi_slot; struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration; #endif diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 2201115257..63810f08eb 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -611,7 +611,7 @@ static bool WGI_JoystickInit(void) * As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later. * See https://github.com/libsdl-org/SDL/issues/5552 for more details. */ - static HANDLE cookie = NULL; // CO_MTA_USAGE_COOKIE* + static HANDLE cookie = NULL; // CO_MTA_USAGE_COOKIE if (!cookie) { hr = wgi.CoIncrementMTAUsage(&cookie); if (FAILED(hr)) { From cfed9b3aca79e083c481df2afefefb25819f6b3b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 19 May 2026 14:21:55 -0700 Subject: [PATCH 375/407] Allow setting NULL palette on any surface Fixes https://github.com/libsdl-org/SDL/issues/15654 --- src/video/SDL_surface.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index ddd02fa657..d38d9a48ce 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -423,10 +423,14 @@ SDL_Palette *SDL_CreateSurfacePalette(SDL_Surface *surface) bool SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette) { - CHECK_PARAM(!SDL_SurfaceValid(surface) || !SDL_ISPIXELFORMAT_INDEXED(surface->format)) { + CHECK_PARAM(!SDL_SurfaceValid(surface)) { return SDL_InvalidParamError("surface"); } + CHECK_PARAM(palette && !SDL_ISPIXELFORMAT_INDEXED(surface->format)) { + return SDL_SetError("Surface doesn't use a palette"); + } + CHECK_PARAM(palette && palette->ncolors > (1 << SDL_BITSPERPIXEL(surface->format))) { return SDL_SetError("Palette doesn't match surface format"); } From f9380e15de1c57295e88757af16b5f74cdb1d46b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 19 May 2026 15:41:04 -0700 Subject: [PATCH 376/407] visionOS: fixed mousewheel values Here are the observed values using a Bluetooth mouse on visionOS 26.5 Slow scroll up: Mouse scroll: 0,-0.017334 Mouse scroll: 0,0 Mouse scroll: 0,-0.017334 Mouse scroll: 0,0 Slow scroll down: Mouse scroll: 0,0.017334 Mouse scroll: 0,0 Mouse scroll: 0,0.017334 Mouse scroll: 0,0 Fast scroll up: Mouse scroll: 0,-0.017334 Mouse scroll: 0,-9.36021 Mouse scroll: 0,-100.08 Mouse scroll: 0,-75.2287 Mouse scroll: 0,-82.2284 Mouse scroll: 0,-92.0137 Mouse scroll: 0,-95.1917 Mouse scroll: 0,-101.846 Mouse scroll: 0,-203.266 Mouse scroll: 0,0 Fast scroll down: Mouse scroll: 0,0.017334 Mouse scroll: 0,11.424 Mouse scroll: 0,59.3571 Mouse scroll: 0,68.7859 Mouse scroll: 0,267.834 Mouse scroll: 0,95.0823 Mouse scroll: 0,201.809 Mouse scroll: 0,0 --- src/video/uikit/SDL_uikitevents.m | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index a2722f0c01..3b94db3152 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -359,15 +359,18 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { Uint64 timestamp = SDL_GetTicksNS(); +#ifdef SDL_PLATFORM_VISIONOS + /* Mouse scroll values on visionOS have swapped axes compared to other platforms. + * There is also an acceleration ramp applied, so clamp to a single tick per event. + */ + float vertical = yValue < 0 ? -1 : yValue > 0 ? 1 : 0; + float horizontal = xValue < 0 ? -1 : xValue > 0 ? 1 : 0; +#else /* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis. * The vertical values are negative moving the mouse wheel up and positive moving it down. * The horizontal values are negative moving the mouse wheel left and positive moving it right. * The vertical values are inverted compared to SDL, and the horizontal values are as expected. */ -#ifdef SDL_PLATFORM_VISIONOS - float vertical = -yValue; - float horizontal = xValue; -#else float vertical = -xValue; float horizontal = yValue; #endif From c9e2e732b674679f4bc5caa0e36c192411cb6fc8 Mon Sep 17 00:00:00 2001 From: Ahmed Lyas Date: Wed, 20 May 2026 04:05:23 +0000 Subject: [PATCH 377/407] examples: Add blending example (#15657) --- .../renderer/20-blending/20-blending.vcxproj | 12 + examples/CMakeLists.txt | 1 + examples/renderer/20-blending/README.txt | 5 + examples/renderer/20-blending/blending.c | 234 ++++++++++++++++++ .../renderer/20-blending/onmouseover.webp | Bin 0 -> 150910 bytes examples/renderer/20-blending/thumbnail.png | Bin 0 -> 11663 bytes 6 files changed, 252 insertions(+) create mode 100644 VisualC/examples/renderer/20-blending/20-blending.vcxproj create mode 100644 examples/renderer/20-blending/README.txt create mode 100644 examples/renderer/20-blending/blending.c create mode 100644 examples/renderer/20-blending/onmouseover.webp create mode 100644 examples/renderer/20-blending/thumbnail.png diff --git a/VisualC/examples/renderer/20-blending/20-blending.vcxproj b/VisualC/examples/renderer/20-blending/20-blending.vcxproj new file mode 100644 index 0000000000..ff89bd3e0d --- /dev/null +++ b/VisualC/examples/renderer/20-blending/20-blending.vcxproj @@ -0,0 +1,12 @@ + + + + {B938A3C0-6C64-4734-B705-ED3642C01B47} + + + + + + + + \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ca88933009..752eb640e3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -142,6 +142,7 @@ add_sdl_example_executable(renderer-cliprect SOURCES renderer/15-cliprect/clipre add_sdl_example_executable(renderer-read-pixels SOURCES renderer/17-read-pixels/read-pixels.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.png) add_sdl_example_executable(renderer-debug-text SOURCES renderer/18-debug-text/debug-text.c) add_sdl_example_executable(renderer-affine-textures SOURCES renderer/19-affine-textures/affine-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.png) +add_sdl_example_executable(renderer-blending SOURCES renderer/20-blending/blending.c) add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c) add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c) add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav) diff --git a/examples/renderer/20-blending/README.txt b/examples/renderer/20-blending/README.txt new file mode 100644 index 0000000000..fb7ae5333b --- /dev/null +++ b/examples/renderer/20-blending/README.txt @@ -0,0 +1,5 @@ +This example uses SDL_SetTextureBlendMode() to apply blending to textures, +and SDL_ComposeCustomBlendMode() to create a custom blend mode. + +You can also use SDL_SetRenderDrawBlendMode() to apply blending to the +entire renderer, but it only affects filled rects and lines, not texture diff --git a/examples/renderer/20-blending/blending.c b/examples/renderer/20-blending/blending.c new file mode 100644 index 0000000000..53701fb969 --- /dev/null +++ b/examples/renderer/20-blending/blending.c @@ -0,0 +1,234 @@ +/* + * Blending combines a source color 'src', + * with the pixels already on the screen 'dst', + * to produce transparency and other visual effects. + * + * formula: dst := (a * dst) op (b * src) + * + * where: + * dst: existed pixel on the screen. + * src: new pixel. + * a: dst factor. + * b: src factor. + * op: blend operation (usually addition). + * + * In graphics programming, color and alpha are usually blended separately: + * dstRGB := (a * srcRGB) op (b * dstRGB) + * dstA := (c * srcA) op (d * dstA) + * + * This example uses SDL_SetTextureBlendMode() to apply blending to textures, + * and uses SDL_ComposeCustomBlendMode() to create a custom blend mode. + * + * You can also use SDL_SetRenderDrawBlendMode() to apply blending to the + * entire renderer, but it only affects filled rects and lines, not textures. + * + * This code is public domain. Feel free to use it for any purpose! + */ + + +#define SDL_MAIN_USE_CALLBACKS 1 +#include +#include + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* UI Constants */ +#define ROWS 2 +#define COLS 3 +#define GRID_SIZE ((WINDOW_WIDTH - 1) / 18.0f) +#define PANEL_SIZE (GRID_SIZE * 4) +#define ROW_OFFSET ((WINDOW_HEIGHT - ROWS * PANEL_SIZE) / 4) +#define COL_OFFSET (GRID_SIZE * COLS) +#define RECT_SIZE 50.0f +#define RED_OFFSET (GRID_SIZE) +#define GREEN_OFFSET (RECT_SIZE / 3 + GRID_SIZE) +#define BLUE_OFFSET (RECT_SIZE * 2 / 3 + GRID_SIZE) + +static SDL_FRect panels[ROWS*COLS]; +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *red_rect_texture = NULL; +static SDL_Texture *green_rect_texture = NULL; +static SDL_Texture *blue_rect_texture = NULL; +static Uint8 alpha = 255; +static SDL_BlendMode blend_modes[] = { + /*The default no blending: dstRGB := srcRGB + dstA := srcA */ + SDL_BLENDMODE_NONE, + + /* Alpha blending: dstRGB := srcA * srcRGB + (1 - srcA) * dstRGB + dstA := srcA + (1 - srcA) * dstA */ + SDL_BLENDMODE_BLEND, + + /* Additive blending: dstRGB := srcRGB + dstRGB + dstA := srcA + dstA */ + SDL_BLENDMODE_ADD, + + /* Modulate blending: dstRGB := srcRGB * dstRGB + dstA := dstA */ + SDL_BLENDMODE_MOD, + + /* Multiply blending: dstRGB := srcRGB * dstRGB + (1 - srcA) * dstRGB + dstA := dstA */ + SDL_BLENDMODE_MUL, + + /* Our custom blending 'Screen Blending': dstRGB := 1 - (1 - dstRGB) * (1 - srcRGB) + dstA := dstA */ + 0 +}; +static const char *blend_mode_names[] = { "NONE", "BLEND", "ADD", "MOD", "MUL", "SCREEN \"CUSTOM\"" }; + +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + + SDL_SetAppMetadata("Example Blending", "1.0", "com.example.blending"); + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + if (!SDL_CreateWindowAndRenderer("examples/renderer/blending", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); + + int row = 0; + int col = 0; + for (row = 0; row < ROWS; row++) + { + for (col = 0; col < COLS; col++) + { + panels[col + row*COLS] = (SDL_FRect){ col*PANEL_SIZE + col*COL_OFFSET, row*PANEL_SIZE + (row+1)*ROW_OFFSET, PANEL_SIZE, PANEL_SIZE }; + } + } + + /* Create 'screen blend' mode */ + blend_modes[ROWS*COLS - 1] = SDL_ComposeCustomBlendMode( + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR, /* srcRGB factor := (1 - dstRGB) */ + SDL_BLENDFACTOR_ONE, /* dstRGB factor := 1 */ + SDL_BLENDOPERATION_ADD, /* RGB operation := + */ + SDL_BLENDFACTOR_ZERO, /* srcA factor := 0 */ + SDL_BLENDFACTOR_ONE, /* dstA factor := dstA */ + SDL_BLENDOPERATION_ADD /* A operation := + */ + ); + + surface = SDL_CreateSurface((int)RECT_SIZE, (int)RECT_SIZE, SDL_PIXELFORMAT_RGBA8888); + if (!surface) { + SDL_Log("Couldn't create surface: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_FillSurfaceRect(surface, NULL, 0xFF0000FF); /* Red */ + red_rect_texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!red_rect_texture) { + SDL_Log("Couldn't create texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_FillSurfaceRect(surface, NULL, 0x00FF00FF); /* Green */ + green_rect_texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!green_rect_texture) { + SDL_Log("Couldn't create texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_FillSurfaceRect(surface, NULL, 0x0000FFFF); /* Blue */ + blue_rect_texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!blue_rect_texture) { + SDL_Log("Couldn't create texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; + } + if (event->type == SDL_EVENT_KEY_DOWN) { + /* UP arrow increase alpha */ + if (event->key.key == SDLK_UP && alpha <= 255-8) alpha += 8; + /* DOWN arrow decrease alpha */ + if (event->key.key == SDLK_DOWN && alpha >= 8) alpha -= 8; + } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + + int i = 0; + float x; + float y; + /* Render checkerboard panels */ + for (i = 0; i < ROWS*COLS; i++) + { + /* Loop through the panel pixels */ + for (y = panels[i].y; y < PANEL_SIZE + panels[i].y; y += GRID_SIZE) + { + for (x = panels[i].x; x < PANEL_SIZE + panels[i].x; x += GRID_SIZE) + { + SDL_FRect grid = { x, y, GRID_SIZE, GRID_SIZE }; + bool dark = (int)(x/GRID_SIZE + y/GRID_SIZE) % 2; + + if (dark) SDL_SetRenderDrawColor(renderer, 70, 70, 70, 255); /* Darker color */ + else SDL_SetRenderDrawColor(renderer, 110, 110, 110, 255); /* Lighter color */ + + SDL_RenderFillRect(renderer, &grid); + } + } + + /* Label the blend mode */ + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); + SDL_RenderDebugText(renderer, panels[i].x, panels[i].y - 15, blend_mode_names[i]); + } + + /* Render panels */ + SDL_RenderRects(renderer, panels, ROWS*COLS); + + /* Render UI text */ + SDL_RenderDebugText(renderer, WINDOW_WIDTH - 176, WINDOW_HEIGHT - 20, "UP/DOWN: CHANGE ALPHA"); + SDL_RenderDebugTextFormat(renderer, 0, WINDOW_HEIGHT - 20, "ALPHA: %d", alpha); + + /* Update textures alpha mod */ + SDL_SetTextureAlphaMod(red_rect_texture, alpha); + SDL_SetTextureAlphaMod(green_rect_texture, alpha); + SDL_SetTextureAlphaMod(blue_rect_texture, alpha); + + /* Render panels */ + for (i = 0; i < ROWS*COLS; i++) { + /* Update rects destination */ + SDL_FRect red_dst = { panels[i].x + RED_OFFSET, panels[i].y + RED_OFFSET, RECT_SIZE, RECT_SIZE }; + SDL_FRect green_dst = { panels[i].x + GREEN_OFFSET, panels[i].y + GREEN_OFFSET, RECT_SIZE, RECT_SIZE }; + SDL_FRect blue_dst = { panels[i].x + BLUE_OFFSET, panels[i].y + BLUE_OFFSET, RECT_SIZE, RECT_SIZE }; + + /* Apply the current blend mode */ + SDL_SetTextureBlendMode(red_rect_texture, blend_modes[i]); + SDL_SetTextureBlendMode(green_rect_texture, blend_modes[i]); + SDL_SetTextureBlendMode(blue_rect_texture, blend_modes[i]); + + /* Render textures */ + SDL_RenderTexture(renderer, red_rect_texture, NULL, &red_dst); + SDL_RenderTexture(renderer, green_rect_texture, NULL, &green_dst); + SDL_RenderTexture(renderer, blue_rect_texture, NULL, &blue_dst); + } + + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(red_rect_texture); + SDL_DestroyTexture(green_rect_texture); + SDL_DestroyTexture(blue_rect_texture); +} diff --git a/examples/renderer/20-blending/onmouseover.webp b/examples/renderer/20-blending/onmouseover.webp new file mode 100644 index 0000000000000000000000000000000000000000..dc1e2d94df3d9cbc86d10cac92202a2352af462d GIT binary patch literal 150910 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�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 z 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 b!*&LRw%;a=evx!bIDsSIS(}v{@;Lur{_hjQ literal 0 HcmV?d00001 From 35098e927cd9c8b92d4eaea7d3f73958cc211f82 Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Wed, 6 May 2026 01:25:30 +0200 Subject: [PATCH 378/407] emscripten: don't dispatch user input to hidden windows --- src/video/emscripten/SDL_emscriptenevents.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c index 6326d6967e..d4bd854a9e 100644 --- a/src/video/emscripten/SDL_emscriptenevents.c +++ b/src/video/emscripten/SDL_emscriptenevents.c @@ -713,6 +713,15 @@ static void Emscripten_UpdateMouseFromEvent(SDL_WindowData *window_data, const E { SDL_assert(event->pointer_type == PTRTYPE_MOUSE); + // Hidden windows (e.g. a shared GL-context window) may share the DOM canvas with the + // visible window. Their pointer-event listeners would otherwise fire alongside the + // visible window's, fighting over `mouse->focus` and producing events tagged with the + // hidden window's ID -- causing downstream consumers that key by window ID to silently + // drop them. Hidden windows shouldn't take part in user-input dispatch. + if (window_data->window->flags & SDL_WINDOW_HIDDEN) { + return; + } + // rescale (in case canvas is being scaled) double client_w, client_h; emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); @@ -838,6 +847,11 @@ static void Emscripten_HandleMouseFocus(SDL_WindowData *window_data, const Emscr { SDL_assert(event->pointer_type == PTRTYPE_MOUSE); + // Hidden windows shouldn't ever become the mouse-focus target. + if (window_data->window->flags & SDL_WINDOW_HIDDEN) { + return; + } + const bool isPointerLocked = window_data->has_pointer_lock; if (!isPointerLocked) { From 8fe1d7faec7e910d9bb0f88ca6e95afd75e582d3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 20 May 2026 00:40:25 -0400 Subject: [PATCH 379/407] examples/save-rendering-to-bitmaps: Dump alpha channel. examples/renderer/20-blending triggered this: the renderer's framebuffer has an alpha channel, even if the window itself doesn't, so we ended up with some weird rendering in the onmouseover.webp when I rebuilt it. --- examples/save-rendering-to-bitmaps.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/save-rendering-to-bitmaps.h b/examples/save-rendering-to-bitmaps.h index bf3eab8df7..e75bf23806 100644 --- a/examples/save-rendering-to-bitmaps.h +++ b/examples/save-rendering-to-bitmaps.h @@ -32,6 +32,11 @@ static bool SAVERENDERING_SDL_RenderPresent(SDL_Renderer *renderer) if (!surface) { SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to read pixels for frame #%u! (%s)", framenum, SDL_GetError()); } else { + SDL_Surface *cvt = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBX32); + if (cvt) { + SDL_DestroySurface(surface); + surface = cvt; + } char fname[64]; SDL_snprintf(fname, sizeof (fname), "frame%05u.png", framenum); if (!SDL_SavePNG(surface, fname)) { From d8f42ee069920d3a964d226568733f3e437bb1c2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 20 May 2026 00:42:57 -0400 Subject: [PATCH 380/407] examples/renderer/20-blending: Make thumbnail/onmouseover match other examples. --- .../renderer/20-blending/onmouseover.webp | Bin 150910 -> 69856 bytes examples/renderer/20-blending/thumbnail.png | Bin 11663 -> 10007 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/renderer/20-blending/onmouseover.webp b/examples/renderer/20-blending/onmouseover.webp index dc1e2d94df3d9cbc86d10cac92202a2352af462d..6d44367b21888657c55952b8932ed2e9fbeb2e81 100644 GIT binary patch literal 69856 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%0AakWZ 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�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 z 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 literal 11663 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 b!*&LRw%;a=evx!bIDsSIS(}v{@;Lur{_hjQ From f8dab6ad51d3fc516be1a3f3e62971a237a6cc74 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 20 May 2026 12:51:41 -0400 Subject: [PATCH 381/407] README-migration: Note that render target support is not universally available. Fixes #15474. --- docs/README-migration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README-migration.md b/docs/README-migration.md index 7aeb4842b0..3fd243c8f2 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -1447,7 +1447,7 @@ The following functions have been removed: * SDL_GetTextureUserData() - use SDL_GetTextureProperties() instead * SDL_RenderGetIntegerScale() * SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE -* SDL_RenderTargetSupported() - render targets are always supported +* SDL_RenderTargetSupported() - render targets are usually supported; just create a texture with SDL_TEXTUREACCESS_TARGET and see if it fails. * SDL_SetTextureUserData() - use SDL_GetTextureProperties() instead The following enums have been renamed: @@ -1461,7 +1461,7 @@ The following symbols have been removed: * SDL_RENDERER_ACCELERATED - all renderers except `SDL_SOFTWARE_RENDERER` are accelerated * SDL_RENDERER_PRESENTVSYNC - replaced with SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER during renderer creation and SDL_PROP_RENDERER_VSYNC_NUMBER after renderer creation * SDL_RENDERER_SOFTWARE - you can check whether the name of the renderer is `SDL_SOFTWARE_RENDERER` -* SDL_RENDERER_TARGETTEXTURE - all renderers support target texture functionality +* SDL_RENDERER_TARGETTEXTURE - most renderers support target texture functionality; just create a texture with SDL_TEXTUREACCESS_TARGET and see if it fails. * SDL_ScaleModeBest - use SDL_SCALEMODE_LINEAR instead ## SDL_rwops.h From 9a56bc66b5a4c824550a58207ba498d8f7d7d43f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 20 May 2026 13:02:41 -0400 Subject: [PATCH 382/407] assert: fixed compiler warning with LLVM + x86_64-pc-windows-msvc target. Fixes #15578. --- include/SDL3/SDL_assert.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL3/SDL_assert.h b/include/SDL3/SDL_assert.h index fb6746235b..6c8a47d004 100644 --- a/include/SDL3/SDL_assert.h +++ b/include/SDL3/SDL_assert.h @@ -265,7 +265,7 @@ disable assertions. */ #define SDL_NULL_WHILE_LOOP_CONDITION (0) -#elif defined(_MSC_VER) /* Avoid /W4 warnings. */ +#elif defined(_MSC_VER) && !defined(__clang__) /* Avoid /W4 warnings. */ /* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking this condition isn't constant. And looks like an owl's face! */ #define SDL_NULL_WHILE_LOOP_CONDITION (0,0) From 8371c09aa7d7afeffbcb782d8252b7959033c5f5 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 20 May 2026 11:01:40 -0400 Subject: [PATCH 383/407] x11: Reject click-through button events based on serial XInput2 may send mouse buttons presses on both the master and slave devices, and the click-through button event should be ignored on both if required. --- src/video/x11/SDL_x11events.c | 12 +++++++----- src/video/x11/SDL_x11events.h | 2 +- src/video/x11/SDL_x11window.h | 1 + src/video/x11/SDL_x11xinput2.c | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 961c8b08e2..a500cba637 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1130,7 +1130,7 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_ } } -void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time) +void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time, unsigned long serial) { SDL_Window *window = windowdata->window; int xticks = 0, yticks = 0; @@ -1149,7 +1149,6 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S if (X11_IsWheelEvent(button, &xticks, &yticks)) { SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL); } else { - bool ignore_click = false; if (button > 7) { /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ... => subtract (8-SDL_BUTTON_X1) to get value SDL expects */ @@ -1164,11 +1163,14 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S if (windowdata->last_focus_event_time) { const int X11_FOCUS_CLICK_TIMEOUT = 10; if (SDL_GetTicks() < (windowdata->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) { - ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, false); + if (!SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, false)) { + // Ignore all press events with this serial. + windowdata->ignore_button_press_serial = serial; + } } windowdata->last_focus_event_time = 0; } - if (!ignore_click) { + if (serial != windowdata->ignore_button_press_serial) { SDL_SendMouseButton(timestamp, window, mouseID, button, true); } } @@ -1872,7 +1874,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) } X11_HandleButtonPress(_this, data, SDL_GLOBAL_MOUSE_ID, xevent->xbutton.button, - xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.time); + xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.time, xevent->xbutton.serial); } break; case ButtonRelease: diff --git a/src/video/x11/SDL_x11events.h b/src/video/x11/SDL_x11events.h index 8174f509cb..fbd0bace0a 100644 --- a/src/video/x11/SDL_x11events.h +++ b/src/video/x11/SDL_x11events.h @@ -31,7 +31,7 @@ extern void X11_ReconcileKeyboardState(SDL_VideoDevice *_this); extern void X11_GetBorderValues(SDL_WindowData *data); extern Uint64 X11_GetEventTimestamp(unsigned long time); extern void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent); -extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time); +extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time, unsigned long serial); extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time); extern SDL_WindowData *X11_FindWindow(SDL_VideoData *videodata, Window window); extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result); diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 1ba725b9bd..a9cc77c3b5 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -63,6 +63,7 @@ struct SDL_WindowData bool xinput2_keyboard_enabled; bool mouse_grabbed; Uint64 last_focus_event_time; + unsigned long ignore_button_press_serial; PendingFocusEnum pending_focus; Uint64 pending_focus_time; bool pending_move; diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 56ccee53e5..f2c188474d 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -646,7 +646,7 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) if (down) { X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button, - (float)xev->event_x, (float)xev->event_y, xev->time); + (float)xev->event_x, (float)xev->event_y, xev->time, xev->serial); } else { X11_HandleButtonRelease(_this, windowdata, (SDL_MouseID)xev->sourceid, button, xev->time); } From ef9a5b7040b36d9c6b8ab4572eb7b9d6d4190659 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 20 May 2026 11:33:46 -0400 Subject: [PATCH 384/407] x11: Ignore slave button presses when the window lacks keyboard focus XInput2 can send slave button presses before FocusIn events, which can confuse the click-through suppression logic. A window must have keyboard focus to grab the mouse anyway, so ignore slave presses when lacking keyboard focus. --- src/video/x11/SDL_x11xinput2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index f2c188474d..bd138d507a 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -626,8 +626,10 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) int x_ticks = 0, y_ticks = 0; if (xev->deviceid != videodata->xinput_master_pointer_device) { - // Ignore slave button events on non-focused windows, or focus can be incorrectly set while a grab is active. - if (SDL_GetMouseFocus() != windowdata->window) { + /* Ignore slave button events on non-focused windows, as they can arrive before FocusIn events, + * or result in focus being incorrectly set while a grab is active. + */ + if (SDL_GetMouseFocus() != windowdata->window || SDL_GetKeyboardFocus() != windowdata->window) { break; } From 0dbd9d2a65634cae4555b4d47771009b3c9fcae4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 20 May 2026 14:56:54 -0700 Subject: [PATCH 385/407] Fixed a rare crash on Raspberry Pi when creating a window --- src/video/wayland/SDL_waylanddatamanager.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c index 6b9d045caf..b88566fcac 100644 --- a/src/video/wayland/SDL_waylanddatamanager.c +++ b/src/video/wayland/SDL_waylanddatamanager.c @@ -470,6 +470,10 @@ void Wayland_data_offer_notify_from_mimes(SDL_WaylandDataOffer *offer, bool chec // Do a first pass to compute allocation size. SDL_MimeDataList *item = NULL; wl_list_for_each(item, &offer->mimes, link) { + if (!item->mime_type) { + continue; + } + // If origin metadata is found, queue a check and wait for confirmation that this offer isn't recursive. if (check_origin && SDL_strcmp(item->mime_type, SDL_DATA_ORIGIN_MIME) == 0) { Wayland_data_offer_check_source(offer, item->mime_type); @@ -493,6 +497,10 @@ void Wayland_data_offer_notify_from_mimes(SDL_WaylandDataOffer *offer, bool chec item = NULL; int i = 0; wl_list_for_each(item, &offer->mimes, link) { + if (!item->mime_type) { + continue; + } + new_mime_types[i] = strPtr; strPtr = stpcpy(strPtr, item->mime_type) + 1; i++; From 19d73016e8333cd890d16ac972c0c1a9f8c8072a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 20 May 2026 15:11:09 -0700 Subject: [PATCH 386/407] Fixed a rare crash on Raspberry Pi when creating a window --- src/video/wayland/SDL_waylanddatamanager.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c index b88566fcac..4501efaa1a 100644 --- a/src/video/wayland/SDL_waylanddatamanager.c +++ b/src/video/wayland/SDL_waylanddatamanager.c @@ -183,10 +183,14 @@ static SDL_MimeDataList *mime_data_list_find(struct wl_list *list, { SDL_MimeDataList *found = NULL; - SDL_MimeDataList *mime_list = NULL; - wl_list_for_each (mime_list, list, link) { - if (SDL_strcmp(mime_list->mime_type, mime_type) == 0) { - found = mime_list; + SDL_MimeDataList *item = NULL; + wl_list_for_each (item, list, link) { + if (!item->mime_type) { + continue; + } + + if (SDL_strcmp(item->mime_type, mime_type) == 0) { + found = item; break; } } From 47c8dcc968b29db7164e3ee5b5a8d8874ef7d26b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 20 May 2026 14:57:36 -0700 Subject: [PATCH 387/407] android: handle sensor registration synchronized in one place --- .../org/libsdl/app/SDLControllerManager.java | 16 +++------- .../java/org/libsdl/app/SDLSensorManager.java | 32 +++++++++++++++++++ .../main/java/org/libsdl/app/SDLSurface.java | 6 ++-- 3 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index bce15e9de2..a41467c61d 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -91,13 +91,7 @@ public class SDLControllerManager * This method is called by SDL using JNI. */ static void joystickSetSensorsEnabled(int device_id, boolean enabled) { - // Run this on the UI thread so we don't race with enableSensor() in SDLSurface.java - SDL.getContext().runOnUiThread(new Runnable() { - @Override - public void run() { - mJoystickHandler.setSensorsEnabled(device_id, enabled); - } - }); + mJoystickHandler.setSensorsEnabled(device_id, enabled); } /** @@ -558,17 +552,17 @@ class SDLJoystickHandler { } if (enabled) { if (joystick.accelerometerSensor != null) { - joystick.sensorManager.registerListener(joystick.sensorListener, joystick.accelerometerSensor, SensorManager.SENSOR_DELAY_GAME, null); + SDLSensorManager.registerListener(joystick.sensorManager, joystick.sensorListener, joystick.accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); } if (joystick.gyroscopeSensor != null) { - joystick.sensorManager.registerListener(joystick.sensorListener, joystick.gyroscopeSensor, SensorManager.SENSOR_DELAY_GAME, null); + SDLSensorManager.registerListener(joystick.sensorManager, joystick.sensorListener, joystick.gyroscopeSensor, SensorManager.SENSOR_DELAY_GAME); } } else { if (joystick.accelerometerSensor != null) { - joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.accelerometerSensor); + SDLSensorManager.unregisterListener(joystick.sensorManager, joystick.sensorListener, joystick.accelerometerSensor); } if (joystick.gyroscopeSensor != null) { - joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.gyroscopeSensor); + SDLSensorManager.unregisterListener(joystick.sensorManager, joystick.sensorListener, joystick.gyroscopeSensor); } } } diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java new file mode 100644 index 0000000000..586e3fab6e --- /dev/null +++ b/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java @@ -0,0 +1,32 @@ +package org.libsdl.app; + +import android.hardware.Sensor; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +// This class coordinates synchronized access to sensor manager registration +// +// This prevents a java.util.ConcurrentModificationException exception on +// Android 16, specifically on the Samsung Tab S9 Ultra. + +class SDLSensorManager +{ + static private SDLSensorManager mManager = new SDLSensorManager(); + + public static void registerListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) { + mManager.RegisterListener(manager, listener, sensor, samplingPeriodUs); + } + + public static void unregisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor) { + mManager.UnregisterListener(manager, listener, sensor); + } + + private synchronized void RegisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) { + manager.registerListener(listener, sensor, samplingPeriodUs, null); + } + + private synchronized void UnregisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor) { + manager.unregisterListener(listener, sensor); + } +} + diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java index dedc00b78a..196cf04ec2 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java @@ -328,11 +328,11 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, protected void enableSensor(int sensortype, boolean enabled) { // TODO: This uses getDefaultSensor - what if we have >1 accels? if (enabled) { - mSensorManager.registerListener(this, + SDLSensorManager.registerListener(mSensorManager, this, mSensorManager.getDefaultSensor(sensortype), - SensorManager.SENSOR_DELAY_GAME, null); + SensorManager.SENSOR_DELAY_GAME); } else { - mSensorManager.unregisterListener(this, + SDLSensorManager.unregisterListener(mSensorManager, this, mSensorManager.getDefaultSensor(sensortype)); } } From 516f4a0bd5d97b402a1b27682d2d5e6e5119e189 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 20 May 2026 17:32:01 -0700 Subject: [PATCH 388/407] Added notes about faster crc32() options --- src/stdlib/SDL_crc32.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/stdlib/SDL_crc32.c b/src/stdlib/SDL_crc32.c index 8bad67dd76..a92bf02526 100644 --- a/src/stdlib/SDL_crc32.c +++ b/src/stdlib/SDL_crc32.c @@ -29,6 +29,12 @@ /* NOTE: DO NOT CHANGE THIS ALGORITHM There is code that relies on this in the joystick code */ +/* If you're looking for a faster CRC32 implementation, + the crc32() in zlib is a convenient option. + + This is also Zlib licensed and extremely fast: + https://github.com/corsix/fast-crc32 +*/ static Uint32 crc32_for_byte(Uint32 r) { From 3545bad5899a843362164c038a216c2ad176a3ac Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 21 May 2026 06:50:21 -0700 Subject: [PATCH 389/407] Process repeated joystick key events on Android This prevents them from being interpreted as keyboard keys by the Java code, and if internally we are treating them as keyboard keys, they'll be repeated properly. Fixes https://github.com/libsdl-org/SDL/issues/15664 --- .../app/src/main/java/org/libsdl/app/SDLActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 151224daad..633fa48c61 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -1505,9 +1505,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and // SOURCE_JOYSTICK, while its key events arrive from the keyboard source // So, retrieve the device itself and check all of its sources - // - // Echo events (event.getRepeatCount() > 0) should be ignored - if (SDLControllerManager.isDeviceSDLJoystick(deviceId) && event.getRepeatCount() == 0) { + if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) { // Note that we process events with specific key codes here if (event.getAction() == KeyEvent.ACTION_DOWN) { if (SDLControllerManager.onNativePadDown(deviceId, keyCode, event.getScanCode())) { From 13f91a67fc1ea717b0604f674f0cd30768062a0d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 21 May 2026 09:56:15 -0700 Subject: [PATCH 390/407] Fixed Ipega controllers being ignored in keyboard mode (thanks @AntTheAlchemist!) --- src/joystick/SDL_gamepad.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 6dab310b80..5d65991646 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -206,7 +206,7 @@ static const struct SDL_GamepadBlacklistWords SDL_gamepad_blacklist_words[] = { {"Synaptics ", GAMEPAD_BLACKLIST_ANYWHERE}, // "Synaptics TM2768-001", "SynPS/2 Synaptics TouchPad" {"Trackpad", GAMEPAD_BLACKLIST_ANYWHERE}, {"Clickpad", GAMEPAD_BLACKLIST_ANYWHERE}, - // "PG-90215 Keyboard", "Usb Keyboard Usb Keyboard Consumer Control", "Framework Laptop 16 Keyboard Module - ISO System Control" + // "Usb Keyboard Usb Keyboard Consumer Control", "Framework Laptop 16 Keyboard Module - ISO System Control" {" Keyboard", GAMEPAD_BLACKLIST_ANYWHERE}, {" Laptop ", GAMEPAD_BLACKLIST_ANYWHERE}, // "Framework Laptop 16 Numpad Module System Control" {"Mouse ", GAMEPAD_BLACKLIST_BEGIN}, // "Mouse passthrough" @@ -3281,6 +3281,10 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version case GAMEPAD_BLACKLIST_ANYWHERE: if (SDL_strstr(name, blacklist_word->str) != NULL) { + if (SDL_startswith(name, "PG-") { + // Ipega gamepads have modes with keyboard keys in addition to gamepad controls + break; + } return true; } break; From fe1918a47fb8b13a76a96fd1f07e1f3ff941a4e1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 21 May 2026 10:05:20 -0700 Subject: [PATCH 391/407] Fixed build --- src/joystick/SDL_gamepad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 5d65991646..90924582f2 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -3281,7 +3281,7 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version case GAMEPAD_BLACKLIST_ANYWHERE: if (SDL_strstr(name, blacklist_word->str) != NULL) { - if (SDL_startswith(name, "PG-") { + if (SDL_startswith(name, "PG-")) { // Ipega gamepads have modes with keyboard keys in addition to gamepad controls break; } From 6b4ae6846017b4afcde8f91c7d1bd2e2512c0ff8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 21 May 2026 12:20:03 -0700 Subject: [PATCH 392/407] android: fixed a possible joystick-related deadlock on application termination --- src/video/android/SDL_androidevents.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/video/android/SDL_androidevents.c b/src/video/android/SDL_androidevents.c index 4bdd717e12..605591b990 100644 --- a/src/video/android/SDL_androidevents.c +++ b/src/video/android/SDL_androidevents.c @@ -178,6 +178,26 @@ static void Android_OnDestroy(void) static void Android_HandleLifecycleEvent(SDL_AndroidLifecycleEvent event) { + // Make sure we're holding the joystick lock before dispatching life cycle events + // This prevents deadlocks of this form: + // 1. SDL locks the event watch list to dispatch the lifecycle event + // 2. a joystick sensor event arrives, taking the joystick lock + // 3. the lifecycle event dispatch calls into the application event + // watcher, which closes joysticks, trying to take the joystick lock + // 4. SDL delivers the sensor event, trying lock the event watch list + // 5. BOOM, deadlock! + // + // There are a few solutions to this, most of which involve unlocking the + // event watch list while delivering events or unlocking the joystick lock + // while delivering joystick events, both of which reduce performance and + // are extremely risky, so we'll do this, which is the least risky option. + // + // If you end up needing to wait for another thread that handles joystick + // events in your life cycle handling, then you can simply unlock joysticks, + // wait for that thread to complete, and then re-lock joysticks. + + SDL_LockJoysticks(); + switch (event) { case SDL_ANDROID_LIFECYCLE_WAKE: // Nothing to do, just return @@ -197,6 +217,8 @@ static void Android_HandleLifecycleEvent(SDL_AndroidLifecycleEvent event) default: break; } + + SDL_UnlockJoysticks(); } static Sint64 GetLifecycleEventTimeout(bool paused, Sint64 timeoutNS) From 33c9f1a70a813654a02c922aa33c658d8f9bd422 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 21 May 2026 18:15:27 +0200 Subject: [PATCH 393/407] Fix -Wdeprecated-declarations warnings An alternative could be to define _CRT_SECURE_NO_WARNINGS --- CMakeLists.txt | 6 ++--- include/build_config/SDL_build_config.h.cmake | 5 ++++ src/stdlib/SDL_string.c | 25 +++++++++++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d38f667724..cca8398794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1139,8 +1139,8 @@ if(SDL_LIBC) _Exit exp expf fabs fabsf floor floorf fmod fmodf fopen64 fseeko fseeko64 getenv - _i64toa index itoa - log log10 log10f logf lround lroundf _ltoa + _i64toa _i64toa_s index itoa _itoa_s + log log10 log10f logf lround lroundf _ltoa _ltoa_s malloc memcmp memcpy memmove memset modf modff pow powf putenv rindex round roundf @@ -1154,7 +1154,7 @@ if(SDL_LIBC) ) if(WINDOWS OR CYGWIN) list(APPEND symbols_to_check - _copysign _fseeki64 _strrev _ui64toa _uitoa _ultoa _wcsdup + _copysign _fseeki64 _strrev _ui64toa _ui64toa_s _uitoa _ultoa _ultoa_s _wcsdup ) else() list(APPEND symbols_to_check diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 2e0cdc21b4..5a95fdf3e0 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -106,13 +106,18 @@ #cmakedefine HAVE_STRNSTR 1 #cmakedefine HAVE_STRTOK_R 1 #cmakedefine HAVE_ITOA 1 +#cmakedefine HAVE__ITOA_S 1 #cmakedefine HAVE__LTOA 1 +#cmakedefine HAVE__LTOA_S 1 #cmakedefine HAVE__UITOA 1 #cmakedefine HAVE__ULTOA 1 +#cmakedefine HAVE__ULTOA_S 1 #cmakedefine HAVE_STRTOL 1 #cmakedefine HAVE_STRTOUL 1 #cmakedefine HAVE__I64TOA 1 +#cmakedefine HAVE__I64TOA_S 1 #cmakedefine HAVE__UI64TOA 1 +#cmakedefine HAVE__UI64TOA_S 1 #cmakedefine HAVE_STRTOLL 1 #cmakedefine HAVE_STRTOULL 1 #cmakedefine HAVE_STRTOD 1 diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index f8813044ee..51839404d2 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1155,7 +1155,10 @@ static const char ntoa_table[] = { char *SDL_itoa(int value, char *string, int radix) { -#ifdef HAVE_ITOA +#ifdef HAVE__ITOA_S + (void)_ltoa_s(value, string, 12, radix); + return string; +#elif defined(HAVE_ITOA) return itoa(value, string, radix); #else return SDL_ltoa((long)value, string, radix); @@ -1173,7 +1176,10 @@ char *SDL_uitoa(unsigned int value, char *string, int radix) char *SDL_ltoa(long value, char *string, int radix) { -#ifdef HAVE__LTOA +#ifdef HAVE__LTOA_S + (void)_ltoa_s(value, string, 64, radix); + return string; +#elif defined(HAVE__LTOA) return _ltoa(value, string, radix); #else char *bufp = string; @@ -1191,7 +1197,10 @@ char *SDL_ltoa(long value, char *string, int radix) char *SDL_ultoa(unsigned long value, char *string, int radix) { -#ifdef HAVE__ULTOA +#ifdef HAVE__ULTOA_S + (void)_ultoa_s(value, string, 64, radix); + return string; +#elif defined(HAVE__ULTOA) return _ultoa(value, string, radix); #else char *bufp = string; @@ -1215,7 +1224,10 @@ char *SDL_ultoa(unsigned long value, char *string, int radix) char *SDL_lltoa(long long value, char *string, int radix) { -#ifdef HAVE__I64TOA +#ifdef HAVE__I64TOA_S + (void)_i64toa_s(value, string, 64, radix); + return string; +#elif defined(HAVE__I64TOA) return _i64toa(value, string, radix); #else char *bufp = string; @@ -1233,7 +1245,10 @@ char *SDL_lltoa(long long value, char *string, int radix) char *SDL_ulltoa(unsigned long long value, char *string, int radix) { -#ifdef HAVE__UI64TOA +#ifdef HAVE__UI64TOA_S + (void)_ui64toa_s(value, string, 64, radix); + return string; +#elif defined(HAVE__UI64TOA) return _ui64toa(value, string, radix); #else char *bufp = string; From 6243fa2ffd8de2cf310ec4851eb0d9faef83b2fa Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 21 May 2026 18:15:42 +0200 Subject: [PATCH 394/407] Fix -Wempty-body warnings in SDL_malloc.c ABORT is used in the assert macro. --- src/stdlib/SDL_malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index d30a8bbb13..cd48c61d9f 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -28,7 +28,7 @@ #define LACKS_STRINGS_H #define LACKS_STRING_H #define LACKS_STDLIB_H -#define ABORT +#define ABORT do {} while (0) #define NO_MALLOC_STATS 1 #define USE_LOCKS 1 #define USE_DL_PREFIX From 2bb6df90ad2761037fca39c6bba81b506381ab2f Mon Sep 17 00:00:00 2001 From: kholo Date: Fri, 22 May 2026 15:18:32 +0200 Subject: [PATCH 395/407] Ignore `Huion Tablet Kamvas Pro 22` --- src/joystick/SDL_joystick.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 1b8278fc12..79c5997e21 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -449,6 +449,7 @@ static Uint32 initial_blacklist_devices[] = { MAKE_VIDPID(0x1532, 0x0282), // Razer Huntsman Mini Analog, non-functional DInput device MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) MAKE_VIDPID(0x256c, 0x006d), // Huion Tablet_GS1331, Huion Tablet_GS1331 Touch Strip + MAKE_VIDPID(0x256c, 0x006e), // Huion Tablet Kamvas Pro 22, Huion Tablet Kamvas Pro 22 Touch Strip MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller MAKE_VIDPID(0x3297, 0x1969), // Moonlander MK1 Keyboard MAKE_VIDPID(0x3434, 0x0121), // Keychron Q3 System Control From 7f03da9588841e8d3da74e0dfeed50f95f2e4e6f Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Tue, 5 May 2026 01:54:29 +0200 Subject: [PATCH 396/407] emscripten: dedupe keyboard event listeners across multiple windows --- src/video/emscripten/SDL_emscriptenevents.c | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c index d4bd854a9e..dcdee7914c 100644 --- a/src/video/emscripten/SDL_emscriptenevents.c +++ b/src/video/emscripten/SDL_emscriptenevents.c @@ -1341,11 +1341,33 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data) keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element); if (keyElement) { + // Emscripten's HTML5 helpers do not deduplicate `addEventListener` calls: + // see `registerOrRemoveHandler` in `emscripten/src/lib/libhtml5.js`. + // + // If a previous SDL window already registered keyboard handlers on the same + // target, the new registration would *stack* a second listener, causing every + // browser keydown to fire `Emscripten_HandleKey` twice. + // + // The duplicate calls then produce two `SDL_EVENT_KEY_DOWN` events per physical + // keypress (the second one with `repeat=true`, due to the keystate-based repeat + // detection in `SDL_SendKeyboardKeyInternal`). + // + // We must clear any prior handler on this target before installing ours: + emscripten_set_keydown_callback(keyElement, NULL, 0, NULL); + emscripten_set_keyup_callback(keyElement, NULL, 0, NULL); + emscripten_set_keypress_callback(keyElement, NULL, 0, NULL); + MAIN_THREAD_EM_ASM_INT({ var data = $0; // our keymod state can get confused in various ways (changed capslock when browser didn't have focus, etc), and you can't query the current // state from the DOM, outside of a keyboard event, so catch keypresses globally and reset mod state if it's unexpectedly wrong. Best we can do. // Note that this thing _only_ adjusts the lock keys if necessary; the real SDL keypress handling happens elsewhere. + + // Remove any prior listener first -- `addEventListener` does not deduplicate either. + if (document.sdlEventHandlerLockKeysCheck) { + document.removeEventListener("keydown", document.sdlEventHandlerLockKeysCheck); + } + document.sdlEventHandlerLockKeysCheck = function(event) { // don't try to adjust the state on the actual lock key presses; the normal key handler will catch that and adjust. if ((event.key != "CapsLock") && (event.key != "NumLock") && (event.key != "ScrollLock")) From 2f13731d235ceed15c909838e0d0f6a4c5fd9a6f Mon Sep 17 00:00:00 2001 From: Bitwolf <65789901+Bitwolfies@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:30:58 -0700 Subject: [PATCH 397/407] Update Famicom controllers to a more user friendly name. --- src/joystick/hidapi/SDL_hidapi_switch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index c96c7842e2..cb60c93a07 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1458,11 +1458,11 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) device->type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO; break; case k_eSwitchDeviceInfoControllerType_HVCLeft: - HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (1)"); + HIDAPI_SetDeviceName(device, "Nintendo Family Computer Controller (1)"); device->type = SDL_GAMEPAD_TYPE_STANDARD; break; case k_eSwitchDeviceInfoControllerType_HVCRight: - HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (2)"); + HIDAPI_SetDeviceName(device, "Nintendo Family Computer Controller (2)"); device->type = SDL_GAMEPAD_TYPE_STANDARD; break; case k_eSwitchDeviceInfoControllerType_NESLeft: From 290f0c831fe47d0c91a377e4b843a7599358a892 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 27 Mar 2026 22:08:07 -0400 Subject: [PATCH 398/407] iOS: Fix SDL_EVENT_DROP_FILE lost on cold start from URL open --- src/video/uikit/SDL_uikitappdelegate.m | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index 4f40d93dcf..d4a8c07f87 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -352,6 +352,7 @@ API_AVAILABLE(ios(13.0)) @implementation SDLUIKitSceneDelegate { UIWindow *launchWindow; + NSMutableArray *launchURLs; } + (NSString *)getSceneDelegateClassName @@ -411,15 +412,16 @@ API_AVAILABLE(ios(13.0)) // Set working directory to resource path [[NSFileManager defaultManager] changeCurrentDirectoryPath:[bundle resourcePath]]; - // Handle any connection options (like opening URLs) + launchURLs = [[NSMutableArray alloc] init]; + for (NSUserActivity *activity in connectionOptions.userActivities) { if (activity.webpageURL) { - [self handleURL:activity.webpageURL]; + [launchURLs addObject:activity.webpageURL]; } } for (UIOpenURLContext *urlContext in connectionOptions.URLContexts) { - [self handleURL:urlContext.URL]; + [launchURLs addObject:urlContext.URL]; } SDL_SetMainReady(); @@ -488,6 +490,7 @@ API_AVAILABLE(ios(13.0)) - (void)postFinishLaunch { [self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0]; + [self performSelector:@selector(processLaunchURLs) withObject:nil afterDelay:0.0]; SDL_SetiOSEventPump(true); exit_status = SDL_CallMainFunction(forward_argc, forward_argv, forward_main); @@ -499,6 +502,14 @@ API_AVAILABLE(ios(13.0)) } } +- (void)processLaunchURLs +{ + for (NSURL *url in launchURLs) { + [self handleURL:url]; + } + launchURLs = nil; +} + - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0)) { // This doesn't appear to be called, but it needs to be implemented to signal that we support the UIScene life cycle From 39be8a703f809c50ff666e7499a27a832ccf4219 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 22 May 2026 10:34:35 -0400 Subject: [PATCH 399/407] examples/renderer/20-blending: center alpha and instructional text. Otherwise, it tends to get lost behind the "Source Code" tab in the web builds, if the browser window is too small. --- examples/renderer/20-blending/blending.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/renderer/20-blending/blending.c b/examples/renderer/20-blending/blending.c index 53701fb969..9cea912779 100644 --- a/examples/renderer/20-blending/blending.c +++ b/examples/renderer/20-blending/blending.c @@ -195,8 +195,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) SDL_RenderRects(renderer, panels, ROWS*COLS); /* Render UI text */ - SDL_RenderDebugText(renderer, WINDOW_WIDTH - 176, WINDOW_HEIGHT - 20, "UP/DOWN: CHANGE ALPHA"); - SDL_RenderDebugTextFormat(renderer, 0, WINDOW_HEIGHT - 20, "ALPHA: %d", alpha); + SDL_RenderDebugText(renderer, (WINDOW_WIDTH - 176) / 2, WINDOW_HEIGHT - 30, "UP/DOWN: CHANGE ALPHA"); + SDL_RenderDebugTextFormat(renderer, (WINDOW_WIDTH - 80) / 2, WINDOW_HEIGHT - 20, "ALPHA: %d", alpha); /* Update textures alpha mod */ SDL_SetTextureAlphaMod(red_rect_texture, alpha); From 9fe200c215b334dbc115a4033d751bc0049b42e1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 22 May 2026 10:35:41 -0400 Subject: [PATCH 400/407] examples/renderer/20-blending: Note when a blend mode is unsupported. --- examples/renderer/20-blending/blending.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/renderer/20-blending/blending.c b/examples/renderer/20-blending/blending.c index 9cea912779..9c68189282 100644 --- a/examples/renderer/20-blending/blending.c +++ b/examples/renderer/20-blending/blending.c @@ -211,14 +211,25 @@ SDL_AppResult SDL_AppIterate(void *appstate) SDL_FRect blue_dst = { panels[i].x + BLUE_OFFSET, panels[i].y + BLUE_OFFSET, RECT_SIZE, RECT_SIZE }; /* Apply the current blend mode */ - SDL_SetTextureBlendMode(red_rect_texture, blend_modes[i]); + const bool supported = SDL_SetTextureBlendMode(red_rect_texture, blend_modes[i]); /* just make sure the renderer supports this blend mode */ SDL_SetTextureBlendMode(green_rect_texture, blend_modes[i]); - SDL_SetTextureBlendMode(blue_rect_texture, blend_modes[i]); + SDL_SetTextureBlendMode(blue_rect_texture, blend_modes[i]); /* Render textures */ SDL_RenderTexture(renderer, red_rect_texture, NULL, &red_dst); SDL_RenderTexture(renderer, green_rect_texture, NULL, &green_dst); SDL_RenderTexture(renderer, blue_rect_texture, NULL, &blue_dst); + + /* Not all renderers support all blend modes. The renderer will try to pick something close in this case, + but it should be noted that the results might be unexpected, so we add "[UNSUPPORTED]" to this panel. */ + if (!supported) { + const float textwidth = 104.0f; + const SDL_FRect dst = { panels[i].x + ((panels[i].w - textwidth) / 2.0f), panels[i].y + (panels[i].h - 8), textwidth, 8 }; + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(renderer, &dst); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); + SDL_RenderDebugText(renderer, dst.x, dst.y, "[UNSUPPORTED]"); + } } SDL_RenderPresent(renderer); From 5f8eb445419c5e9c4388ac414722d7baee2a9655 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 22 May 2026 11:42:53 -0400 Subject: [PATCH 401/407] wayland: Handle captured pointer movements over a subsurface Some compositors will send pointer enter/leave event while moving between surfaces that are part of the same window while mouse capture is active. Maintain window focus in this case, and adjust the coordinates relative to the content surface by the subsurface offset, if necessary. --- src/video/wayland/SDL_waylandevents.c | 34 ++++++++++++++++++++----- src/video/wayland/SDL_waylandevents_c.h | 1 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index b38ef441db..e828dc9f69 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -685,8 +685,16 @@ static void pointer_dispatch_absolute_motion(SDL_WaylandSeat *seat) SDL_Window *window = window_data ? window_data->sdlwindow : NULL; if (window_data) { - const float sx = (float)(wl_fixed_to_double(seat->pointer.pending_frame.absolute.sx) * window_data->pointer_scale.x); - const float sy = (float)(wl_fixed_to_double(seat->pointer.pending_frame.absolute.sy) * window_data->pointer_scale.y); + double sx = wl_fixed_to_double(seat->pointer.pending_frame.absolute.sx); + double sy = wl_fixed_to_double(seat->pointer.pending_frame.absolute.sy); + + if (seat->pointer.focus_surface == window_data->mask.surface) { + sx += (double)window_data->mask.offset_x; + sy += (double)window_data->mask.offset_y; + } + + sx *= window_data->pointer_scale.x; + sy *= window_data->pointer_scale.y; SDL_SendMouseMotion(seat->pointer.pending_frame.timestamp_ns, window_data->sdlwindow, seat->pointer.sdl_id, false, sx, sy); seat->pointer.last_motion.x = (int)SDL_floorf(sx); @@ -816,6 +824,7 @@ static void pointer_dispatch_enter(SDL_WaylandSeat *seat) } seat->pointer.focus = window; + seat->pointer.focus_surface = seat->pointer.pending_frame.enter_surface; ++window->pointer_focus_count; SDL_SetMouseFocus(window->sdlwindow); @@ -874,6 +883,7 @@ static void pointer_dispatch_leave(SDL_WaylandSeat *seat, bool update_pointer) window->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; seat->pointer.focus = NULL; + seat->pointer.focus_surface = NULL; for (Uint8 i = 1; seat->pointer.buttons_pressed; ++i) { if (seat->pointer.buttons_pressed & SDL_BUTTON_MASK(i)) { SDL_SendMouseButton(0, window->sdlwindow, seat->pointer.sdl_id, i, false); @@ -1283,12 +1293,24 @@ static void pointer_handle_frame(void *data, struct wl_pointer *pointer) if (seat->pointer.pending_frame.enter_surface) { if (seat->pointer.pending_frame.leave_surface) { - // Leaving the previous surface before entering a new surface. - pointer_dispatch_leave(seat, false); - seat->pointer.pending_frame.leave_surface = NULL; + SDL_WindowData *window_data = seat->pointer.focus; + SDL_WindowData *new_focus = Wayland_GetWindowDataForOwnedSurface(seat->pointer.pending_frame.enter_surface); + + if (window_data && (window_data->sdlwindow->flags & SDL_WINDOW_MOUSE_CAPTURE) && window_data == new_focus) { + // The mouse is captured and moving between owned window surfaces. Just change the focused surface. + seat->pointer.focus_surface = seat->pointer.pending_frame.enter_surface; + seat->pointer.pending_frame.enter_surface = NULL; + seat->pointer.pending_frame.leave_surface = NULL; + } else { + // Leaving the previous surface before entering a new surface. + pointer_dispatch_leave(seat, false); + seat->pointer.pending_frame.leave_surface = NULL; + } } - pointer_dispatch_enter(seat); + if (seat->pointer.pending_frame.enter_surface) { + pointer_dispatch_enter(seat); + } } if (seat->pointer.pending_frame.have_absolute) { diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index 1a597a35f8..9e3d573b6c 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -189,6 +189,7 @@ typedef struct SDL_WaylandSeat struct zwp_pointer_gesture_pinch_v1 *gesture_pinch; SDL_WindowData *focus; + struct wl_surface *focus_surface; // According to the spec, a seat can only have one active gesture of any type at a time. SDL_WindowData *gesture_focus; From e7b238a6ed9d64bcc92f8ffc75fecc10f0153b73 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 22 May 2026 12:30:11 -0400 Subject: [PATCH 402/407] Fix casting errors --- src/video/wayland/SDL_waylandevents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index e828dc9f69..67f74fe5d1 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -695,10 +695,10 @@ static void pointer_dispatch_absolute_motion(SDL_WaylandSeat *seat) sx *= window_data->pointer_scale.x; sy *= window_data->pointer_scale.y; - SDL_SendMouseMotion(seat->pointer.pending_frame.timestamp_ns, window_data->sdlwindow, seat->pointer.sdl_id, false, sx, sy); + SDL_SendMouseMotion(seat->pointer.pending_frame.timestamp_ns, window_data->sdlwindow, seat->pointer.sdl_id, false, (float)sx, (float)sy); - seat->pointer.last_motion.x = (int)SDL_floorf(sx); - seat->pointer.last_motion.y = (int)SDL_floorf(sy); + seat->pointer.last_motion.x = (int)SDL_floor(sx); + seat->pointer.last_motion.y = (int)SDL_floor(sy); // If the pointer should be confined, but wasn't for some reason, keep trying until it is. if (!SDL_RectEmpty(&window->mouse_rect) && !seat->pointer.is_confined) { From 3626598675f499f0b24a369ebb52b23628d4898d Mon Sep 17 00:00:00 2001 From: 0xDEADCADE <69792955+0xDEADCADE@users.noreply.github.com> Date: Sat, 23 May 2026 14:01:42 +0200 Subject: [PATCH 403/407] Remove CenterPad and RightStick from Steam Controller (2015) internal state struct These values are never used for the Steam Controller (2015), as it does not physically have these inputs. --- src/joystick/hidapi/SDL_hidapi_steam.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index 624e8b5dd5..3a50d1fc89 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -75,18 +75,10 @@ typedef struct SteamControllerStateInternal_t short sRightPadX; short sRightPadY; - // Center pad coordinates - short sCenterPadX; - short sCenterPadY; - // Left analog stick coordinates short sLeftStickX; short sLeftStickY; - // Right analog stick coordinates - short sRightStickX; - short sRightStickY; - unsigned short sTriggerL; unsigned short sTriggerR; From 0a96d47599838c2aa36cc6dad9395acb33189539 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sat, 23 May 2026 12:20:30 -0400 Subject: [PATCH 404/407] wayland: Remove focus references when a pointer capture ends on a subsurface The core mouse code will unfocus the window when a capture ends outside the window boundaries, but the backend still needs to update the internal focus references. --- src/video/wayland/SDL_waylandevents.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 67f74fe5d1..82369b876b 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1048,6 +1048,11 @@ static void pointer_dispatch_button(SDL_WaylandSeat *seat, Uint8 sdl_button, boo window->sdlwindow->flags |= SDL_WINDOW_MOUSE_CAPTURE; } else { window->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + + // If ending the capture on a subsurface, dispatch a leave event to remove focus. + if (seat->pointer.focus_surface != window->surface) { + seat->pointer.pending_frame.leave_surface = window->surface; + } } } From ae07e32269d88cd20d9e7d00701d7b5a62da8955 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 23 May 2026 20:11:10 +0300 Subject: [PATCH 405/407] SDL_itoa(): use _itoa_s(), not _ltoa_s() typo introduced by commit 33c9f1a70a813654a02c922aa33c658d8f9bd422 --- src/stdlib/SDL_string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 51839404d2..b16b1c6792 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1156,7 +1156,7 @@ static const char ntoa_table[] = { char *SDL_itoa(int value, char *string, int radix) { #ifdef HAVE__ITOA_S - (void)_ltoa_s(value, string, 12, radix); + (void)_itoa_s(value, string, 12, radix); return string; #elif defined(HAVE_ITOA) return itoa(value, string, radix); From 800f347e5e33b5f11b73a9a5f0a2afd8ebaf030f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 23 May 2026 23:47:24 -0400 Subject: [PATCH 406/407] examples/demo/04-bytepusher: Remove render target. This doesn't need a render target to function. The comment suggested it was needed to make debug text look better when scaled, but maybe logical presentation used to do linear scaling exclusively at the time? --- examples/demo/04-bytepusher/bytepusher.c | 40 +++++++++++------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/examples/demo/04-bytepusher/bytepusher.c b/examples/demo/04-bytepusher/bytepusher.c index e5c4e5c382..6911956222 100644 --- a/examples/demo/04-bytepusher/bytepusher.c +++ b/examples/demo/04-bytepusher/bytepusher.c @@ -33,7 +33,6 @@ typedef struct { SDL_Renderer* renderer; SDL_Palette* palette; SDL_Texture* texture; - SDL_Texture* rendertarget; /* we need this render target for text to look good */ SDL_AudioStream* audiostream; char status[SCREEN_W / 8]; int status_ticks; @@ -199,13 +198,11 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { } vm->texture = SDL_CreateTexture(vm->renderer, SDL_PIXELFORMAT_INDEX8, SDL_TEXTUREACCESS_STREAMING, SCREEN_W, SCREEN_H); - vm->rendertarget = SDL_CreateTexture(vm->renderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_TARGET, SCREEN_W, SCREEN_H); - if (!vm->texture || !vm->rendertarget) { + if (!vm->texture) { return SDL_APP_FAILURE; } SDL_SetTexturePalette(vm->texture, vm->palette); SDL_SetTextureScaleMode(vm->texture, SDL_SCALEMODE_NEAREST); - SDL_SetTextureScaleMode(vm->rendertarget, SDL_SCALEMODE_NEAREST); if (!(vm->audiostream = SDL_OpenAudioDeviceStream( SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audiospec, NULL, NULL @@ -274,26 +271,26 @@ SDL_AppResult SDL_AppIterate(void* appstate) { if (updated) { const void *pixels = &vm->ram[(Uint32)vm->ram[IO_SCREEN_PAGE] << 16]; SDL_UpdateTexture(vm->texture, NULL, pixels, SCREEN_W); - - SDL_SetRenderTarget(vm->renderer, vm->rendertarget); - SDL_RenderTexture(vm->renderer, vm->texture, NULL, NULL); - - if (vm->display_help) { - print(vm, 4, 4, "Drop a BytePusher file in this"); - print(vm, 8, 12, "window to load and run it!"); - print(vm, 4, 28, "Press ENTER to switch between"); - print(vm, 8, 36, "positional and symbolic input."); - } - - if (vm->status_ticks > 0) { - vm->status_ticks -= 1; - print(vm, 4, SCREEN_H - 12, vm->status); - } } - SDL_SetRenderTarget(vm->renderer, NULL); SDL_RenderClear(vm->renderer); - SDL_RenderTexture(vm->renderer, vm->rendertarget, NULL, NULL); + + if (vm->display_help) { + print(vm, 4, 4, "Drop a BytePusher file in this"); + print(vm, 8, 12, "window to load and run it!"); + print(vm, 4, 28, "Press ENTER to switch between"); + print(vm, 8, 36, "positional and symbolic input."); + } else { + SDL_RenderTexture(vm->renderer, vm->texture, NULL, NULL); + } + + if (vm->status_ticks > 0) { + if (updated) { + vm->status_ticks--; + } + print(vm, 4, SCREEN_H - 12, vm->status); + } + SDL_RenderPresent(vm->renderer); return SDL_APP_CONTINUE; @@ -387,7 +384,6 @@ void SDL_AppQuit(void* appstate, SDL_AppResult result) { if (appstate) { BytePusher* vm = (BytePusher*)appstate; SDL_DestroyAudioStream(vm->audiostream); - SDL_DestroyTexture(vm->rendertarget); SDL_DestroyTexture(vm->texture); SDL_DestroyPalette(vm->palette); SDL_DestroyRenderer(vm->renderer); From 6c55fad411cbaa24ae4f488b4e349a21a3699b5c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 23 May 2026 23:56:48 -0400 Subject: [PATCH 407/407] examples/demo/04-bytepusher: go back to showing help text on load failures. If the VM was already running, and then a file failed to open at all (a directory was dropped on the window, etc), this wouldn't go back to showing the help text. --- examples/demo/04-bytepusher/bytepusher.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/demo/04-bytepusher/bytepusher.c b/examples/demo/04-bytepusher/bytepusher.c index 6911956222..25525735bf 100644 --- a/examples/demo/04-bytepusher/bytepusher.c +++ b/examples/demo/04-bytepusher/bytepusher.c @@ -74,6 +74,8 @@ static bool load(BytePusher* vm, SDL_IOStream* stream, bool closeio) { size_t bytes_read = 0; bool ok = true; + vm->display_help = true; // will set to false if load succeeds. + SDL_memset(vm->ram, 0, RAM_SIZE); if (!stream) {