Skip to content

GPU: OpenXR integration #10925

Open
Open
@Beyley

Description

@Beyley

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 of XrSessionCreateInfo being a XrGraphicsBindingD3D11KHR with the created ID3D11Device
  • 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 with XrSessionCreateInfo.next pointing to a XrGraphicsBindingD3D12KHR with the created ID3D12Device and ID3D12CommandQueue
  • 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 the MTLDevice to use
  • Create the GPU objects, including a command queue
  • Create an XrSession with the next ptr of XrSessionCreateInfo pointing to XrGraphicsBindingMetalKHR 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 your VkDevice
  • Call xrGetVulkanGraphicsDeviceKHR to get the VkPhysicalDevice to use
  • Create your VkDevice, pick a queue family+index
  • Create an XrSession with the XrSessionCreateInfo.next ptr pointing to a XrGraphicsBindingVulkanKHR 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 your VkInstance
  • Call xrGetVulkanGraphicsDevice2KHR to get the VkPhysicalDevice to use
  • Call xrCreateVulkanDeviceKHR to create the VkDevice to use
  • Select your queue family/queue index
  • Create the XrSession with the XrSessionCreateInfo.next ptr pointing to a XrGraphicsBindingVulkanKHR 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

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

XR_KHR_vulkan_enable

  • VkPhysicalDevice, like Metal, it seems that Vulkan with OpenXR also forces you to use a particular VkPhysicalDevice, 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions