Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

OpenXR Spatial Containers

vrarwiki.com · VR & AR Wiki

OpenXR Spatial Containers are a set of OpenXR extensions for presenting application content in system-managed spatial windows. They allow a compatible OpenXR runtime to arrange content from several applications, control which containers are visible and receive input, and support bounded or full-screen immersive presentation. A container can hold a panel with limited depth or a volume containing three-dimensional content.[1]

Reviewed 21 October 2026. Published Khronos specifications, release history and official sample code About review dates.

The two initial extensions are XR_EXT_spatial_container, which defines container management, and XR_EXT_spatial_container_self_rendering, which lets applications supply their own rendered images through OpenXR composition layers. The release notes for OpenXR Specification 1.1.63, dated 1 September 2026, list both as new ratified multi-vendor extensions.[2] The Khronos Group published its explanatory announcement on 19 October 2026, describing specifications and sample code as available while implementation rollout was still expected during 2026.[3]

Presentation model

The extensions address an application model in which several spatial experiences can coexist, including augmented reality and mixed reality applications. Instead of treating the entire session as one visible application surface, the runtime manages individual containers. It can place or move them on the user's behalf, show or hide them, and decide which can receive input. The desktop-window analogy describes this division of responsibility; a container's content need not be a flat rectangle.[1]

Bounds mode Meaning
Bounded The container has finite bounds and occupies a limited region. Its content can be a panel with small depth offsets or a three-dimensional volume.
Immersive The container has infinite bounds and uses full-screen immersive presentation. The runtime may hide other containers, but applications cannot assume that it always does so.

The mode definitions and visibility rules come from XR_EXT_spatial_container. Applications can request mode changes, allowing an experience to move between bounded and immersive presentation when the system supports the requested modes.[1]

An application supplies suggested dimensions when creating a container, but the runtime may ignore that suggestion. Once created, this extension provides no request to set an arbitrary new size: the application can request a change between bounded and immersive modes and observe the dimensions chosen by the runtime. Bounds changes are reported through events and can also be queried.[1]

Availability and capability queries

Spatial containers are optional extensions. Their presence in a published OpenXR specification does not establish that a particular runtime implements them. The system capability structure, XrSystemSpatialContainerPropertiesEXT, reports the maximum number of containers an application can create and whether bounded and immersive modes are supported. A runtime implementing the base extension must support at least one of those modes.[4]

The creation limit is distinct from the number of containers that can be displayed simultaneously. The base extension does not expose a query for the latter, since the runtime may change display limits according to the state of other applications. A constrained implementation may display only one container at a time.[4] For graphical runtimes implementing the self-rendering extension, that extension additionally requires support for immersive containers.[5]

The base extension also defines xrEnumerateSupportedSpatialContainerGraphicsPresentationsEXT, which reports supported graphics presentation methods. The Khronos sample enables both extensions when creating its instance and queries system properties before creating containers. The example source does not establish support on a particular headset.[1][6]

Container lifecycle and input

An application opts a session into the container model by including XrSessionCreateInfoSpatialContainersEXT in session creation. A new container starts hidden, unable to receive input, and in bounded mode. The application can configure its initial mode, request visibility, and wait for the runtime's visibility event before starting to render it.[1]

Visibility requests are asynchronous. A runtime may defer or reject a request to show a container, for example when the user previously minimized it. Mode changes are asynchronous as well, and a request to change a visible container's mode may be denied. Applications therefore need to respond to the resulting state-change or denial events rather than treating a successful request as immediate presentation.[1]

The container state includes separate visible, interactable and boundsMode values. Interactable means that a container can receive input, and several containers may be interactable at once.[7] The runtime controls this status; an application cannot request input focus for a container through the base extension. An interactable container must also be visible.[1]

This changes the ordinary OpenXR session lifecycle. During active container use the session remains in XR_SESSION_STATE_IDLE, which is treated as running, while visibility, interaction and closure are communicated per container. The session-level xrBeginSession and xrEndSession calls are not used in this mode. Session loss still produces XR_SESSION_STATE_LOSS_PENDING and closes the session's containers.[1]

Spaces and placement

A container has a local coordinate system with its origin at the center of its bounds. The application obtains an XrSpace for it through xrCreateSpatialContainerSpaceEXT. The runtime may change the container's pose when the user moves it or when its bounds mode changes. Its origin is therefore not world-locked; an immersive application that needs a world-locked origin can use a suitable reference space instead.[8]

OpenXR spaces are coordinate frames used to express and locate poses relative to one another.[9] A spatial container adds presentation and lifecycle management around content. The related OpenXR Spatial Entities framework addresses a different task: representing environmental features, tracking planes and markers, and supporting spatial anchor and persistence capabilities. A display container and an environmental entity are separate concepts.[10]

Self-rendering

With XR_EXT_spatial_container_self_rendering, the application generates the pixels and submits them through standard OpenXR swapchains and composition layers. It begins or ends rendering for each container with xrBeginSpatialContainerRenderingEXT and xrEndSpatialContainerRenderingEXT. These operations control membership in the active rendering set; they are not calls made for each frame.[5]

The frame loop still uses xrWaitFrame and xrBeginFrame. It locates views for the active containers through xrLocateSpatialContainerViewsEXT, renders the required layers, and submits the container layer information through an extension structure attached to xrEndFrame. Ordinary session-level layer submission and xrLocateViews are not used in this mode.[5]

Rendering recommendations are supplied per container. XrSpatialContainerViewStateEXT reports valid view data, the effective view configuration, whether layers should be submitted, and a recommended image extent. These allow rendering to reflect the container's current presentation rather than assuming it occupies the whole display. For view-dependent content, the recommended extent can change every frame; the specification advises changing the image region used rather than recreating the swapchain solely because this recommendation changed.[11]

For each active container, an application can submit new layers, explicitly retain its previous layer submission and image contents, or clear the container. This allows a container whose content does not need updating to retain its previous submission.[5]

Pixel bounds and volume bounds

A bounded self-rendered container has both three-dimensional volume bounds and the two-dimensional pixel bounds obtained by projecting that volume onto each display. The runtime must discard pixels outside those projected bounds. It must not automatically discard pixels that lie inside the projected bounds but outside the three-dimensional volume, so stereoscopic content can appear to extend in front of or beyond the container's volume.[12]

Applications can clip their own rendering to the volume and describe that behavior with XrSpatialContainerLayerVolumeClippingEXT. The clipping value is a hint about what the application rendered, rather than an instruction requiring the runtime to perform arbitrary three-dimensional clipping.[12]

Publication and implementation status

The initial published design separates container management from the mechanism that draws its content. The base extension defines management, while the self-rendering extension defines application-generated imagery. In the 19 October 2026 announcement, Khronos described a system-provided renderer as further work underway. That announcement did not establish such a renderer as part of the two published extensions.[3]

Khronos also published a spatial-container example in the OpenXR-SDK-Source repository.[6] The specifications and example describe an interoperable application interface. Actual use still depends on extension support, graphics presentation support, mode capabilities and runtime decisions about visibility and input.[4][1]

References

  1. ↑ 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 "The OpenXR 1.1.65 Specification: XR_EXT_spatial_container". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_EXT_spatial_container. Retrieved 2026-10-21.
  2. ↑ "Changelog for OpenXR-Docs and OpenXR-Registry Repos: OpenXR Specification 1.1.63 (2026-09-01)". Khronos Group. 2026-09-01. https://github.com/KhronosGroup/OpenXR-Docs/blob/main/CHANGELOG.Docs.md. Retrieved 2026-10-21.
  3. ↑ 3.0 3.1 Khronos OpenXR Working Group (2026-10-19). "OpenXR Spatial Containers Bring a Cross-Platform Spatial Windowing API to XR". Khronos Group. https://www.khronos.org/blog/openxr-spatial-containers. Retrieved 2026-10-21.
  4. ↑ 4.0 4.1 4.2 "XrSystemSpatialContainerPropertiesEXT: System properties for spatial containers". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrSystemSpatialContainerPropertiesEXT.html. Retrieved 2026-10-21.
  5. ↑ 5.0 5.1 5.2 5.3 "The OpenXR 1.1.65 Specification: XR_EXT_spatial_container_self_rendering". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_EXT_spatial_container_self_rendering. Retrieved 2026-10-21.
  6. ↑ 6.0 6.1 "OpenXR spatial containers sample: openxr_program_spatial_containers.cpp". Khronos Group, OpenXR-SDK-Source. https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/main/src/tests/hello_xr/openxr_program_spatial_containers.cpp. Retrieved 2026-10-21.
  7. ↑ "XrSpatialContainerStateEXT: The state of a spatial container". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrSpatialContainerStateEXT.html. Retrieved 2026-10-21.
  8. ↑ "xrCreateSpatialContainerSpaceEXT: Create a space that is the origin of a spatial container". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/man/html/xrCreateSpatialContainerSpaceEXT.html. Retrieved 2026-10-21.
  9. ↑ "The OpenXR 1.1.65 Specification: Spaces". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#spaces. Retrieved 2026-10-21.
  10. ↑ Khronos OpenXR Working Group (2025-06-10). "OpenXR Spatial Entities Extensions Released for Developer Feedback". Khronos Group. https://www.khronos.org/blog/openxr-spatial-entities-extensions-released-for-developer-feedback. Retrieved 2026-10-21.
  11. ↑ "XrSpatialContainerViewStateEXT: View suitability information for a spatial container". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrSpatialContainerViewStateEXT.html. Retrieved 2026-10-21.
  12. ↑ 12.0 12.1 "XrSpatialContainerLayerVolumeClippingEXT: Specify what volume clipping an app has done when submitting layers". Khronos OpenXR Registry. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrSpatialContainerLayerVolumeClippingEXT.html. Retrieved 2026-10-21.