libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.52k stars 1.77k forks source link

GPU: OpenXR integration #10925

Open Beyley opened 6 days ago

Beyley commented 6 days ago

After taking a deep dive into the various graphics API init routines for OpenXR (and reading the entire core specification front to back), I think the only way to make this work cleanly and according to the OpenXR spec is if SDL fully wrapped the creation of your OpenXR Instance, System, and Session into the same function call that creates the SDL_GPUDevice*. There is just way too much intertwined with the core init code of the GPU device, since all the extensions tell you which GPU device/instance/adapter you must use for rendering with OpenXR.

Along with this, there should likely be an SDL_GPUCreateXrSwapchain function, which picks the best format to use, and returns the created swapchain, and also SDL_GPUEnumerateXrSwapchainImages, which returns the SDL_GPUTexture* for every swapchain image in the swapchain you need to render to. The SDL_GPUCreateXrSwapchain function can probably be omitted if desired, by having an SDL_GPUGetXrSwapchainFormats, which internally calls xrEnumerateSwapchainFormats and returns all the ones SDL_GPU can render to.

Init steps for each API

These are written from the perspective of SDL creating a GPU device from scratch (after it has determined which API it wants to use for VR)

XR_KHR_D3D11_enable

XR_KHR_D3D12_enable

XR_KHR_metal_enable

Note about Vulkan

From what I can see, you probably need to support both the XR_KHR_vulkan_enable and XR_KHR_vulkan_enable2 extensions, as some runtimes may only support one or the other.

XR_KHR_vulkan_enable

XR_KHR_vulkan_enable2

Brief summary of the handles that need to be passed between OpenXR and SDL, mostly to give scale of just how intertwined the init of the GPU device and OpenXR session really are.

List of GPU handles needed to pass into OpenXR

List of GPU handles returned by OpenXR, needed to be passed into the GPU API

The various OpenXR extensions also return some required info to init a functional GPU device for OpenXR usage

flibitijibibo commented 5 days ago

Agreed - in the nuclear case we can just add a property but it'd be nice to have a full list of what apps need to support VR with any given GPU API.

We could maybe kill two birds with one stone by having an OpenXR sample at https://github.com/TheSpydog/SDL_gpu_examples, and developing a gpu-xr PR to support it. My only experience with XR right now is input, for #4464, so I dunno how much help I'll be.

Beyley commented 5 days ago

it'd be nice to have a full list of what apps need to support VR with any given GPU API.

I've updated the issue with a full breakdown of the init process for every currently supported graphics API, turns out this will probably be a lot more involved than I originally thought. But should still be possible without exposing any raw GPU handles to the end user.

We could maybe kill two birds with one stone by having an OpenXR sample at TheSpydog/SDL_gpu_examples, and developing a gpu-xr PR to support it. My only experience with XR right now is input, for https://github.com/libsdl-org/SDL/issues/4464, so I dunno how much help I'll be.

I might fork off SDL and SDL_gpu_examples at some point, to try to actually get some code down for this, unless someone gets to it before me

Beyley commented 1 hour ago

I have started very early work on this here and here. Right now I have instance/system/session creation working on Vulkan with KHR_vulkan_enable2. (side note: my SDL is saying its forked off that other repo since i've forked SDL in the past for other stuff)

I have nothing visual to show yet, since I still gotta write the rest of the surrounding code in the example itself, and also write some swapchain related functions in SDL_gpu to let me render to the XR session swapchain.

Only after that can I actually start working on cleaning this up to upstream. (which includes stuff like making the OpenXR loader dynamically loaded)

I'm terrible with CMake, so forgive my dirty hacks and probable sins in the CMake patches to SDL :smiling_face_with_tear: