Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPU: OpenXR integration #11601

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
81908c9
gpu + openxr: Implement initial OpenXR support
Beyley Sep 29, 2024
0f1b4b1
openxr: Fix docs syntax
Beyley Dec 22, 2024
06165bf
gpu: Clean up XR func return values
Beyley Dec 22, 2024
a8666e1
gpu + openxr: Add SDL_XRGPUSupportsProperties
Beyley Dec 22, 2024
a7d323a
openxr: Put structure base header for typedefs
Beyley Dec 23, 2024
eb27beb
gpu: Attempt to fix d3d12 and metal GPU backends
Beyley Dec 23, 2024
736ed52
gpu: Fix d3d12 compilation, and probably metal compilation
Beyley Dec 23, 2024
766e400
gpu: Wait for idle in VULKAN_DestroyXRSwapchain
Beyley Dec 23, 2024
626808e
gpu + openxr: Turn XR device creation into property
Beyley Dec 24, 2024
be446ad
gpu: fix d3d12+metal PrepareDriver func defs
Beyley Dec 24, 2024
6756be5
openxr: Add OpenXR sdk headers to repo
Beyley Dec 24, 2024
7a7f103
cmake: Make DXVK and OpenXR depend on SDL_GPU
Beyley Dec 24, 2024
42fdc34
cmake: Escape SDL_GPU_OPENXR_DYNAMIC in cmake script
Beyley Dec 24, 2024
c32ac6e
gpu: Fix uninitialized variable usage in OpenXR physical device init
Beyley Dec 24, 2024
8121640
gpu: Fix uninitialized memory usage when checking OpenXR vulkan devic…
Beyley Dec 24, 2024
c2448ad
gpu: Add property to specify form factor
Beyley Dec 24, 2024
ef03a30
gpu: Fix warning on GCC
Beyley Dec 24, 2024
6dbcd49
cmake: Make HAVE_GPU_OPENXR match rest of build config
Beyley Dec 24, 2024
98b2343
gpu/vulkan: Use props OpenXR version in PrepareDriver
Beyley Jan 10, 2025
c08ef2d
gpu/d3d12: Implement OpenXR session creation
Beyley Jan 10, 2025
ade4830
gpu+d3d12: Initial buggy OpenXR swapchain support
Beyley Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,8 @@ 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)
set_option(SDL_GPU_DXVK "Build SDL_GPU with DXVK support" OFF)
dep_option(SDL_GPU_DXVK "Build SDL_GPU with DXVK support" OFF SDL_GPU OFF)
dep_option(SDL_GPU_OPENXR "Build SDL_GPU with OpenXR support" ON SDL_GPU OFF)

set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION")

Expand Down Expand Up @@ -3027,6 +3028,18 @@ if(SDL_GPU)
set(SDL_VIDEO_RENDER_GPU 1)
set(HAVE_RENDER_GPU TRUE)
endif()
if(SDL_GPU_OPENXR)
if(WIN32)
set(SDL_GPU_OPENXR_DYNAMIC "\"openxr_loader.dll\"")
elseif(APPLE)
set(SDL_GPU_OPENXR_DYNAMIC "\"libopenxr_loader.dylib\"")
else()
set(SDL_GPU_OPENXR_DYNAMIC "\"libopenxr_loader.so.1\"")
Copy link
Contributor

@madebr madebr Dec 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like only Linux has a versioned library. This is probably an oversight.

Reminder for me to create a PR to the oxr repo.

endif()

sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/xr/*.c")
set(HAVE_GPU_OPENXR 1)
endif()
endif()

# Dummies
Expand Down
14 changes: 14 additions & 0 deletions include/SDL3/SDL_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2155,6 +2155,20 @@ extern SDL_DECLSPEC SDL_GPUDevice *SDLCALL SDL_CreateGPUDeviceWithProperties(
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN "SDL.gpu.device.create.shaders.metallib"
#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING "SDL.gpu.device.create.d3d12.semantic"

#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENABLE "SDL.gpu.device.create.xr.enable"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_INSTANCE_OUT "SDL.gpu.device.create.xr.instance_out"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_SYSTEM_ID_OUT "SDL.gpu.device.create.xr.system_id_out"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_VERSION "SDL.gpu.device.create.xr.version"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_FORM_FACTOR "SDL.gpu.device.create.xr.form_factor"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_COUNT "SDL.gpu.device.create.xr.extensions.count"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_NAMES "SDL.gpu.device.create.xr.extensions.names"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_COUNT "SDL.gpu.device.create.xr.layers.count"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_NAMES "SDL.gpu.device.create.xr.layers.names"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_NAME "SDL.gpu.device.create.xr.application.name"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_VERSION "SDL.gpu.device.create.xr.application.version"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_NAME "SDL.gpu.device.create.xr.engine.name"
#define SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_VERSION "SDL.gpu.device.create.xr.engine.version"

/**
* Destroys a GPU context previously returned by SDL_CreateGPUDevice.
*
Expand Down
105 changes: 105 additions & 0 deletions include/SDL3/SDL_openxr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <[email protected]>

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;
#endif /* NO_SDL_OPENXR_TYPEDEFS */

extern SDL_DECLSPEC XrResult SDLCALL SDL_CreateGPUXRSession(
SDL_GPUDevice *device,
const XrSessionCreateInfo *createinfo,
XrSession *session);

/* TODO: document this. tl;dr: SDL_gpu picks the format,
and validates the usageFlags are supported by SDL_gpu,
but all other fields are fair game */
/* TODO: figure out then document what usageFlags are actually possible to be supported by SDL_gpu */
extern SDL_DECLSPEC XrResult SDLCALL SDL_CreateGPUXRSwapchain(
SDL_GPUDevice *device,
XrSession session,
const XrSwapchainCreateInfo *createinfo, /**< The swapchain create info. */
SDL_GPUTextureFormat *textureFormat, /**< The texture format that SDL picked. */
XrSwapchain *swapchain, /**< The created OpenXR swapchain. */
SDL_GPUTexture ***textures /**< A pointer to where to store the swapchain texture array. */);

extern SDL_DECLSPEC XrResult SDLCALL SDL_DestroyGPUXRSwapchain(SDL_GPUDevice *device, XrSwapchain swapchain, SDL_GPUTexture **swapchainImages);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>

#endif /* SDL_openxr_h_ */
2 changes: 2 additions & 0 deletions include/build_config/SDL_build_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@
#cmakedefine SDL_GPU_D3D12 1
#cmakedefine SDL_GPU_VULKAN 1
#cmakedefine SDL_GPU_METAL 1
#cmakedefine HAVE_GPU_OPENXR 1
#cmakedefine SDL_GPU_OPENXR_DYNAMIC @SDL_GPU_OPENXR_DYNAMIC@

/* Enable system power support */
#cmakedefine SDL_POWER_ANDROID 1
Expand Down
1 change: 1 addition & 0 deletions src/SDL_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,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

Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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>

Expand Down Expand Up @@ -559,6 +560,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)
Expand Down
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,9 @@ SDL3_0.0.0 {
SDL_GetTrayMenuParentEntry;
SDL_GetTrayMenuParentTray;
SDL_GetThreadState;
SDL_CreateGPUXRSession;
SDL_CreateGPUXRSwapchain;
SDL_DestroyGPUXRSwapchain;
# extra symbols go here (don't modify this line)
local: *;
};
4 changes: 4 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -1255,3 +1255,7 @@
#define SDL_GetTrayMenuParentEntry SDL_GetTrayMenuParentEntry_REAL
#define SDL_GetTrayMenuParentTray SDL_GetTrayMenuParentTray_REAL
#define SDL_GetThreadState SDL_GetThreadState_REAL
#define SDL_CreateXRGPUDeviceWithProperties SDL_CreateXRGPUDeviceWithProperties_REAL
#define SDL_CreateGPUXRSession SDL_CreateGPUXRSession_REAL
#define SDL_CreateGPUXRSwapchain SDL_CreateGPUXRSwapchain_REAL
#define SDL_DestroyGPUXRSwapchain SDL_DestroyGPUXRSwapchain_REAL
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1263,3 +1263,6 @@ SDL_DYNAPI_PROC(SDL_TrayMenu*,SDL_GetTrayEntryParent,(SDL_TrayEntry *a),(a),retu
SDL_DYNAPI_PROC(SDL_TrayEntry*,SDL_GetTrayMenuParentEntry,(SDL_TrayMenu *a),(a),return)
SDL_DYNAPI_PROC(SDL_Tray*,SDL_GetTrayMenuParentTray,(SDL_TrayMenu *a),(a),return)
SDL_DYNAPI_PROC(SDL_ThreadState,SDL_GetThreadState,(SDL_Thread *a),(a),return)
SDL_DYNAPI_PROC(XrResult,SDL_CreateGPUXRSession,(SDL_GPUDevice *a, const XrSessionCreateInfo *b, XrSession *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)
42 changes: 40 additions & 2 deletions src/gpu/SDL_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_METALLIB;
}
#ifndef HAVE_GPU_OPENXR
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENABLE, 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) {
Expand All @@ -415,7 +421,8 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
SDL_SetError("Required shader format for backend %s not provided!", gpudriver);
return NULL;
}
if (backends[i]->PrepareDriver(_this)) {

if (backends[i]->PrepareDriver(_this, props)) {
return backends[i];
}
}
Expand All @@ -430,7 +437,8 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
// Don't select a backend which doesn't support the app's shaders.
continue;
}
if (backends[i]->PrepareDriver(_this)) {

if (backends[i]->PrepareDriver(_this, props)) {
return backends[i];
}
}
Expand Down Expand Up @@ -547,6 +555,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
Expand Down Expand Up @@ -2919,3 +2934,26 @@ Uint32 SDL_CalculateGPUTextureFormatSize(
Uint32 blocksPerColumn = (height + blockHeight - 1) / blockHeight;
return depth_or_layer_count * blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
}

XrResult SDL_CreateGPUXRSession(
SDL_GPUDevice *device,
const XrSessionCreateInfo *createinfo,
XrSession *session)
{
CHECK_DEVICE_MAGIC(device, XR_NULL_HANDLE);

return device->CreateXRSession(device->driverData, createinfo, session);
}

XrResult SDL_CreateGPUXRSwapchain(
SDL_GPUDevice *device,
XrSession session,
const XrSwapchainCreateInfo *createinfo,
SDL_GPUTextureFormat *textureFormat,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures)
{
CHECK_DEVICE_MAGIC(device, XR_NULL_HANDLE);

return device->CreateXRSwapchain(device->driverData, session, createinfo, textureFormat, swapchain, textures);
}
25 changes: 24 additions & 1 deletion src/gpu/SDL_sysgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#ifndef SDL_GPU_DRIVER_H
#define SDL_GPU_DRIVER_H

#include <SDL3/SDL_openxr.h>

// Common Structs

typedef struct Pass
Expand Down Expand Up @@ -449,6 +451,11 @@ struct SDL_GPUDevice

void (*DestroyDevice)(SDL_GPUDevice *device);

XrResult (*DestroyXRSwapchain)(
SDL_GPURenderer *device,
XrSwapchain swapchain,
SDL_GPUTexture **swapchainImages);

// State Creation

SDL_GPUComputePipeline *(*CreateComputePipeline)(
Expand Down Expand Up @@ -481,6 +488,19 @@ struct SDL_GPUDevice
SDL_GPUTransferBufferUsage usage,
Uint32 size);

XrResult (*CreateXRSession)(
SDL_GPURenderer *driverData,
const XrSessionCreateInfo *createinfo,
XrSession *session);

XrResult (*CreateXRSwapchain)(
SDL_GPURenderer *driverData,
XrSession session,
const XrSwapchainCreateInfo *createinfo,
SDL_GPUTextureFormat *textureFormat,
XrSwapchain *swapchain,
SDL_GPUTexture ***textures);

// Debug Naming

void (*SetBufferName)(
Expand Down Expand Up @@ -878,13 +898,16 @@ struct SDL_GPUDevice
result->func = name##_##func;
#define ASSIGN_DRIVER(name) \
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
ASSIGN_DRIVER_FUNC(DestroyXRSwapchain, name) \
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(CreateSampler, name) \
ASSIGN_DRIVER_FUNC(CreateShader, name) \
ASSIGN_DRIVER_FUNC(CreateTexture, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateXRSession, name) \
ASSIGN_DRIVER_FUNC(CreateXRSwapchain, name) \
ASSIGN_DRIVER_FUNC(SetBufferName, name) \
ASSIGN_DRIVER_FUNC(SetTextureName, name) \
ASSIGN_DRIVER_FUNC(InsertDebugLabel, name) \
Expand Down Expand Up @@ -964,7 +987,7 @@ typedef struct SDL_GPUBootstrap
{
const char *name;
const SDL_GPUShaderFormat shader_formats;
bool (*PrepareDriver)(SDL_VideoDevice *_this);
bool (*PrepareDriver)(SDL_VideoDevice *_this, SDL_PropertiesID props);
SDL_GPUDevice *(*CreateDevice)(bool debug_mode, bool prefer_low_power, SDL_PropertiesID props);
} SDL_GPUBootstrap;

Expand Down
Loading