GPU: OpenXR integration (#14837)
Build (All) / Create test plan (push) Has been cancelled
Build (All) / level1 (push) Has been cancelled
Build (All) / level2 (push) Has been cancelled

Based on Beyley's initial draft in #11601.

Co-authored-by: Beyley Cardellio <ep1cm1n10n123@gmail.com>
Co-authored-by: Ethan Lee <flibitijibibo@gmail.com>
This commit is contained in:
Aaron Benjamin
2026-01-30 17:18:51 -05:00
committed by GitHub
parent 8fa8c331a5
commit 9a91d7236a
36 changed files with 19723 additions and 102 deletions
+1
View File
@@ -39,6 +39,7 @@ LOCAL_SRC_FILES := \
$(wildcard $(LOCAL_PATH)/src/io/generic/*.c) \
$(wildcard $(LOCAL_PATH)/src/gpu/*.c) \
$(wildcard $(LOCAL_PATH)/src/gpu/vulkan/*.c) \
$(wildcard $(LOCAL_PATH)/src/gpu/xr/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
+6
View File
@@ -391,6 +391,7 @@ set_option(SDL_LIBUDEV "Enable libudev support" ON)
set_option(SDL_ASAN "Use AddressSanitizer to detect memory errors" OFF)
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)
set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION")
@@ -1272,6 +1273,8 @@ sdl_glob_sources(
"${SDL3_SOURCE_DIR}/src/filesystem/*.h"
"${SDL3_SOURCE_DIR}/src/gpu/*.c"
"${SDL3_SOURCE_DIR}/src/gpu/*.h"
"${SDL3_SOURCE_DIR}/src/gpu/xr/*.c"
"${SDL3_SOURCE_DIR}/src/gpu/xr/*.h"
"${SDL3_SOURCE_DIR}/src/joystick/*.c"
"${SDL3_SOURCE_DIR}/src/joystick/*.h"
"${SDL3_SOURCE_DIR}/src/haptic/*.c"
@@ -3550,6 +3553,9 @@ if(SDL_GPU)
set(SDL_VIDEO_RENDER_GPU 1)
set(HAVE_RENDER_GPU TRUE)
endif()
if(SDL_GPU_OPENXR)
set(HAVE_GPU_OPENXR 1)
endif()
endif()
# Dummies
+6
View File
@@ -927,6 +927,12 @@
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_gpu_openxr.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_openxrdyn.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\gpu\xr\SDL_gpu_openxr_c.h" />
<ClInclude Include="..\..\src\gpu\xr\SDL_openxr_internal.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\src\core\windows\version.rc" />
+3
View File
@@ -52,6 +52,9 @@
<ClCompile Include="..\..\src\gpu\SDL_gpu.c" />
<ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c" />
<ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_gpu_openxr.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_openxrdyn.c" />
<ClInclude Include="..\..\src\gpu\xr\SDL_openxr_internal.h" />
<ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
<ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
+4
View File
@@ -475,6 +475,8 @@
<ClInclude Include="..\..\src\gpu\d3d12\D3D12_Blit.h" />
<ClInclude Include="..\..\src\gpu\SDL_sysgpu.h" />
<ClInclude Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan_vkfuncs.h" />
<ClInclude Include="..\..\src\gpu\xr\SDL_gpu_openxr_c.h" />
<ClInclude Include="..\..\src\gpu\xr\SDL_openxr_internal.h" />
<ClInclude Include="..\..\src\hidapi\SDL_hidapi_windows.h" />
<ClInclude Include="..\..\src\hidapi\windows\hidapi_cfgmgr32.h" />
<ClInclude Include="..\..\src\hidapi\windows\hidapi_descriptor_reconstruct.h" />
@@ -629,6 +631,8 @@
<ClCompile Include="..\..\src\gpu\SDL_gpu.c" />
<ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c" />
<ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_gpu_openxr.c" />
<ClCompile Include="..\..\src\gpu\xr\SDL_openxrdyn.c" />
<ClCompile Include="..\..\src\io\generic\SDL_asyncio_generic.c" />
<ClCompile Include="..\..\src\io\SDL_asyncio.c" />
<ClCompile Include="..\..\src\main\generic\SDL_sysmain_callbacks.c" />
+29
View File
@@ -981,6 +981,15 @@
<ClInclude Include="..\..\src\gpu\SDL_sysgpu.h">
<Filter>gpu</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan_vkfuncs.h">
<Filter>gpu</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gpu\xr\SDL_gpu_openxr_c.h">
<Filter>gpu</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gpu\xr\SDL_openxr_internal.h">
<Filter>gpu</Filter>
</ClInclude>
<ClInclude Include="..\..\include\SDL3\SDL_storage.h" />
<ClInclude Include="..\..\include\SDL3\SDL_time.h" />
<ClInclude Include="..\..\src\core\SDL_core_unsupported.h" />
@@ -1953,6 +1962,26 @@
<ClCompile Include="..\..\src\gpu\SDL_gpu.c">
<Filter>gpu</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c">
<Filter>gpu</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c">
<Filter>gpu</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gpu\xr\SDL_gpu_openxr.c">
<Filter>gpu</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gpu\xr\SDL_openxrdyn.c">
<Filter>gpu</Filter>
</ClCompile>
<ClCompile Include="..\..\src\process\SDL_process.c" />
<ClCompile Include="..\..\src\process\windows\SDL_windowsprocess.c" />
<ClCompile Include="..\..\src\render\gpu\SDL_pipeline_gpu.c" />
<ClCompile Include="..\..\src\render\gpu\SDL_render_gpu.c" />
<ClCompile Include="..\..\src\render\gpu\SDL_shaders_gpu.c" />
<ClCompile Include="..\..\src\storage\generic\SDL_genericstorage.c" />
<ClCompile Include="..\..\src\storage\steam\SDL_steamstorage.c" />
<ClCompile Include="..\..\src\storage\SDL_storage.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_steam_triton.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
+22
View File
@@ -366,6 +366,10 @@
E4F257952C81903800FCEAFC /* SDL_gpu_vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F257832C81903800FCEAFC /* SDL_gpu_vulkan.c */; };
E4F257962C81903800FCEAFC /* SDL_gpu.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F257852C81903800FCEAFC /* SDL_gpu.c */; };
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 */; };
@@ -937,6 +941,10 @@
E4F257832C81903800FCEAFC /* SDL_gpu_vulkan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gpu_vulkan.c; sourceTree = "<group>"; };
E4F257852C81903800FCEAFC /* SDL_gpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gpu.c; sourceTree = "<group>"; };
E4F257862C81903800FCEAFC /* SDL_sysgpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysgpu.h; sourceTree = "<group>"; };
E4F257882C81903800FCEAFC /* SDL_gpu_openxr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gpu_openxr.c; sourceTree = "<group>"; };
E4F257892C81903800FCEAFC /* SDL_openxrdyn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_openxrdyn.c; sourceTree = "<group>"; };
E4F2578A2C81903800FCEAFC /* SDL_gpu_openxr_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gpu_openxr_c.h; sourceTree = "<group>"; };
E4F2578C2C81903800FCEAFC /* SDL_openxr_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_openxr_internal.h; sourceTree = "<group>"; };
E4F798192AD8D84800669F54 /* SDL_core_unsupported.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_core_unsupported.c; sourceTree = "<group>"; };
E4F7981B2AD8D85500669F54 /* SDL_dynapi_unsupported.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_unsupported.h; sourceTree = "<group>"; };
E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_unsupported.c; sourceTree = "<group>"; };
@@ -2354,11 +2362,23 @@
path = vulkan;
sourceTree = "<group>";
};
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 = "<group>";
};
E4F257872C81903800FCEAFC /* gpu */ = {
isa = PBXGroup;
children = (
E4F257812C81903800FCEAFC /* metal */,
E4F257842C81903800FCEAFC /* vulkan */,
E4F2578B2C81903800FCEAFC /* xr */,
E4F257852C81903800FCEAFC /* SDL_gpu.c */,
E4F257862C81903800FCEAFC /* SDL_sysgpu.h */,
);
@@ -2946,6 +2966,8 @@
A7D8A95723E2514000DCD162 /* SDL_atomic.c in Sources */,
A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */,
E4F257952C81903800FCEAFC /* SDL_gpu_vulkan.c in Sources */,
E4F257982C81903800FCEAFC /* SDL_gpu_openxr.c in Sources */,
E4F257992C81903800FCEAFC /* SDL_openxrdyn.c in Sources */,
A7D8BB2723E2514500DCD162 /* SDL_displayevents.c in Sources */,
A7D8AB2523E2514100DCD162 /* SDL_log.c in Sources */,
A7D8AE8823E2514100DCD162 /* SDL_cocoaopengl.m in Sources */,
+14
View File
@@ -2364,6 +2364,20 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDeviceWithProperties(
#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER "SDL.gpu.device.create.vulkan.options"
#define SDL_PROP_GPU_DEVICE_CREATE_METAL_ALLOW_MACFAMILY1_BOOLEAN "SDL.gpu.device.create.metal.allowmacfamily1"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENABLE_BOOLEAN "SDL.gpu.device.create.xr.enable"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_INSTANCE_POINTER "SDL.gpu.device.create.xr.instance_out"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_SYSTEM_ID_POINTER "SDL.gpu.device.create.xr.system_id_out"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_VERSION_NUMBER "SDL.gpu.device.create.xr.version"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_FORM_FACTOR_NUMBER "SDL.gpu.device.create.xr.form_factor"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_COUNT_NUMBER "SDL.gpu.device.create.xr.extensions.count"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_NAMES_POINTER "SDL.gpu.device.create.xr.extensions.names"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_COUNT_NUMBER "SDL.gpu.device.create.xr.layers.count"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_NAMES_POINTER "SDL.gpu.device.create.xr.layers.names"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_NAME_STRING "SDL.gpu.device.create.xr.application.name"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_VERSION_NUMBER "SDL.gpu.device.create.xr.application.version"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_NAME_STRING "SDL.gpu.device.create.xr.engine.name"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_VERSION_NUMBER "SDL.gpu.device.create.xr.engine.version"
/**
* A structure specifying additional options when using Vulkan.
+12
View File
@@ -1145,6 +1145,18 @@ extern "C" {
*/
#define SDL_HINT_GPU_DRIVER "SDL_GPU_DRIVER"
/**
* A variable that specifies the library name to use when loading the OpenXR loader.
*
* By default, SDL will try the system default name, but on some platforms like Windows,
* debug builds of the OpenXR loader have a different name, and are not always directly compatible with release applications.
* Setting this hint allows you to compensate for this difference in your app when applicable.
*
* This hint should be set before the OpenXR loader is loaded.
* For example, creating an OpenXR GPU device will load the OpenXR loader.
*/
#define SDL_HINT_OPENXR_LIBRARY "SDL_OPENXR_LIBRARY"
/**
* A variable to control whether SDL_hid_enumerate() enumerates all HID
* devices or only controllers.
+207
View File
@@ -0,0 +1,207 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/**
* # CategoryOpenXR
*
* 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.
*
*/
#ifndef SDL_openxr_h_
#define SDL_openxr_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(OPENXR_H_)
#define NO_SDL_OPENXR_TYPEDEFS 1
#endif /* OPENXR_H_ */
#if !defined(NO_SDL_OPENXR_TYPEDEFS)
#define XR_NULL_HANDLE 0
#if !defined(XR_DEFINE_HANDLE)
#define XR_DEFINE_HANDLE(object) typedef Uint64 object;
#endif /* XR_DEFINE_HANDLE */
typedef enum XrStructureType {
XR_TYPE_SESSION_CREATE_INFO = 8,
XR_TYPE_SWAPCHAIN_CREATE_INFO = 9,
} XrStructureType;
XR_DEFINE_HANDLE(XrInstance)
XR_DEFINE_HANDLE(XrSystemId)
XR_DEFINE_HANDLE(XrSession)
XR_DEFINE_HANDLE(XrSwapchain)
typedef struct {
XrStructureType type;
const void* next;
} XrSessionCreateInfo;
typedef struct {
XrStructureType type;
const void* next;
} XrSwapchainCreateInfo;
typedef enum XrResult {
XR_ERROR_FUNCTION_UNSUPPORTED = -7,
XR_ERROR_HANDLE_INVALID = -12,
} XrResult;
#define PFN_xrGetInstanceProcAddr SDL_FunctionPointer
#endif /* NO_SDL_OPENXR_TYPEDEFS */
/**
* Creates an OpenXR session. The OpenXR system ID is pulled from the passed GPU context.
*
* \param device a GPU context.
* \param createinfo the create info for the OpenXR session, sans the system ID.
* \param session a pointer filled in with an OpenXR session created for the given device.
* \returns the result of the call.
*
* \sa SDL_CreateGPUDeviceWithProperties
*/
extern SDL_DECLSPEC XrResult SDLCALL SDL_CreateGPUXRSession(SDL_GPUDevice *device, const XrSessionCreateInfo *createinfo, XrSession *session);
/**
* Queries the GPU device for supported XR swapchain image formats.
*
* The returned pointer should be allocated with SDL_malloc() and will be
* passed to SDL_free().
*
* \param device a GPU context.
* \param session an OpenXR session created for the given device.
* \param num_formats a pointer filled with the number of supported XR swapchain formats.
* \returns a 0 terminated array of supported formats or NULL on failure;
* call SDL_GetError() for more information. This should be freed
* with SDL_free() when it is no longer needed.
*
* \sa SDL_CreateGPUXRSwapchain
*/
extern SDL_DECLSPEC SDL_GPUTextureFormat * SDLCALL SDL_GetGPUXRSwapchainFormats(SDL_GPUDevice *device, XrSession session, int *num_formats);
/**
* Creates an OpenXR swapchain.
*
* The array returned via `textures` is sized according to
*`xrEnumerateSwapchainImages`, and thus should only be accessed via index
* values returned from `xrAcquireSwapchainImage`.
*
* Applications are still allowed to call `xrEnumerateSwapchainImages` on the
* returned XrSwapchain if they need to get the exact size of the array.
*
* \param device a GPU context.
* \param session an OpenXR session created for the given device.
* \param createinfo the create info for the OpenXR swapchain, sans the format.
* \param format a supported format for the OpenXR swapchain.
* \param swapchain a pointer filled in with the created OpenXR swapchain.
* \param textures a pointer filled in with the array of created swapchain images.
* \returns the result of the call.
*
* \sa SDL_CreateGPUDeviceWithProperties
* \sa SDL_CreateGPUXRSession
* \sa SDL_GetGPUXRSwapchainFormats
* \sa SDL_DestroyGPUXRSwapchain
*/
extern SDL_DECLSPEC XrResult SDLCALL SDL_CreateGPUXRSwapchain(
SDL_GPUDevice *device,
XrSession session,
const XrSwapchainCreateInfo *createinfo,
SDL_GPUTextureFormat format,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures);
/**
* Destroys and OpenXR swapchain previously returned by SDL_CreateGPUXRSwapchain.
*
* \param device a GPU context.
* \param swapchain a swapchain previously returned by SDL_CreateGPUXRSwapchain.
* \param swapchainImages an array of swapchain images returned by the same call to SDL_CreateGPUXRSwapchain.
* \returns the result of the call.
*
* \sa SDL_CreateGPUDeviceWithProperties
* \sa SDL_CreateGPUXRSession
* \sa SDL_CreateGPUXRSwapchain
*/
extern SDL_DECLSPEC XrResult SDLCALL SDL_DestroyGPUXRSwapchain(SDL_GPUDevice *device, XrSwapchain swapchain, SDL_GPUTexture **swapchainImages);
/**
* Dynamically load the OpenXR loader. This can be called at any time.
*
* SDL keeps a reference count of the OpenXR loader, calling this function multiple
* times will increment that count, rather than loading the library multiple times.
*
* If not called, this will be implicitly called when creating a GPU device with OpenXR.
*
* This function will use the platform default OpenXR loader name,
* unless the `SDL_HINT_OPENXR_LIBRARY` hint is set.
*
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \sa SDL_HINT_OPENXR_LIBRARY
*/
extern SDL_DECLSPEC bool SDLCALL SDL_OpenXR_LoadLibrary(void);
/**
* Unload the OpenXR loader previously loaded by SDL_OpenXR_LoadLibrary.
*
* SDL keeps a reference count of the OpenXR loader, calling this function will decrement that count.
* Once the reference count reaches zero, the library is unloaded.
*
* \threadsafety This function is not thread safe.
*/
extern SDL_DECLSPEC void SDLCALL SDL_OpenXR_UnloadLibrary(void);
/**
* Get the address of the `xrGetInstanceProcAddr` function.
*
* This should be called after either calling SDL_OpenXR_LoadLibrary() or
* creating an OpenXR SDL_GPUDevice.
*
* The actual type of the returned function pointer is PFN_xrGetInstanceProcAddr,
* but that isn't always available. You should include the OpenXR headers before this header,
* or cast the return value of this function to the correct type.
*
* \returns the function pointer for `xrGetInstanceProcAddr` or NULL on
* failure; call SDL_GetError() for more information.
*/
extern SDL_DECLSPEC PFN_xrGetInstanceProcAddr SDLCALL SDL_OpenXR_GetXrGetInstanceProcAddr(void);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_openxr_h_ */
@@ -488,6 +488,7 @@
#cmakedefine SDL_GPU_D3D12 1
#cmakedefine SDL_GPU_VULKAN 1
#cmakedefine SDL_GPU_METAL 1
#cmakedefine HAVE_GPU_OPENXR 1
#cmakedefine SDL_GPU_PRIVATE 1
@@ -193,6 +193,7 @@
#define SDL_VIDEO_VULKAN 1
#define SDL_VIDEO_RENDER_VULKAN 1
#define SDL_GPU_VULKAN 1
#define HAVE_GPU_OPENXR 1
#define SDL_VIDEO_RENDER_GPU 1
#endif
@@ -289,6 +289,7 @@ typedef unsigned int uintptr_t;
#endif
#define SDL_GPU_D3D12 1
#define SDL_GPU_VULKAN 1
#define HAVE_GPU_OPENXR 1
#define SDL_VIDEO_RENDER_GPU 1
/* Enable system power support */
+1
View File
@@ -233,6 +233,7 @@
#undef SDL_GPU_D3D12
#undef SDL_GPU_METAL
#undef SDL_GPU_VULKAN
#undef HAVE_GPU_OPENXR
#undef SDL_VIDEO_RENDER_GPU
#endif // SDL_GPU_DISABLED
+2
View File
@@ -38,6 +38,7 @@
#endif
#include <SDL3/SDL.h>
#include <SDL3/SDL_openxr.h>
#define SDL_MAIN_NOIMPL // don't drag in header-only implementation of SDL_main
#include <SDL3/SDL_main.h>
#include "../core/SDL_core_unsupported.h"
@@ -597,6 +598,7 @@ static void SDL_InitDynamicAPI(void)
#else // SDL_DYNAMIC_API
#include <SDL3/SDL.h>
#include <SDL3/SDL_openxr.h>
Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize);
Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize)
+7
View File
@@ -1272,6 +1272,13 @@ SDL3_0.0.0 {
SDL_LoadSurface;
SDL_SetWindowFillDocument;
SDL_TryLockJoysticks;
SDL_CreateGPUXRSession;
SDL_GetGPUXRSwapchainFormats;
SDL_CreateGPUXRSwapchain;
SDL_DestroyGPUXRSwapchain;
SDL_OpenXR_LoadLibrary;
SDL_OpenXR_UnloadLibrary;
SDL_OpenXR_GetXrGetInstanceProcAddr;
# extra symbols go here (don't modify this line)
local: *;
};
+7
View File
@@ -1298,3 +1298,10 @@
#define SDL_LoadSurface SDL_LoadSurface_REAL
#define SDL_SetWindowFillDocument SDL_SetWindowFillDocument_REAL
#define SDL_TryLockJoysticks SDL_TryLockJoysticks_REAL
#define SDL_CreateGPUXRSession SDL_CreateGPUXRSession_REAL
#define SDL_GetGPUXRSwapchainFormats SDL_GetGPUXRSwapchainFormats_REAL
#define SDL_CreateGPUXRSwapchain SDL_CreateGPUXRSwapchain_REAL
#define SDL_DestroyGPUXRSwapchain SDL_DestroyGPUXRSwapchain_REAL
#define SDL_OpenXR_LoadLibrary SDL_OpenXR_LoadLibrary_REAL
#define SDL_OpenXR_UnloadLibrary SDL_OpenXR_UnloadLibrary_REAL
#define SDL_OpenXR_GetXrGetInstanceProcAddr SDL_OpenXR_GetXrGetInstanceProcAddr_REAL
+7
View File
@@ -1306,3 +1306,10 @@ SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface_IO,(SDL_IOStream *a,bool b),(a,b),r
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface,(const char *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_SetWindowFillDocument,(SDL_Window *a,bool b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_TryLockJoysticks,(void),(),return)
SDL_DYNAPI_PROC(XrResult,SDL_CreateGPUXRSession,(SDL_GPUDevice *a,const XrSessionCreateInfo *b,XrSession *c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_GPUTextureFormat*,SDL_GetGPUXRSwapchainFormats,(SDL_GPUDevice *a,XrSession b,int *c),(a,b,c),return)
SDL_DYNAPI_PROC(XrResult,SDL_CreateGPUXRSwapchain,(SDL_GPUDevice *a,XrSession b,const XrSwapchainCreateInfo *c,SDL_GPUTextureFormat d,XrSwapchain *e,SDL_GPUTexture ***f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(XrResult,SDL_DestroyGPUXRSwapchain,(SDL_GPUDevice *a,XrSwapchain b,SDL_GPUTexture **c),(a,b,c),return)
SDL_DYNAPI_PROC(bool,SDL_OpenXR_LoadLibrary,(void),(),return)
SDL_DYNAPI_PROC(void,SDL_OpenXR_UnloadLibrary,(void),(),)
SDL_DYNAPI_PROC(PFN_xrGetInstanceProcAddr,SDL_OpenXR_GetXrGetInstanceProcAddr,(void),(),return)
+47
View File
@@ -607,6 +607,13 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
return NULL;
}
#ifndef HAVE_GPU_OPENXR
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENABLE_BOOLEAN, false)) {
SDL_SetError("OpenXR is not enabled in this build of SDL");
return NULL;
}
#endif
gpudriver = SDL_GetHint(SDL_HINT_GPU_DRIVER);
if (gpudriver == NULL) {
gpudriver = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, NULL);
@@ -752,6 +759,13 @@ void SDL_DestroyGPUDevice(SDL_GPUDevice *device)
device->DestroyDevice(device);
}
XrResult SDL_DestroyGPUXRSwapchain(SDL_GPUDevice *device, XrSwapchain swapchain, SDL_GPUTexture **swapchainImages)
{
CHECK_DEVICE_MAGIC(device, XR_ERROR_HANDLE_INVALID);
return device->DestroyXRSwapchain(device->driverData, swapchain, swapchainImages);
}
int SDL_GetNumGPUDrivers(void)
{
#ifndef SDL_GPU_DISABLED
@@ -3567,3 +3581,36 @@ SDL_GPUTextureFormat SDL_GetGPUTextureFormatFromPixelFormat(SDL_PixelFormat form
return SDL_GPU_TEXTUREFORMAT_INVALID;
}
}
XrResult SDL_CreateGPUXRSession(
SDL_GPUDevice *device,
const XrSessionCreateInfo *createinfo,
XrSession *session)
{
CHECK_DEVICE_MAGIC(device, XR_ERROR_HANDLE_INVALID);
return device->CreateXRSession(device->driverData, createinfo, session);
}
SDL_GPUTextureFormat* SDL_GetGPUXRSwapchainFormats(
SDL_GPUDevice *device,
XrSession session,
int *num_formats)
{
CHECK_DEVICE_MAGIC(device, NULL);
return device->GetXRSwapchainFormats(device->driverData, session, num_formats);
}
XrResult SDL_CreateGPUXRSwapchain(
SDL_GPUDevice *device,
XrSession session,
const XrSwapchainCreateInfo *createinfo,
SDL_GPUTextureFormat format,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures)
{
CHECK_DEVICE_MAGIC(device, XR_ERROR_HANDLE_INVALID);
return device->CreateXRSwapchain(device->driverData, session, createinfo, format, swapchain, textures);
}
+29
View File
@@ -24,6 +24,8 @@
#ifndef SDL_GPU_DRIVER_H
#define SDL_GPU_DRIVER_H
#include <SDL3/SDL_openxr.h>
// GraphicsDevice Limits
#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16
@@ -669,6 +671,11 @@ struct SDL_GPUDevice
void (*DestroyDevice)(SDL_GPUDevice *device);
XrResult (*DestroyXRSwapchain)(
SDL_GPURenderer *device,
XrSwapchain swapchain,
SDL_GPUTexture **swapchainImages);
SDL_PropertiesID (*GetDeviceProperties)(SDL_GPUDevice *device);
// State Creation
@@ -705,6 +712,24 @@ struct SDL_GPUDevice
Uint32 size,
const char *debugName);
XrResult (*CreateXRSession)(
SDL_GPURenderer *driverData,
const XrSessionCreateInfo *createinfo,
XrSession *session);
SDL_GPUTextureFormat* (*GetXRSwapchainFormats)(
SDL_GPURenderer *driverData,
XrSession session,
int *num_formats);
XrResult (*CreateXRSwapchain)(
SDL_GPURenderer *driverData,
XrSession session,
const XrSwapchainCreateInfo *createinfo,
SDL_GPUTextureFormat format,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures);
// Debug Naming
void (*SetBufferName)(
@@ -1105,6 +1130,7 @@ struct SDL_GPUDevice
result->func = name##_##func;
#define ASSIGN_DRIVER(name) \
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
ASSIGN_DRIVER_FUNC(DestroyXRSwapchain, name) \
ASSIGN_DRIVER_FUNC(GetDeviceProperties, name) \
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
@@ -1113,6 +1139,9 @@ struct SDL_GPUDevice
ASSIGN_DRIVER_FUNC(CreateTexture, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateXRSession, name) \
ASSIGN_DRIVER_FUNC(GetXRSwapchainFormats, name) \
ASSIGN_DRIVER_FUNC(CreateXRSwapchain, name) \
ASSIGN_DRIVER_FUNC(SetBufferName, name) \
ASSIGN_DRIVER_FUNC(SetTextureName, name) \
ASSIGN_DRIVER_FUNC(InsertDebugLabel, name) \
File diff suppressed because it is too large Load Diff
+49
View File
@@ -26,6 +26,12 @@
#include <Metal/Metal.h>
#include <QuartzCore/CoreAnimation.h>
#ifdef HAVE_GPU_OPENXR
#define XR_USE_GRAPHICS_API_METAL 1
#include "../xr/SDL_openxr_internal.h"
#include "../xr/SDL_openxrdyn.h"
#endif
#include "../SDL_sysgpu.h"
// Defines
@@ -4337,6 +4343,10 @@ static bool METAL_SupportsTextureFormat(
static bool METAL_PrepareDriver(SDL_VideoDevice *this, SDL_PropertiesID props)
{
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENABLE_BOOLEAN, false)) {
return false;
}
if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, false) &&
!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) {
return false;
@@ -4499,6 +4509,45 @@ static void METAL_INTERNAL_DestroyBlitResources(
SDL_free(renderer->blitPipelines);
}
static XrResult METAL_DestroyXRSwapchain(
SDL_GPURenderer *driverData,
XrSwapchain swapchain,
SDL_GPUTexture **swapchainImages)
{
SDL_SetError("The metal backend does not currently support OpenXR");
return XR_ERROR_FUNCTION_UNSUPPORTED;
}
static SDL_GPUTextureFormat* METAL_GetXRSwapchainFormats(
SDL_GPURenderer *driverData,
XrSession session,
int *num_formats)
{
SDL_SetError("The metal backend does not currently support OpenXR");
return NULL;
}
static XrResult METAL_CreateXRSwapchain(
SDL_GPURenderer *driverData,
XrSession session,
const XrSwapchainCreateInfo *oldCreateInfo,
SDL_GPUTextureFormat format,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures)
{
SDL_SetError("The metal backend does not currently support OpenXR");
return XR_ERROR_FUNCTION_UNSUPPORTED;
}
static XrResult METAL_CreateXRSession(
SDL_GPURenderer *driverData,
const XrSessionCreateInfo *createinfo,
XrSession *session)
{
SDL_SetError("The metal backend does not currently support OpenXR");
return XR_ERROR_FUNCTION_UNSUPPORTED;
}
static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
{
@autoreleasepool {
File diff suppressed because it is too large Load Diff
+199
View File
@@ -0,0 +1,199 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef HAVE_GPU_OPENXR
#include "SDL_gpu_openxr.h"
#ifdef SDL_PLATFORM_ANDROID
#include "../../core/android/SDL_android.h"
#endif
#define VALIDATION_LAYER_API_NAME "XR_APILAYER_LUNARG_core_validation"
/* On Android, the OpenXR loader is initialized by SDL_OpenXR_LoadLibrary() in SDL_openxrdyn.c
* which must be called before this. That function handles the complex initialization using
* direct SDL_LoadFunction calls to avoid issues with xrGetInstanceProcAddr from runtime
* negotiation not supporting pre-instance calls. This stub is kept for API compatibility. */
#ifdef SDL_PLATFORM_ANDROID
static bool SDL_OPENXR_INTERNAL_InitializeAndroidLoader(void)
{
/* The loader should already be initialized by SDL_OpenXR_LoadLibrary().
* We just verify that xrGetInstanceProcAddr is available. */
if (xrGetInstanceProcAddr == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "xrGetInstanceProcAddr is NULL - SDL_OpenXR_LoadLibrary was not called first");
return false;
}
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Android OpenXR loader verified (was initialized by SDL_OpenXR_LoadLibrary)");
return true;
}
#endif /* SDL_PLATFORM_ANDROID */
bool SDL_OPENXR_INTERNAL_ValidationLayerAvailable()
{
#ifdef SDL_PLATFORM_ANDROID
/* On Android/Quest, the xrGetInstanceProcAddr obtained through runtime negotiation
* crashes when used for pre-instance global functions. Skip validation layer check. */
return false;
#endif
Uint32 apiLayerCount;
if (XR_FAILED(xrEnumerateApiLayerProperties(0, &apiLayerCount, NULL))) {
return false;
}
if (apiLayerCount <= 0) {
return false;
}
XrApiLayerProperties *apiLayerProperties = SDL_stack_alloc(XrApiLayerProperties, apiLayerCount);
if (XR_FAILED(xrEnumerateApiLayerProperties(apiLayerCount, &apiLayerCount, apiLayerProperties))) {
SDL_stack_free(apiLayerProperties);
return false;
}
bool found = false;
for (Uint32 i = 0; i < apiLayerCount; i++) {
XrApiLayerProperties apiLayer = apiLayerProperties[i];
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "api layer available: %s", apiLayer.layerName);
if (SDL_strcmp(apiLayer.layerName, VALIDATION_LAYER_API_NAME) == 0) {
found = true;
break;
}
}
SDL_stack_free(apiLayerProperties);
return found;
}
XrResult SDL_OPENXR_INTERNAL_GPUInitOpenXR(
bool debugMode,
XrExtensionProperties gpuExtension,
SDL_PropertiesID props,
XrInstance *instance,
XrSystemId *systemId,
XrInstancePfns **xr)
{
XrResult xrResult;
#ifdef SDL_PLATFORM_ANDROID
// Android requires loader initialization before any other XR calls
if (!SDL_OPENXR_INTERNAL_InitializeAndroidLoader()) {
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to initialize Android OpenXR loader");
return XR_ERROR_INITIALIZATION_FAILED;
}
#endif
bool validationLayersAvailable = SDL_OPENXR_INTERNAL_ValidationLayerAvailable();
Uint32 userApiLayerCount = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_COUNT_NUMBER, 0);
const char *const *userApiLayerNames = SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_NAMES_POINTER, NULL);
Uint32 userExtensionCount = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_COUNT_NUMBER, 0);
const char *const *userExtensionNames = SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_NAMES_POINTER, NULL);
// allocate enough space for the validation layer + the user's api layers
const char **apiLayerNames = SDL_stack_alloc(const char *, userApiLayerCount + 1);
SDL_memcpy(apiLayerNames, userApiLayerNames, sizeof(const char *) * (userApiLayerCount));
apiLayerNames[userApiLayerCount] = VALIDATION_LAYER_API_NAME;
// On Android, we need an extra extension for android_create_instance
#ifdef SDL_PLATFORM_ANDROID
const Uint32 platformExtensionCount = 2; // GPU extension + Android create instance
#else
const Uint32 platformExtensionCount = 1; // GPU extension only
#endif
const char **extensionNames = SDL_stack_alloc(const char *, userExtensionCount + platformExtensionCount);
SDL_memcpy(extensionNames, userExtensionNames, sizeof(const char *) * (userExtensionCount));
extensionNames[userExtensionCount] = gpuExtension.extensionName;
#ifdef SDL_PLATFORM_ANDROID
extensionNames[userExtensionCount + 1] = XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME;
#endif
XrInstanceCreateInfo xrInstanceCreateInfo = { XR_TYPE_INSTANCE_CREATE_INFO };
xrInstanceCreateInfo.applicationInfo.apiVersion = SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_VERSION_NUMBER, XR_API_VERSION_1_0);
xrInstanceCreateInfo.enabledApiLayerCount = userApiLayerCount + ((debugMode && validationLayersAvailable) ? 1 : 0); // in debug mode, we enable the validation layer
xrInstanceCreateInfo.enabledApiLayerNames = apiLayerNames;
xrInstanceCreateInfo.enabledExtensionCount = userExtensionCount + platformExtensionCount;
xrInstanceCreateInfo.enabledExtensionNames = extensionNames;
#ifdef SDL_PLATFORM_ANDROID
// Get JNI environment and JavaVM for Android instance creation
JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
JavaVM *vm = NULL;
if (env) {
(*env)->GetJavaVM(env, &vm);
}
void *activity = SDL_GetAndroidActivity();
XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid = { XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR };
instanceCreateInfoAndroid.applicationVM = vm;
instanceCreateInfoAndroid.applicationActivity = activity;
xrInstanceCreateInfo.next = &instanceCreateInfoAndroid;
#endif
const char *applicationName = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_NAME_STRING, "SDL Application");
Uint32 applicationVersion = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_VERSION_NUMBER, 0);
SDL_strlcpy(xrInstanceCreateInfo.applicationInfo.applicationName, applicationName, XR_MAX_APPLICATION_NAME_SIZE);
xrInstanceCreateInfo.applicationInfo.applicationVersion = applicationVersion;
const char *engineName = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_NAME_STRING, "SDLGPU");
uint32_t engineVersion = (uint32_t)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_VERSION_NUMBER, SDL_VERSION);
SDL_strlcpy(xrInstanceCreateInfo.applicationInfo.engineName, engineName, XR_MAX_APPLICATION_NAME_SIZE);
xrInstanceCreateInfo.applicationInfo.engineVersion = engineVersion;
if ((xrResult = xrCreateInstance(&xrInstanceCreateInfo, instance)) != XR_SUCCESS) {
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to create OpenXR instance");
SDL_stack_free(apiLayerNames);
SDL_stack_free(extensionNames);
return false;
}
SDL_stack_free(apiLayerNames);
SDL_stack_free(extensionNames);
*xr = SDL_OPENXR_LoadInstanceSymbols(*instance);
if (!*xr) {
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to load required OpenXR instance symbols");
/* NOTE: we can't actually destroy the created OpenXR instance here,
as we only get that function pointer by loading the instance symbols...
let's just hope that doesn't happen. */
return false;
}
XrSystemGetInfo systemGetInfo = { XR_TYPE_SYSTEM_GET_INFO };
systemGetInfo.formFactor = (XrFormFactor)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_FORM_FACTOR_NUMBER, XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY);
if ((xrResult = (*xr)->xrGetSystem(*instance, &systemGetInfo, systemId)) != XR_SUCCESS) {
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to get OpenXR system");
(*xr)->xrDestroyInstance(*instance);
SDL_free(*xr);
return false;
}
return true;
}
#endif /* HAVE_GPU_OPENXR */
+30
View File
@@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_openxrdyn.h"
XrResult SDL_OPENXR_INTERNAL_GPUInitOpenXR(
bool debugMode,
XrExtensionProperties gpuExtension,
SDL_PropertiesID props,
XrInstance *instance,
XrSystemId *systemId,
XrInstancePfns **xr);
+52
View File
@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* This internal header provides access to the vendored OpenXR headers
* without requiring include path modifications in project files.
* Similar to SDL_vulkan_internal.h for Vulkan headers.
*/
#ifndef SDL_openxr_internal_h_
#define SDL_openxr_internal_h_
#include "SDL_internal.h"
/* Define platform-specific OpenXR macros BEFORE including openxr headers */
#ifdef SDL_PLATFORM_ANDROID
#include <jni.h>
#define XR_USE_PLATFORM_ANDROID
#endif
/* Include the vendored OpenXR headers using relative path */
#include "../../video/khronos/openxr/openxr.h"
#include "../../video/khronos/openxr/openxr_platform.h"
/* Compatibility: XR_API_VERSION_1_0 was added in OpenXR 1.1.x */
#ifndef XR_API_VERSION_1_0
#define XR_API_VERSION_1_0 XR_MAKE_VERSION(1, 0, XR_VERSION_PATCH(XR_CURRENT_API_VERSION))
#endif
#define SDL_OPENXR_CHECK_VERSION(x, y, z) \
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) > x || \
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) == x && XR_VERSION_MINOR(XR_CURRENT_API_VERSION) > y) || \
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) == x && XR_VERSION_MINOR(XR_CURRENT_API_VERSION) == y && XR_VERSION_PATCH(XR_CURRENT_API_VERSION) >= z))
#endif /* SDL_openxr_internal_h_ */
+414
View File
@@ -0,0 +1,414 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_openxrdyn.h"
#ifdef HAVE_GPU_OPENXR
#include <SDL3/SDL_dlopennote.h>
#if defined(SDL_PLATFORM_APPLE)
static const char *openxr_library_names[] = { "libopenxr_loader.dylib", NULL };
#elif defined(SDL_PLATFORM_WINDOWS)
static const char *openxr_library_names[] = { "openxr_loader.dll", NULL };
#elif defined(SDL_PLATFORM_ANDROID)
/* On Android, use the Khronos OpenXR loader (libopenxr_loader.so) which properly
* exports xrGetInstanceProcAddr. This is bundled via the Gradle dependency:
* implementation 'org.khronos.openxr:openxr_loader_for_android:X.Y.Z'
*
* The Khronos loader handles runtime discovery internally via the Android broker
* pattern and properly supports all pre-instance global functions.
*
* Note: Do NOT use Meta's forwardloader (libopenxr_forwardloader.so) - it doesn't
* export xrGetInstanceProcAddr directly and the function obtained via runtime
* negotiation crashes on pre-instance calls (e.g., xrEnumerateApiLayerProperties). */
static const char *openxr_library_names[] = { "libopenxr_loader.so", NULL };
#else
static const char *openxr_library_names[] = { "libopenxr_loader.so.1", "libopenxr_loader.so", NULL };
SDL_ELF_NOTE_DLOPEN(
"gpu-openxr",
"Support for OpenXR with SDL_GPU rendering",
SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libopenxr_loader.so.1", "libopenxr_loader.so"
)
#endif
#define DEBUG_DYNAMIC_OPENXR 0
typedef struct
{
SDL_SharedObject *lib;
} openxrdynlib;
static openxrdynlib openxr_loader = { NULL };
#ifndef SDL_PLATFORM_ANDROID
static void *OPENXR_GetSym(const char *fnname, bool *failed)
{
void *fn = SDL_LoadFunction(openxr_loader.lib, fnname);
#if DEBUG_DYNAMIC_OPENXR
if (fn) {
SDL_Log("OPENXR: Found '%s' in %s (%p)\n", fnname, dynlib->libname, fn);
} else {
SDL_Log("OPENXR: Symbol '%s' NOT FOUND!\n", fnname);
}
#endif
return fn;
}
#endif
// Define all the function pointers and wrappers...
#define SDL_OPENXR_SYM(name) PFN_##name OPENXR_##name = NULL;
#include "SDL_openxrsym.h"
static int openxr_load_refcount = 0;
#ifdef SDL_PLATFORM_ANDROID
#include <jni.h>
#include "../../video/khronos/openxr/openxr_platform.h"
/* On Android, we need to initialize the loader with JNI context before use */
static bool openxr_android_loader_initialized = false;
static bool OPENXR_InitializeAndroidLoader(void)
{
XrResult result;
PFN_xrInitializeLoaderKHR initializeLoader = NULL;
PFN_xrGetInstanceProcAddr loaderGetProcAddr = NULL;
JNIEnv *env = NULL;
JavaVM *vm = NULL;
jobject activity = NULL;
if (openxr_android_loader_initialized) {
return true;
}
/* The Khronos OpenXR loader (libopenxr_loader.so) properly exports xrGetInstanceProcAddr.
* Get it directly from the library - this is the standard approach. */
loaderGetProcAddr = (PFN_xrGetInstanceProcAddr)SDL_LoadFunction(openxr_loader.lib, "xrGetInstanceProcAddr");
if (loaderGetProcAddr == NULL) {
SDL_SetError("Failed to get xrGetInstanceProcAddr from OpenXR loader. "
"Make sure you're using the Khronos loader (libopenxr_loader.so), "
"not Meta's forwardloader.");
return false;
}
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Got xrGetInstanceProcAddr from loader: %p", (void*)loaderGetProcAddr);
#endif
/* Get xrInitializeLoaderKHR via xrGetInstanceProcAddr */
result = loaderGetProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&initializeLoader);
if (XR_FAILED(result) || initializeLoader == NULL) {
SDL_SetError("Failed to get xrInitializeLoaderKHR (result: %d)", (int)result);
return false;
}
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Got xrInitializeLoaderKHR: %p", (void*)initializeLoader);
#endif
/* Get Android environment info from SDL */
env = (JNIEnv *)SDL_GetAndroidJNIEnv();
if (!env) {
SDL_SetError("Failed to get Android JNI environment");
return false;
}
if ((*env)->GetJavaVM(env, &vm) != 0) {
SDL_SetError("Failed to get JavaVM from JNIEnv");
return false;
}
activity = (jobject)SDL_GetAndroidActivity();
if (!activity) {
SDL_SetError("Failed to get Android activity");
return false;
}
XrLoaderInitInfoAndroidKHR loaderInitInfo = {
.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR,
.next = NULL,
.applicationVM = vm,
.applicationContext = activity
};
result = initializeLoader((XrLoaderInitInfoBaseHeaderKHR *)&loaderInitInfo);
if (XR_FAILED(result)) {
SDL_SetError("xrInitializeLoaderKHR failed with result %d", (int)result);
return false;
}
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: xrInitializeLoaderKHR succeeded");
#endif
/* Store the xrGetInstanceProcAddr function - this one properly handles
* all pre-instance calls (unlike Meta's forwardloader runtime negotiation) */
OPENXR_xrGetInstanceProcAddr = loaderGetProcAddr;
xrGetInstanceProcAddr = loaderGetProcAddr;
openxr_android_loader_initialized = true;
return true;
}
#endif /* SDL_PLATFORM_ANDROID */
SDL_DECLSPEC void SDLCALL SDL_OpenXR_UnloadLibrary(void)
{
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: UnloadLibrary called, current refcount=%d", openxr_load_refcount);
#endif
// Don't actually unload if more than one module is using the libs...
if (openxr_load_refcount > 0) {
if (--openxr_load_refcount == 0) {
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Refcount reached 0, unloading library");
#endif
#ifdef SDL_PLATFORM_ANDROID
/* On Android/Quest, don't actually unload the library or reset the loader state.
* The Quest OpenXR runtime doesn't support being re-initialized after teardown.
* xrInitializeLoaderKHR and xrNegotiateLoaderRuntimeInterface must only be called once.
* We keep the library loaded and the loader initialized.
*
* IMPORTANT: We also keep xrGetInstanceProcAddr intact so we can reload other
* function pointers on the next LoadLibrary call. Only NULL out the other symbols. */
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Android - keeping library loaded and loader initialized");
#endif
// Only NULL out non-essential function pointers, keep xrGetInstanceProcAddr
#define SDL_OPENXR_SYM(name) \
if (SDL_strcmp(#name, "xrGetInstanceProcAddr") != 0) { \
OPENXR_##name = NULL; \
}
#include "SDL_openxrsym.h"
#else
// On non-Android, NULL everything and unload
#define SDL_OPENXR_SYM(name) OPENXR_##name = NULL;
#include "SDL_openxrsym.h"
SDL_UnloadObject(openxr_loader.lib);
openxr_loader.lib = NULL;
#endif
}
#if DEBUG_DYNAMIC_OPENXR
else {
SDL_Log("SDL/OpenXR: Refcount is now %d, not unloading", openxr_load_refcount);
}
#endif
}
}
// returns non-zero if all needed symbols were loaded.
SDL_DECLSPEC bool SDLCALL SDL_OpenXR_LoadLibrary(void)
{
bool result = true;
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: LoadLibrary called, current refcount=%d, lib=%p", openxr_load_refcount, (void*)openxr_loader.lib);
#endif
// deal with multiple modules (gpu, openxr, etc) needing these symbols...
if (openxr_load_refcount++ == 0) {
#ifdef SDL_PLATFORM_ANDROID
/* On Android, the library may already be loaded if this is a reload after
* unload (we don't actually unload on Android to preserve runtime state) */
if (openxr_loader.lib == NULL) {
#endif
const char *path_hint = SDL_GetHint(SDL_HINT_OPENXR_LIBRARY);
// If a hint was specified, try that first
if (path_hint && *path_hint) {
openxr_loader.lib = SDL_LoadObject(path_hint);
}
// If no hint or hint failed, try the default library names
if (!openxr_loader.lib) {
for (int i = 0; openxr_library_names[i] != NULL; i++) {
openxr_loader.lib = SDL_LoadObject(openxr_library_names[i]);
if (openxr_loader.lib) {
break;
}
}
}
if (!openxr_loader.lib) {
SDL_SetError("Failed loading OpenXR library");
openxr_load_refcount--;
return false;
}
#if defined(SDL_PLATFORM_ANDROID)
} else {
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Library already loaded (Android reload), skipping SDL_LoadObject");
#endif
}
#endif
#ifdef SDL_PLATFORM_ANDROID
/* On Android, we need to initialize the loader before other functions work.
* OPENXR_InitializeAndroidLoader() will return early if already initialized. */
if (!OPENXR_InitializeAndroidLoader()) {
SDL_UnloadObject(openxr_loader.lib);
openxr_loader.lib = NULL;
openxr_load_refcount--;
return false;
}
#endif
bool failed = false;
#ifdef SDL_PLATFORM_ANDROID
/* On Android with Meta's forwardloader, we need special handling.
* After calling xrInitializeLoaderKHR, the global functions should be available
* either as direct exports from the forwardloader or via xrGetInstanceProcAddr(NULL, ...).
*
* Try getting functions directly from the forwardloader first since they'll go
* through the proper forwarding path. */
XrResult xrResult;
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Loading global functions...");
#endif
/* First try to get functions directly from the forwardloader library */
OPENXR_xrEnumerateApiLayerProperties = (PFN_xrEnumerateApiLayerProperties)SDL_LoadFunction(openxr_loader.lib, "xrEnumerateApiLayerProperties");
OPENXR_xrCreateInstance = (PFN_xrCreateInstance)SDL_LoadFunction(openxr_loader.lib, "xrCreateInstance");
OPENXR_xrEnumerateInstanceExtensionProperties = (PFN_xrEnumerateInstanceExtensionProperties)SDL_LoadFunction(openxr_loader.lib, "xrEnumerateInstanceExtensionProperties");
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Direct symbols - xrEnumerateApiLayerProperties=%p, xrCreateInstance=%p, xrEnumerateInstanceExtensionProperties=%p",
(void*)OPENXR_xrEnumerateApiLayerProperties,
(void*)OPENXR_xrCreateInstance,
(void*)OPENXR_xrEnumerateInstanceExtensionProperties);
#endif
/* If direct loading failed, fall back to xrGetInstanceProcAddr(NULL, ...) */
if (OPENXR_xrEnumerateApiLayerProperties == NULL) {
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrEnumerateApiLayerProperties", (PFN_xrVoidFunction*)&OPENXR_xrEnumerateApiLayerProperties);
if (XR_FAILED(xrResult) || OPENXR_xrEnumerateApiLayerProperties == NULL) {
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Failed to get xrEnumerateApiLayerProperties via xrGetInstanceProcAddr");
#endif
failed = true;
}
}
if (OPENXR_xrCreateInstance == NULL) {
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrCreateInstance", (PFN_xrVoidFunction*)&OPENXR_xrCreateInstance);
if (XR_FAILED(xrResult) || OPENXR_xrCreateInstance == NULL) {
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Failed to get xrCreateInstance via xrGetInstanceProcAddr");
#endif
failed = true;
}
}
if (OPENXR_xrEnumerateInstanceExtensionProperties == NULL) {
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrEnumerateInstanceExtensionProperties", (PFN_xrVoidFunction*)&OPENXR_xrEnumerateInstanceExtensionProperties);
if (XR_FAILED(xrResult) || OPENXR_xrEnumerateInstanceExtensionProperties == NULL) {
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Failed to get xrEnumerateInstanceExtensionProperties via xrGetInstanceProcAddr");
#endif
failed = true;
}
}
#if DEBUG_DYNAMIC_OPENXR
SDL_Log("SDL/OpenXR: Final symbols - xrEnumerateApiLayerProperties=%p, xrCreateInstance=%p, xrEnumerateInstanceExtensionProperties=%p",
(void*)OPENXR_xrEnumerateApiLayerProperties,
(void*)OPENXR_xrCreateInstance,
(void*)OPENXR_xrEnumerateInstanceExtensionProperties);
SDL_Log("SDL/OpenXR: Global functions loading %s", failed ? "FAILED" : "succeeded");
#endif
#else
#define SDL_OPENXR_SYM(name) OPENXR_##name = (PFN_##name)OPENXR_GetSym(#name, &failed);
#include "SDL_openxrsym.h"
#endif
if (failed) {
// in case something got loaded...
SDL_OpenXR_UnloadLibrary();
result = false;
}
}
#if DEBUG_DYNAMIC_OPENXR
else {
SDL_Log("SDL/OpenXR: Library already loaded (refcount=%d), skipping", openxr_load_refcount);
}
#endif
return result;
}
SDL_DECLSPEC PFN_xrGetInstanceProcAddr SDLCALL SDL_OpenXR_GetXrGetInstanceProcAddr(void)
{
if (xrGetInstanceProcAddr == NULL) {
SDL_SetError("The OpenXR loader has not been loaded");
}
return xrGetInstanceProcAddr;
}
XrInstancePfns *SDL_OPENXR_LoadInstanceSymbols(XrInstance instance)
{
XrResult result;
XrInstancePfns *pfns = SDL_calloc(1, sizeof(XrInstancePfns));
#define SDL_OPENXR_INSTANCE_SYM(name) \
result = xrGetInstanceProcAddr(instance, #name, (PFN_xrVoidFunction *)&pfns->name); \
if (result != XR_SUCCESS) { \
SDL_free(pfns); \
return NULL; \
}
#include "SDL_openxrsym.h"
return pfns;
}
#else
SDL_DECLSPEC bool SDLCALL SDL_OpenXR_LoadLibrary(void)
{
return SDL_SetError("OpenXR is not enabled in this build of SDL");
}
SDL_DECLSPEC void SDLCALL SDL_OpenXR_UnloadLibrary(void)
{
SDL_SetError("OpenXR is not enabled in this build of SDL");
}
SDL_DECLSPEC PFN_xrGetInstanceProcAddr SDLCALL SDL_OpenXR_GetXrGetInstanceProcAddr(void)
{
return (PFN_xrGetInstanceProcAddr)SDL_SetError("OpenXR is not enabled in this build of SDL");
}
#endif // HAVE_GPU_OPENXR
+55
View File
@@ -0,0 +1,55 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_openxrdyn_h_
#define SDL_openxrdyn_h_
/* Use the internal header for vendored OpenXR includes */
#include "SDL_openxr_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct XrInstancePfns
{
#define SDL_OPENXR_INSTANCE_SYM(name) \
PFN_##name name;
#include "SDL_openxrsym.h"
} XrInstancePfns;
extern XrInstancePfns *SDL_OPENXR_LoadInstanceSymbols(XrInstance instance);
/* Define the function pointers */
#define SDL_OPENXR_SYM(name) \
extern PFN_##name OPENXR_##name;
#include "SDL_openxrsym.h"
#define xrGetInstanceProcAddr OPENXR_xrGetInstanceProcAddr
#define xrEnumerateApiLayerProperties OPENXR_xrEnumerateApiLayerProperties
#define xrEnumerateInstanceExtensionProperties OPENXR_xrEnumerateInstanceExtensionProperties
#define xrCreateInstance OPENXR_xrCreateInstance
#ifdef __cplusplus
}
#endif
#endif // SDL_openxrdyn_h_
+49
View File
@@ -0,0 +1,49 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* *INDENT-OFF* */ // clang-format off
#include "../../video/khronos/openxr/openxr.h"
#ifndef SDL_OPENXR_SYM
#define SDL_OPENXR_SYM(name)
#endif
#ifndef SDL_OPENXR_INSTANCE_SYM
#define SDL_OPENXR_INSTANCE_SYM(name)
#endif
SDL_OPENXR_SYM(xrGetInstanceProcAddr)
SDL_OPENXR_SYM(xrEnumerateApiLayerProperties)
SDL_OPENXR_SYM(xrCreateInstance)
SDL_OPENXR_SYM(xrEnumerateInstanceExtensionProperties)
SDL_OPENXR_INSTANCE_SYM(xrEnumerateSwapchainFormats)
SDL_OPENXR_INSTANCE_SYM(xrCreateSession)
SDL_OPENXR_INSTANCE_SYM(xrGetSystem)
SDL_OPENXR_INSTANCE_SYM(xrCreateSwapchain)
SDL_OPENXR_INSTANCE_SYM(xrEnumerateSwapchainImages)
SDL_OPENXR_INSTANCE_SYM(xrDestroyInstance)
SDL_OPENXR_INSTANCE_SYM(xrDestroySwapchain)
#undef SDL_OPENXR_SYM
#undef SDL_OPENXR_INSTANCE_SYM
/* *INDENT-ON* */ // clang-format on
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,141 @@
#ifndef OPENXR_LOADER_NEGOTIATION_H_
#define OPENXR_LOADER_NEGOTIATION_H_ 1
/*
** Copyright 2017-2025 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"
#ifdef __cplusplus
extern "C" {
#endif
// XR_LOADER_VERSION_1_0 is a preprocessor guard. Do not pass it to API calls.
#define XR_LOADER_VERSION_1_0 1
#define XR_CURRENT_LOADER_API_LAYER_VERSION 1
#define XR_CURRENT_LOADER_RUNTIME_VERSION 1
#define XR_LOADER_INFO_STRUCT_VERSION 1
#define XR_API_LAYER_INFO_STRUCT_VERSION 1
#define XR_RUNTIME_INFO_STRUCT_VERSION 1
#define XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 1
#define XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 1
#define XR_API_LAYER_MAX_SETTINGS_PATH_SIZE 512
typedef enum XrLoaderInterfaceStructs {
XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0,
XR_LOADER_INTERFACE_STRUCT_LOADER_INFO = 1,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST = 2,
XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST = 3,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO = 4,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO = 5,
XR_LOADER_INTERFACE_STRUCTS_MAX_ENUM = 0x7FFFFFFF
} XrLoaderInterfaceStructs;
typedef XrResult (XRAPI_PTR *PFN_xrGetInstanceProcAddr)(XrInstance instance, const char* name, PFN_xrVoidFunction* function);
typedef struct XrApiLayerCreateInfo XrApiLayerCreateInfo;
typedef XrResult (XRAPI_PTR *PFN_xrCreateApiLayerInstance)(
const XrInstanceCreateInfo* info,
const XrApiLayerCreateInfo* apiLayerInfo,
XrInstance* instance);
typedef struct XrApiLayerNextInfo {
XrLoaderInterfaceStructs structType;
uint32_t structVersion;
size_t structSize;
char layerName[XR_MAX_API_LAYER_NAME_SIZE];
PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr;
PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance;
struct XrApiLayerNextInfo* next;
} XrApiLayerNextInfo;
typedef struct XrApiLayerCreateInfo {
XrLoaderInterfaceStructs structType;
uint32_t structVersion;
size_t structSize;
void* XR_MAY_ALIAS loaderInstance;
char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE];
XrApiLayerNextInfo* nextInfo;
} XrApiLayerCreateInfo;
typedef struct XrNegotiateLoaderInfo {
XrLoaderInterfaceStructs structType;
uint32_t structVersion;
size_t structSize;
uint32_t minInterfaceVersion;
uint32_t maxInterfaceVersion;
XrVersion minApiVersion;
XrVersion maxApiVersion;
} XrNegotiateLoaderInfo;
typedef struct XrNegotiateRuntimeRequest {
XrLoaderInterfaceStructs structType;
uint32_t structVersion;
size_t structSize;
uint32_t runtimeInterfaceVersion;
XrVersion runtimeApiVersion;
PFN_xrGetInstanceProcAddr getInstanceProcAddr;
} XrNegotiateRuntimeRequest;
typedef struct XrNegotiateApiLayerRequest {
XrLoaderInterfaceStructs structType;
uint32_t structVersion;
size_t structSize;
uint32_t layerInterfaceVersion;
XrVersion layerApiVersion;
PFN_xrGetInstanceProcAddr getInstanceProcAddr;
PFN_xrCreateApiLayerInstance createApiLayerInstance;
} XrNegotiateApiLayerRequest;
typedef XrResult (XRAPI_PTR *PFN_xrCreateApiLayerInstance)(const XrInstanceCreateInfo* info, const XrApiLayerCreateInfo* layerInfo, XrInstance* instance);
typedef XrResult (XRAPI_PTR *PFN_xrNegotiateLoaderRuntimeInterface)(const XrNegotiateLoaderInfo* loaderInfo, XrNegotiateRuntimeRequest* runtimeRequest);
typedef XrResult (XRAPI_PTR *PFN_xrNegotiateLoaderApiLayerInterface)(const XrNegotiateLoaderInfo* loaderInfo, const char* layerName, XrNegotiateApiLayerRequest* apiLayerRequest);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateApiLayerInstance(
const XrInstanceCreateInfo* info,
const XrApiLayerCreateInfo* layerInfo,
XrInstance* instance);
XRAPI_ATTR XrResult XRAPI_CALL xrNegotiateLoaderRuntimeInterface(
const XrNegotiateLoaderInfo* loaderInfo,
XrNegotiateRuntimeRequest* runtimeRequest);
XRAPI_ATTR XrResult XRAPI_CALL xrNegotiateLoaderApiLayerInterface(
const XrNegotiateLoaderInfo* loaderInfo,
const char* layerName,
XrNegotiateApiLayerRequest* apiLayerRequest);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,114 @@
/*
** Copyright (c) 2017-2025 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0 OR MIT
*/
#ifndef OPENXR_PLATFORM_DEFINES_H_
#define OPENXR_PLATFORM_DEFINES_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Platform-specific calling convention macros.
*
* Platforms should define these so that OpenXR clients call OpenXR functions
* with the same calling conventions that the OpenXR implementation expects.
*
* XRAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* XRAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* XRAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void);
* Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void);
*/
#if defined(_WIN32)
#define XRAPI_ATTR
// On Windows, functions use the stdcall convention
#define XRAPI_CALL __stdcall
#define XRAPI_PTR XRAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "API not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define XRAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define XRAPI_CALL
#define XRAPI_PTR XRAPI_ATTR
#else
// On other platforms, use the default calling convention
#define XRAPI_ATTR
#define XRAPI_CALL
#define XRAPI_PTR
#endif
#include <stddef.h>
#if !defined(XR_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined( XR_NO_STDINT_H )
// XR_PTR_SIZE (in bytes)
#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__))
#define XR_PTR_SIZE 8
#else
#define XR_PTR_SIZE 4
#endif
// Needed so we can use clang __has_feature portably.
#if !defined(XR_COMPILER_HAS_FEATURE)
#if defined(__clang__)
#define XR_COMPILER_HAS_FEATURE(x) __has_feature(x)
#else
#define XR_COMPILER_HAS_FEATURE(x) 0
#endif
#endif
// Identifies if the current compiler has C++11 support enabled.
// Does not by itself identify if any given C++11 feature is present.
#if !defined(XR_CPP11_ENABLED) && defined(__cplusplus)
#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#define XR_CPP11_ENABLED 1
#elif defined(_MSC_VER) && (_MSC_VER >= 1600)
#define XR_CPP11_ENABLED 1
#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version.
#define XR_CPP11_ENABLED 1
#endif
#endif
// Identifies if the current compiler supports C++11 nullptr.
#if !defined(XR_CPP_NULLPTR_SUPPORTED)
#if defined(XR_CPP11_ENABLED) && \
((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \
(defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1600)) || \
(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403)))
#define XR_CPP_NULLPTR_SUPPORTED 1
#endif
#endif
#if !defined(XR_CPP_NULLPTR_SUPPORTED)
#define XR_CPP_NULLPTR_SUPPORTED 0
#endif // !defined(XR_CPP_NULLPTR_SUPPORTED)
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,330 @@
#ifndef OPENXR_REFLECTION_PARENT_STRUCTS_H_
#define OPENXR_REFLECTION_PARENT_STRUCTS_H_ 1
/*
** Copyright (c) 2017-2025 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 that have a parent type.
*/
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrCompositionLayerBaseHeader
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader_CORE(_avail, _unavail) \
_avail(XrCompositionLayerProjection, XR_TYPE_COMPOSITION_LAYER_PROJECTION) \
_avail(XrCompositionLayerQuad, XR_TYPE_COMPOSITION_LAYER_QUAD) \
_avail(XrCompositionLayerCubeKHR, XR_TYPE_COMPOSITION_LAYER_CUBE_KHR) \
_avail(XrCompositionLayerCylinderKHR, XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR) \
_avail(XrCompositionLayerEquirectKHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR) \
_avail(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \
_avail(XrCompositionLayerPassthroughFB, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB) \
_avail(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrEventDataBaseHeader
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader_CORE(_avail, _unavail) \
_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(XrEventDataVisibilityMaskChangedKHR, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR) \
_avail(XrEventDataPerfSettingsEXT, XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT) \
_avail(XrEventDataMainSessionVisibilityChangedEXTX, XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX) \
_avail(XrEventDataDisplayRefreshRateChangedFB, XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB) \
_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(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) \
_avail(XrEventDataSpaceQueryCompleteFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) \
_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(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \
_avail(XrEventDataPassthroughLayerResumedMETA, XR_TYPE_EVENT_DATA_PASSTHROUGH_LAYER_RESUMED_META) \
_avail(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \
_avail(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrHapticBaseHeader
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader_CORE(_avail, _unavail) \
_avail(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \
_avail(XrHapticAmplitudeEnvelopeVibrationFB, XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB) \
_avail(XrHapticPcmVibrationFB, XR_TYPE_HAPTIC_PCM_VIBRATION_FB) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSwapchainImageBaseHeader
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader(_avail, _unavail) \
_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_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) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_CORE(_avail, _unavail) \
#if defined(XR_USE_GRAPHICS_API_D3D11)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \
_avail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \
_unavail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \
#endif
#if defined(XR_USE_GRAPHICS_API_D3D12)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \
_avail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \
_unavail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_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) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \
_unavail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \
#endif
#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \
_avail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \
_unavail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \
#endif
#if defined(XR_USE_GRAPHICS_API_VULKAN)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \
_avail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \
_unavail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \
#endif
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrLoaderInitInfoBaseHeaderKHR
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_CORE(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_CORE(_avail, _unavail) \
#if defined(XR_USE_PLATFORM_ANDROID)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
_avail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
_unavail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \
#endif
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrBindingModificationBaseHeaderKHR
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR_CORE(_avail, _unavail) \
_avail(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \
_avail(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSwapchainStateBaseHeaderFB
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_CORE(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_CORE(_avail, _unavail) \
_avail(XrSwapchainStateFoveationFB, XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB) \
#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \
_avail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \
_unavail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \
#endif
#if defined(XR_USE_GRAPHICS_API_VULKAN)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \
_avail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \
_unavail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \
#endif
#if defined(XR_USE_PLATFORM_ANDROID)
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
_avail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \
#else
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \
_unavail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \
#endif
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsCreateInfoBaseHeaderML
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \
_avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \
_avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrFutureCompletionBaseHeaderEXT
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
_avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \
_avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \
_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(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \
_avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \
_avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsQueryInfoBaseHeaderML
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \
_avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceQueryInfoBaseHeaderFB
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \
_avail(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceFilterInfoBaseHeaderFB
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB_CORE(_avail, _unavail) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB_CORE(_avail, _unavail) \
_avail(XrSpaceUuidFilterInfoFB, XR_TYPE_SPACE_UUID_FILTER_INFO_FB) \
_avail(XrSpaceComponentFilterInfoFB, XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB) \
/// 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) \
// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrShareSpacesRecipientBaseHeaderMETA()
#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrShareSpacesRecipientBaseHeaderMETA_CORE(_avail, _unavail) \
_avail(XrShareSpacesRecipientGroupsMETA, XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META) \
#endif
+2
View File
@@ -66,6 +66,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(void);
extern SDL_DECLSPEC void SDLCALL JNI_OnLoad(void);
#include <SDL3/SDL_openxr.h>
const static struct {
const char *name;
SDL_FunctionPointer address;