Description
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
- Create an XrInstance with the
XR_KHR_D3D11_enable
extension enabled. - Create the XrSystem
- Call
xrGetD3D11GraphicsRequirementsKHR
with the created OpenXR instance and system to get the feature level and adapter to use when creating your D3D11 objects. - Create your D3D11 device and such
- Create an XrSession with the
next
ptr ofXrSessionCreateInfo
being aXrGraphicsBindingD3D11KHR
with the createdID3D11Device
- Continue creating the
SDL_GPUDevice*
as normal
XR_KHR_D3D12_enable
- Create an XrInstance with the
XR_KHR_D3D12_enable
extension enabled. - Create the XrSystem
- Call
xrGetD3D12GraphicsRequirementsKHR
to get the minimum feature level and adapter to use. - Create your D3D12 device and a command queue
- Call
xrCreateSession
withXrSessionCreateInfo.next
pointing to aXrGraphicsBindingD3D12KHR
with the createdID3D12Device
andID3D12CommandQueue
- Continue creating the
SDL_GPUDevice*
as normal
XR_KHR_metal_enable
- Create an XrInstance with the
XR_KHR_metal_enable
extension enabled. - Create the XrSystem
- Call
xrGetMetalGraphicsRequirementsKHR
to get theMTLDevice
to use - Create the GPU objects, including a command queue
- Create an XrSession with the
next
ptr ofXrSessionCreateInfo
pointing toXrGraphicsBindingMetalKHR
filled in with the created command queue. - Continue creating the
SDL_GPUDevice*
as normal
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
- Create an XrInstance with the
XR_KHR_vulkan_enable
extension enabled - Create the XrSystem
- Call
xrGetVulkanGraphicsRequirementsKHR
to get the minimum/maximum Vulkan version supported by the OpenXR runtime - Call
xrGetVulkanInstanceExtensionsKHR
to get the instance extensions to enable when creating your VkInstance - Create your VkInstance
- Call
xrGetVulkanDeviceExtensionsKHR
to get the Vulkan device extensions to enable when creating yourVkDevice
- Call
xrGetVulkanGraphicsDeviceKHR
to get theVkPhysicalDevice
to use - Create your
VkDevice
, pick a queue family+index - Create an XrSession with the
XrSessionCreateInfo.next
ptr pointing to aXrGraphicsBindingVulkanKHR
with the VkInstance, VkPhysicalDevice, VkDevice, queue family, and queue index to use. - Continue creating the
SDL_GPUDevice*
as normal
XR_KHR_vulkan_enable2
- Create an XrInstance with the
XR_KHR_vulkan_enable2
extension enabled. - Create the OpenXR System
- Call
xrGetVulkanGraphicsRequirements2KHR
to get the minimum/maximum Vulkan version supported by the OpenXR runtime - Call
xrCreateVulkanInstanceKHR
to create yourVkInstance
- Call
xrGetVulkanGraphicsDevice2KHR
to get theVkPhysicalDevice
to use - Call
xrCreateVulkanDeviceKHR
to create theVkDevice
to use - Select your queue family/queue index
- Create the XrSession with the
XrSessionCreateInfo.next
ptr pointing to aXrGraphicsBindingVulkanKHR
with the VkInstance, VkPhysicalDevice, VkDevice, queue family, and queue index - Continue creating the
SDL_GPUDevice*
as normal
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
ID3D11Device*
ID3D12Device*
ID3D12CommandQueue*
(NOTE: I haven't used OpenXR with D3D12, but I from reading the spec, I believe this can be any D3D12 command queue)MTLCommandQueue
(it actually wants an "an Objective-C object that conforms to the MTLCommandQueue protocol", but I dont know enough metal/obj-c to know what that entails)
XR_KHR_vulkan_enable
XR_KHR_vulkan_enable2
PFN_vkGetInstanceProcAddr
const VkInstanceCreateInfo*
const VkAllocationCallbacks*
VkPhysicalDevice
const VkDeviceCreateInfo*
const VkAllocationCallbacks*
List of GPU handles returned by OpenXR, needed to be passed into the GPU API
ID3D11Texture2D*
, returned byxrEnumerateSwapchainImages
ID3D12Resource*
, returned byxrEnumerateSwapchainImages
MTLTexture
, returned byxrEnumerateSwapchainImages
. (once again it's actually a void*, and is defined as "texture is populated with a valid Metal texture to use, which must be able to be bridged casted to an Objective-C object that conforms to the MTLTexture protocol")MTLDevice
, returned byxrGetMetalGraphicsRequirementsKHR
. The spec seems to force you to use a specificMTLDevice
on metal, you can't create your own.VkImage
returned byxrEnumerateSwapchainImages
LUID
for the D3D11/D3D12 adapter to use
XR_KHR_vulkan_enable
VkPhysicalDevice
, like Metal, it seems that Vulkan with OpenXR also forces you to use a particularVkPhysicalDevice
, and the application is unable to pick one on it's own.
XR_KHR_vulkan_enable2
The various OpenXR extensions also return some required info to init a functional GPU device for OpenXR usage
- Minimum feature level for D3D11 device, returned by
xrGetD3D11GraphicsRequirementsKHR
. - Minimum feature level for D3D12 device, returned by
xrGetD3D12GraphicsRequirementsKHR
- (
XR_KHR_vulkan_enable
) Minimum/Maximum Vulkan version supported by the OpenXR runtime, returned byxrGetVulkanGraphicsRequirementsKHR
- (
XR_KHR_vulkan_enable2
) Minimum/Maximum Vulkan version supported, returned byxrGetVulkanGraphicsRequirements2KHR