Preamble

Copyright (c) 2017-2023, The Khronos Group Inc.

This Specification is protected by copyright laws and contains material proprietary to Khronos. Except as described by these terms, it or any components may not be reproduced, republished, distributed, transmitted, displayed, broadcast or otherwise exploited in any manner without the express prior written permission of Khronos.

Khronos grants a conditional copyright license to use and reproduce the unmodified Specification for any purpose, without fee or royalty, EXCEPT no licenses to any patent, trademark or other intellectual property rights are granted under these terms.

Khronos makes no, and expressly disclaims any, representations or warranties, express or implied, regarding this Specification, including, without limitation: merchantability, fitness for a particular purpose, non-infringement of any intellectual property, correctness, accuracy, completeness, timeliness, and reliability. Under no circumstances will Khronos, or any of its Promoters, Contributors or Members, or their respective partners, officers, directors, employees, agents or representatives be liable for any damages, whether direct, indirect, special or consequential damages for lost revenues, lost profits, or otherwise, arising from or in connection with these materials.

This document contains extensions which are not ratified by Khronos, and as such is not a ratified Specification, though it contains text from (and is a superset of) the ratified OpenXR Specification that can be found at https://registry.khronos.org/OpenXR/specs/1.0-khr/html/xrspec.html (core with KHR extensions).

The Khronos Intellectual Property Rights Policy defines the terms 'Scope', 'Compliant Portion', and 'Necessary Patent Claims'.

Some parts of this Specification are purely informative and so are EXCLUDED from the Scope of this Specification. The Document Conventions section of the Introduction defines how these parts of the Specification are identified.

Where this Specification uses technical terminology, defined in the Glossary or otherwise, that refer to enabling technologies that are not expressly set forth in this Specification, those enabling technologies are EXCLUDED from the Scope of this Specification. For clarity, enabling technologies not disclosed with particularity in this Specification (e.g. semiconductor manufacturing technology, hardware architecture, processor architecture or microarchitecture, memory architecture, compiler technology, object oriented technology, basic operating system technology, compression technology, algorithms, and so on) are NOT to be considered expressly set forth; only those application program interfaces and data structures disclosed with particularity are included in the Scope of this Specification.

For purposes of the Khronos Intellectual Property Rights Policy as it relates to the definition of Necessary Patent Claims, all recommended or optional features, behaviors and functionality set forth in this Specification, if implemented, are considered to be included as Compliant Portions.

Khronos® and Vulkan® are registered trademarks, and glTF™ is a trademark of The Khronos Group Inc. OpenXR™ is a trademark owned by The Khronos Group Inc. and is registered as a trademark in China, the European Union, Japan and the United Kingdom. OpenGL® is a registered trademark and the OpenGL ES™ and OpenGL SC™ logos are trademarks of Hewlett Packard Enterprise used under license by Khronos. All other product names, trademarks, and/or company names are used solely for identification and belong to their respective owners.

1. Introduction

This chapter is informative except for the section on Normative Terminology.

This document, referred to as the "OpenXR Specification" or just the "Specification" hereafter, describes OpenXR: what it is, how it acts, and what is required to implement it. We assume that the reader has a basic understanding of computer graphics and the technologies involved in virtual and augmented reality. This means familiarity with the essentials of computer graphics algorithms and terminology, modern GPUs (Graphic Processing Units), tracking technologies, head mounted devices, and input modalities.

The canonical version of the Specification is available in the official OpenXR Registry, located at URL

1.1. What is OpenXR?

OpenXR is an API (Application Programming Interface) for XR applications. XR refers to a continuum of real-and-virtual combined environments generated by computers through human-machine interaction and is inclusive of the technologies associated with virtual reality (VR), augmented reality (AR) and mixed reality (MR). OpenXR is the interface between an application and an in-process or out-of-process "XR runtime system", or just "runtime" hereafter. The runtime may handle such functionality as frame composition, peripheral management, and raw tracking information.

Optionally, a runtime may support device layer plugins which allow access to a variety of hardware across a commonly defined interface.

1.2. The Programmer’s View of OpenXR

To the application programmer, OpenXR is a set of functions that interface with a runtime to perform commonly required operations such as accessing controller/peripheral state, getting current and/or predicted tracking positions, and submitting rendered frames.

A typical OpenXR program begins with a call to create an instance which establishes a connection to a runtime. Then a call is made to create a system which selects for use a physical display and a subset of input, tracking, and graphics devices. Subsequently a call is made to create buffers into which the application will render one or more views using the appropriate graphics APIs for the platform. Finally calls are made to create a session and begin the application’s XR rendering loop.

1.3. The Implementor’s View of OpenXR

To the runtime implementor, OpenXR is a set of functions that control the operation of the XR system and establishes the lifecycle of a XR application.

The implementor’s task is to provide a software library on the host which implements the OpenXR API, while mapping the work for each OpenXR function to the graphics hardware as appropriate for the capabilities of the device.

1.4. Our View of OpenXR

We view OpenXR as a mechanism for interacting with VR/AR/MR systems in a platform-agnostic way.

We expect this model to result in a specification that satisfies the needs of both programmers and runtime implementors. It does not, however, necessarily provide a model for implementation. A runtime implementation must produce results conforming to those produced by the specified methods, but may carry out particular procedures in ways that are more efficient than the one specified.

1.5. Filing Bug Reports

Issues with and bug reports on the OpenXR Specification and the API Registry can be filed in the Khronos OpenXR GitHub repository, located at URL

Please tag issues with appropriate labels, such as “Specification”, “Ref Pages” or “Registry”, to help us triage and assign them appropriately. Unfortunately, GitHub does not currently let users who do not have write access to the repository set GitHub labels on issues. In the meantime, they can be added to the title line of the issue set in brackets, e.g. “[Specification]”.

1.6. Document Conventions

The OpenXR specification is intended for use by both implementors of the API and application developers seeking to make use of the API, forming a contract between these parties. Specification text may address either party; typically the intended audience can be inferred from context, though some sections are defined to address only one of these parties. (For example, Valid Usage sections only address application developers). Any requirements, prohibitions, recommendations or options defined by normative terminology are imposed only on the audience of that text.

1.6.1. Normative Terminology

The key words must, required, should, may, and optional in this document, when denoted as above, are to be interpreted as described in RFC 2119:

must

When used alone, this word, or the term required, means that the definition is an absolute requirement of the specification. When followed by not (“must not” ), the phrase means that the definition is an absolute prohibition of the specification.

should

When used alone, this word means that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. When followed by not (“should not”), the phrase means that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.

may

This word, or the adjective optional, means that an item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances the product while another vendor may omit the same item.

The additional terms can and cannot are to be interpreted as follows:

can

This word means that the particular behavior described is a valid choice for an application, and is never used to refer to runtime behavior.

cannot

This word means that the particular behavior described is not achievable by an application, for example, an entry point does not exist.

There is an important distinction between cannot and must not, as used in this Specification. Cannot means something the application literally is unable to express or accomplish through the API, while must not means something that the application is capable of expressing through the API, but that the consequences of doing so are undefined and potentially unrecoverable for the runtime.

2. Fundamentals

2.1. API Version Numbers and Semantics

Multi-part version numbers are used in several places in the OpenXR API.

// Provided by XR_VERSION_1_0
typedef uint64_t XrVersion;

In each such use, the API major version number, minor version number, and patch version number are packed into a 64-bit integer, referred to as XrVersion, as follows:

Version Numbers
  • The major version number is a 16-bit integer packed into bits 63-48.

  • The minor version number is a 16-bit integer packed into bits 47-32.

  • The patch version number is a 32-bit integer packed into bits 31-0.

Differences in any of the version numbers indicate a change to the API, with each part of the version number indicating a different scope of change, as follows.

Note

The rules below apply to OpenXR versions 1.0 or later. Prerelease versions of OpenXR may use different rules for versioning.

A difference in patch version numbers indicates that some usually small part of the specification or header has been modified, typically to fix a bug, and may have an impact on the behavior of existing functionality. Differences in the patch version number must affect neither full compatibility nor backwards compatibility between two versions, nor may it add additional interfaces to the API. Runtimes may use patch version number to determine whether to enable implementation changes, such as bug fixes, that impact functionality. Runtimes should document any changes that are tied to the patch version. Application developers should retest their application on all runtimes they support after compiling with a new version.

A difference in minor version numbers indicates that some amount of new functionality has been added. This will usually include new interfaces in the header, and may also include behavior changes and bug fixes. Functionality may be deprecated in a minor revision, but must not be removed. When a new minor version is introduced, the patch version is reset to 0, and each minor revision maintains its own set of patch versions. Differences in the minor version number should not affect backwards compatibility, but will affect full compatibility.

A difference in major version numbers indicates a large set of changes to the API, potentially including new functionality and header interfaces, behavioral changes, removal of deprecated features, modification or outright replacement of any feature, and is thus very likely to break compatibility. Differences in the major version number will typically require significant modification to application code in order for it to function properly.

The following table attempts to detail the changes that may occur versus when they must not be updated (indicating the next version number must be updated instead) during an update to any of the major, minor, or patch version numbers:

Table 1. Scenarios Which May Cause a Version Change

Reason

Major Version

Minor Version

Patch Version

Extensions Added/Removed*

may

may

may

Spec-Optional Behavior Changed*

may

may

may

Spec Required Behavior Changed*

may

may

must not

Core Interfaces Added*

may

may

must not

Weak Deprecation*

may

may

must not

Strong Deprecation*

may

must not

must not

Core Interfaces Changed/Removed*

may

must not

must not

In the above table, the following identify the various cases in detail:

Extensions Added/Removed

An extension may be added or removed with a change at this patch level.

Specification-Optional Behavior Changed

Some optional behavior laid out in this specification has changed. Usually this will involve a change in behavior that is marked with the normatives should or may. For example, a runtime that previously did not validate a particular use case may now begin validating that use case.

Specification-Required Behavior Changed

A behavior of runtimes that is required by this specification may have changed. For example, a previously optional validation may now have become mandatory for runtimes.

Core Interfaces Added

New interfaces may have been added to this specification (and to the OpenXR header file) in revisions at this level.

Weak Deprecation

An interface may have been weakly deprecated at this level. This may happen if there is now a better way to accomplish the same thing. Applications making this call should behave the same as before the deprecation, but following the new path may be more performant, less latent, or otherwise yield better results. It is possible that some runtimes may choose to give run-time warnings that the feature has been weakly deprecated and will likely be strongly deprecated or removed in the future.

Strong Deprecation

An interface may have been strongly deprecated at this level. This means that the interface must still exist (so applications that are compiled against it will still run) but it may now be a no-op, or it may be that its behavior has been significantly changed. It may be that this functionality is no longer necessary, or that its functionality has been subsumed by another call. This should not break an application, but some behavior may be different or unanticipated.

Interfaces Changed/Removed

An interface may have been changed — with different parameters or return types — at this level. An interface or feature may also have been removed entirely. It is almost certain that rebuilding applications will be required.

2.2. String Encoding

This API uses strings as input and output for some functions. Unless otherwise specified, all such strings are NULL terminated UTF-8 encoded case-sensitive character arrays.

2.3. Threading Behavior

The OpenXR API is intended to provide scalable performance when used on multiple host threads. All functions must support being called concurrently from multiple threads, but certain parameters, or components of parameters are defined to be externally synchronized. This means that the caller must guarantee that no more than one thread is using such a parameter at a given time.

More precisely, functions use simple stores to update software structures representing objects. A parameter declared as externally synchronized may have its software structures updated at any time during the host execution of the function. If two functions operate on the same object and at least one of the functions declares the object to be externally synchronized, then the caller must guarantee not only that the functions do not execute simultaneously, but also that the two functions are separated by an appropriate memory barrier if needed.

For all functions which destroy an object handle, the application must externally synchronize the object handle parameter and any child handles.

Externally Synchronized Parameters
Implicit Externally Synchronized Parameters

2.4. Multiprocessing Behavior

The OpenXR API does not explicitly recognize nor require support for multiple processes using the runtime simultaneously, nor does it prevent a runtime from providing such support.

2.5. Runtime

An OpenXR runtime is software which implements the OpenXR API. There may be more than one OpenXR runtime installed on a system, but only one runtime can be active at any given time.

2.6. Extensions

OpenXR is an extensible API that grows through the addition of new features. Similar to other Khronos APIs, extensions may expose new OpenXR functions or modify the behavior of existing OpenXR functions. Extensions are optional and therefore must be enabled by the application before the extended functionality is made available. Because extensions are optional, they may be implemented only on a subset of runtimes, graphics platforms, or operating systems. Therefore, an application should first query which extensions are available before enabling.

The application queries the available list of extensions using the xrEnumerateInstanceExtensionProperties function. Once an application determines which target extensions are supported, it can enable some subset of them during the call to xrCreateInstance.

OpenXR extensions have unique names that convey information about what functionality is provided. The names have the following format:

Extension Name Formatting
  • The prefix "XR_" to identify this as an OpenXR extension

  • A string identifier for the vendor tag, which corresponds to the company or group exposing the extension. The vendor tag must use only uppercase letters and decimal digits. Some examples include:

    • "KHR" for Khronos extensions, supported by multiple vendors.

    • "EXT" for non-Khronos extensions supported by multiple vendors.

  • An underscore "_".

  • A string uniquely identifying the extension. The string is a compound of substrings which must use only lower case letters and decimal digits. The substrings are delimited with single underscores.

For example: XR_KHR_composition_layer_cube is an OpenXR extension created by the Khronos (KHR) OpenXR Working Group to support cube composition layers.

The public list of available extensions known at the time of this specification being generated appears in the List of Extensions appendix at the end of this document.

2.7. API Layers

OpenXR is designed to be a layered API, which means that a user or application may insert API layers between the application and the runtime implementation. These API layers provide additional functionality by intercepting OpenXR functions from the layer above and then performing different operations than would otherwise be performed without the layer. In the simplest cases, the layer simply calls the next layer down with the same arguments, but a more complex layer may implement API functionality that is not present in the layers or runtime below it. This mechanism is essentially an architected "function shimming" or "intercept" feature that is designed into OpenXR and meant to replace more informal methods of "hooking" API calls.

2.7.1. Examples of API Layers

Validation Layer

The layered API approach employed by OpenXR allows for the expensive validation of correct API usage to be implemented in a "validation" layer. This layer allows the application developer to develop their application with the validation layer active to ensure that the application is using the API correctly. The validation layer confirms that the application has set up object state correctly, has provided the required data for each function, ensures that required resources are available, etc. If the validation layer detects a problem, it issues an error message that can be logged or captured by the application via a callback. After the developer has determined that the application is correct, they turn off the validation layer to allow the application to run in a production environment without repeatedly incurring the validation expense.

API Logging Layer

Another example of an API layer is an API logging layer that simply serializes all the API calls to an output sink in a text format, including printing out argument values and structure contents.

API Trace Layer

A related API trace layer produces a trace file that contains all the information provided to the API so that the trace file can be played back by a replay program.

2.7.2. Naming API Layers

To organize API layer names and prevent collisions in the API layer name namespace, API layers must be named using the following convention:

XR_APILAYER_<VENDOR-TAG>_short_name

Vendors are responsible for registering a vendor tag with the OpenXR working group and just like for implementors, they must maintain their vendor namespace.

Example of an API layer name produced by the Acme company for the "check best practices" API layer:

XR_APILAYER_ACME_check_best_practices

2.7.3. Activating API Layers

Application Activation

Applications can determine the API layers that are available to them by calling the xrEnumerateApiLayerProperties function to obtain a list of available API layers. Applications then can select the desired API layers from this list and provide them to the xrCreateInstance function when creating an instance.

System Activation

Application users or users performing roles such as system integrator or system administrator may configure a system to activate API layers without involvement from the applications. These platform-dependent steps may include the installation of API layer-related files, setting environment variables, or other platform-specific operations. The options that are available for configuring the API layers in this manner are also dependent on the platform and/or runtime.

2.7.4. API Layer Extensions

API layers may implement OpenXR functions that may or may not be supported by the underlying runtime. In order to expose these new features, the API layer must expose this functionality in the form of an OpenXR extension. It must not expose new OpenXR functions without an associated extension.

For example, an OpenXR API-logging API layer might expose an API function to allow the application to turn logging on for only a portion of its execution. Since new functions must be exposed through an extension, the vendor has created an extension called XR_ACME_logging_on_off to contain these new functions. The application should query if the API layer supports the extension and then, only if it exists, enable both the extension and the API layer by name during xrCreateInstance.

To find out what extensions an API layer supports, an application must first verify that the API layer exists on the current system by calling xrEnumerateApiLayerProperties. After verifying an API layer of interest exists, the application then should call xrEnumerateInstanceExtensionProperties and provide the API layer name as the first parameter. This will return the list of extensions implemented internally in that API layer.

2.8. Type Aliasing

Type aliasing refers to the situation in which the actual type of a element does not match the declared type. Some C and C++ compilers can be configured to assume that the actual type matches the declared type, and may be so configured by default at common optimization levels. Without this, otherwise undefined behavior may occur. This compiler feature is typically referred to as "strict aliasing," and it can usually be enabled or disabled via compiler options. The OpenXR specification does not support strict aliasing, as there are some cases in which an application intentionally provides a struct with a type that differs from the declared type. For example, XrFrameEndInfo::layers is an array of type const XrCompositionLayerBaseHeader code:* const. However, the array must be of one of the specific layer types, such as XrCompositionLayerQuad. Similarly, xrEnumerateSwapchainImages accepts an array of XrSwapchainImageBaseHeader, whereas the actual type passed must be an array of a type such as XrSwapchainImageVulkanKHR.

For OpenXR to work correctly, the compiler must support the type aliasing described here.

// Provided by XR_VERSION_1_0
#if !defined(XR_MAY_ALIAS)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4))
#define XR_MAY_ALIAS __attribute__((__may_alias__))
#else
#define XR_MAY_ALIAS
#endif
#endif

As a convenience, some types and pointers that are known at specification time to alias values of different types have been annotated with the XR_MAY_ALIAS definition. If this macro is not defined before including OpenXR headers, and a new enough Clang or GCC compiler is used, it will be defined to the compiler-specific attribute annotation to inform these compilers that those pointers may alias. However, there is no guarantee that all aliasing types or pointers have been correctly marked with this macro, so thorough testing is still recommended if you choose (at your own risk) to permit your compiler to perform type-based aliasing analysis.

2.9. Valid Usage

Valid usage defines a set of conditions which must be met in order to achieve well-defined run-time behavior in an application. These conditions depend only on API state, and the parameters or objects whose usage is constrained by the condition.

Some valid usage conditions have dependencies on runtime limits or feature availability. It is possible to validate these conditions against the API’s minimum or maximum supported values for these limits and features, or some subset of other known values.

Valid usage conditions should apply to a function or structure where complete information about the condition would be known during execution of an application. This is such that a validation API layer or linter can be written directly against these statements at the point they are specified.

2.9.1. Implicit Valid Usage

Some valid usage conditions apply to all functions and structures in the API, unless explicitly denoted otherwise for a specific function or structure. These conditions are considered implicit. Implicit valid usage conditions are described in detail below.

2.9.2. Valid Usage for Object Handles

Any input parameter to a function that is an object handle must be a valid object handle, unless otherwise specified. An object handle is valid if and only if:

Object Handle Validity Conditions
  • it has been created or allocated by a previous, successful call to the API,

  • it has not been destroyed by a previous call to the API, and

  • its parent handle is also valid.

There are contexts in which an object handle is optional or otherwise unspecified. In those cases, the API uses XR_NULL_HANDLE, which has the integer value 0.

2.9.3. Valid Usage for Pointers

Any parameter that is a pointer must be a valid pointer when the specification indicates that the runtime uses the pointer. A pointer is valid if and only if it points at memory containing values of the number and type(s) expected by the function, and all fundamental types accessed through the pointer (e.g. as elements of an array or as members of a structure) satisfy the alignment requirements of the host processor.

2.9.4. Valid Usage for Enumerated Types

Any parameter of an enumerated type must be a valid enumerant for that type. An enumerant is valid if and only if the enumerant is defined as part of the enumerated type in question.

2.9.5. Valid Usage for Flags

A collection of flags is represented by a bitmask using the type XrFlags64:

typedef uint64_t XrFlags64;

Bitmasks are passed to many functions and structures to compactly represent options and are stored in memory defined by the XrFlags64 type. But the API does not use the XrFlags64 type directly. Instead, a Xr*Flags type is used which is an alias of the XrFlags64 type. The API also defines a set of constant bit definitions used to set the bitmasks.

Any Xr*Flags member or parameter used in the API must be a valid combination of bit flags. A valid combination is either zero or the bitwise OR of valid bit flags. A bit flag is valid if and only if:

Bit Flag Validity
  • The bit flag is one of the constant bit definitions defined by the same Xr*Flags type as the Xr*Flags member or parameter. Valid flag values may also be defined by extensions.

  • The flag is allowed in the context in which it is being used. For example, in some cases, certain bit flags or combinations of bit flags are mutually exclusive.

2.9.6. Valid Usage for Structure Types

Any parameter that is a structure containing a type member must have a value of type which is a valid XrStructureType value matching the type of the structure. As a general rule, the name of this value is obtained by taking the structure name, stripping the leading Xr, prefixing each capital letter with an underscore, converting the entire resulting string to upper case, and prefixing it with XR_TYPE_.

The only exceptions to this rule are API and Operating System names which are converted in a way that produces a more readable value:

Structure Type Format Exceptions
  • OpenGL ⇒ _OPENGL

  • OpenGLES ⇒ _OPENGL_ES

  • EGL ⇒ _EGL

  • D3D ⇒ _D3D

2.9.7. Valid Usage for Structure Pointer Chains

Any structure containing a void* next member must have a value of next that is either NULL, or points to a valid structure that also contains type and next member values. The set of structures connected by next pointers is referred to as a next chain.

In order to use a structure type defined by an extension in a next chain, the proper extension must have been previously enabled during xrCreateInstance. A runtime must ignore all unrecognized structures in a next chain, including those associated with an extension that has not been enabled.

Some structures for use in a chain are described in the core OpenXR specification and are mentioned in the Member Descriptions. Any structure described in this document intended for use in a chain is mentioned in a "See also" list in the implicit valid usage of the structure they chain to. Most chained structures are associated with extensions, and are described in the base OpenXR Specification under the List of Extensions. Vendor-specific extensions may be found there as well, or may only be available from the vendor’s website or internal document repositories.

Unless otherwise specified: Chained structs which are output structs may be modified by the runtime with the exception of the type and next fields. Upon return from any function, all type and next fields in the chain must be unmodified.

Useful Base Structures

As a convenience to runtimes and layers needing to iterate through a structure pointer chain, the OpenXR API provides the following base structures:

The XrBaseInStructure structure is defined as:

// Provided by XR_VERSION_1_0
typedef struct XrBaseInStructure {
    XrStructureType                    type;
    const struct XrBaseInStructure*    next;
} XrBaseInStructure;
Member Descriptions
  • type is the XrStructureType of this structure. This base structure itself has no associated XrStructureType value.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

XrBaseInStructure can be used to facilitate iterating through a read-only structure pointer chain.

The XrBaseOutStructure structure is defined as:

// Provided by XR_VERSION_1_0
typedef struct XrBaseOutStructure {
    XrStructureType               type;
    struct XrBaseOutStructure*    next;
} XrBaseOutStructure;
Member Descriptions
  • type is the XrStructureType of this structure. This base structure itself has no associated XrStructureType value.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

XrBaseOutStructure can be used to facilitate iterating through a structure pointer chain that returns data back to the application.

These structures allow for some type safety and can be used by OpenXR API functions that operate on generic inputs and outputs.

Next Chain Structure Uniqueness

Applications should ensure that they create and insert no more than one occurrence of each type of extension structure in a given next chain. Other components of OpenXR (such as the OpenXR loader or an API Layer) may insert duplicate structures into this chain. This provides those components the ability to update a structure that appears in the next chain by making a modified copy of that same structure and placing the new version at the beginning of the chain. The benefit of allowing this duplication is each component is no longer required to create a copy of the entire next chain just to update one structure. When duplication is present, all other OpenXR components must process only the first instance of a structure of a given type, and then ignore all instances of a structure of that same type.

If a component makes such a structure copy, and the original structure is also used to return content, then that component must copy the necessary content from the copied structure and into the original version of the structure upon completion of the function prior to proceeding back up the call stack. This is to ensure that OpenXR behavior is consistent whether or not that particular OpenXR component is present and/or enabled on the system.

2.9.8. Valid Usage for Nested Structures

The above conditions also apply recursively to members of structures provided as input to a function, either as a direct argument to the function, or themselves a member of another structure.

Specifics on valid usage of each function are covered in their individual sections.

2.10. Return Codes

The core API is designed to capture most, but not all, instances of incorrect usage. As such, most functions provide return codes. Functions in the API return their status via return codes that are in one of the two categories below.

Return Code Categories
  • Successful completion codes are returned when a function needs to communicate success or status information. All successful completion codes are non-negative values.

  • Run time error codes are returned when a function needs to communicate a failure that could only be detected at run time. All run time error codes are negative values.

typedef enum XrResult {
    XR_SUCCESS = 0,
    XR_TIMEOUT_EXPIRED = 1,
    XR_SESSION_LOSS_PENDING = 3,
    XR_EVENT_UNAVAILABLE = 4,
    XR_SPACE_BOUNDS_UNAVAILABLE = 7,
    XR_SESSION_NOT_FOCUSED = 8,
    XR_FRAME_DISCARDED = 9,
    XR_ERROR_VALIDATION_FAILURE = -1,
    XR_ERROR_RUNTIME_FAILURE = -2,
    XR_ERROR_OUT_OF_MEMORY = -3,
    XR_ERROR_API_VERSION_UNSUPPORTED = -4,
    XR_ERROR_INITIALIZATION_FAILED = -6,
    XR_ERROR_FUNCTION_UNSUPPORTED = -7,
    XR_ERROR_FEATURE_UNSUPPORTED = -8,
    XR_ERROR_EXTENSION_NOT_PRESENT = -9,
    XR_ERROR_LIMIT_REACHED = -10,
    XR_ERROR_SIZE_INSUFFICIENT = -11,
    XR_ERROR_HANDLE_INVALID = -12,
    XR_ERROR_INSTANCE_LOST = -13,
    XR_ERROR_SESSION_RUNNING = -14,
    XR_ERROR_SESSION_NOT_RUNNING = -16,
    XR_ERROR_SESSION_LOST = -17,
    XR_ERROR_SYSTEM_INVALID = -18,
    XR_ERROR_PATH_INVALID = -19,
    XR_ERROR_PATH_COUNT_EXCEEDED = -20,
    XR_ERROR_PATH_FORMAT_INVALID = -21,
    XR_ERROR_PATH_UNSUPPORTED = -22,
    XR_ERROR_LAYER_INVALID = -23,
    XR_ERROR_LAYER_LIMIT_EXCEEDED = -24,
    XR_ERROR_SWAPCHAIN_RECT_INVALID = -25,
    XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED = -26,
    XR_ERROR_ACTION_TYPE_MISMATCH = -27,
    XR_ERROR_SESSION_NOT_READY = -28,
    XR_ERROR_SESSION_NOT_STOPPING = -29,
    XR_ERROR_TIME_INVALID = -30,
    XR_ERROR_REFERENCE_SPACE_UNSUPPORTED = -31,
    XR_ERROR_FILE_ACCESS_ERROR = -32,
    XR_ERROR_FILE_CONTENTS_INVALID = -33,
    XR_ERROR_FORM_FACTOR_UNSUPPORTED = -34,
    XR_ERROR_FORM_FACTOR_UNAVAILABLE = -35,
    XR_ERROR_API_LAYER_NOT_PRESENT = -36,
    XR_ERROR_CALL_ORDER_INVALID = -37,
    XR_ERROR_GRAPHICS_DEVICE_INVALID = -38,
    XR_ERROR_POSE_INVALID = -39,
    XR_ERROR_INDEX_OUT_OF_RANGE = -40,
    XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED = -41,
    XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED = -42,
    XR_ERROR_NAME_DUPLICATED = -44,
    XR_ERROR_NAME_INVALID = -45,
    XR_ERROR_ACTIONSET_NOT_ATTACHED = -46,
    XR_ERROR_ACTIONSETS_ALREADY_ATTACHED = -47,
    XR_ERROR_LOCALIZED_NAME_DUPLICATED = -48,
    XR_ERROR_LOCALIZED_NAME_INVALID = -49,
    XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING = -50,
    XR_ERROR_RUNTIME_UNAVAILABLE = -51,
  // Provided by XR_KHR_android_thread_settings
    XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR = -1000003000,
  // Provided by XR_KHR_android_thread_settings
    XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR = -1000003001,
    XR_RESULT_MAX_ENUM = 0x7FFFFFFF
} XrResult;

All return codes in the API are reported via XrResult return values.

Some common suffixes shared across many of the return codes are defined below:

  • _INVALID: The specified handle, atom or value is formatted incorrectly, or the specified handle was never created or has been destroyed.

  • _UNSUPPORTED: The specified handle, atom, enumerant or value is formatted correctly but cannot be used for the lifetime of this function’s parent handle.

  • _UNAVAILABLE: The specified handle, atom, enumerant or value is supported by this function’s parent handle but not at this moment.

Success Codes

Enum Description

XR_SUCCESS

Function successfully completed.

XR_TIMEOUT_EXPIRED

The specified timeout time occurred before the operation could complete.

XR_SESSION_LOSS_PENDING

The session will be lost soon.

XR_EVENT_UNAVAILABLE

No event was available.

XR_SPACE_BOUNDS_UNAVAILABLE

The space’s bounds are not known at the moment.

XR_SESSION_NOT_FOCUSED

The session is not in the focused state.

XR_FRAME_DISCARDED

A frame has been discarded from composition.

Error Codes

Enum Description

XR_ERROR_VALIDATION_FAILURE

The function usage was invalid in some way.

XR_ERROR_RUNTIME_FAILURE

The runtime failed to handle the function in an unexpected way that is not covered by another error result.

XR_ERROR_OUT_OF_MEMORY

A memory allocation has failed.

XR_ERROR_API_VERSION_UNSUPPORTED

The runtime does not support the requested API version.

XR_ERROR_INITIALIZATION_FAILED

Initialization of object could not be completed.

XR_ERROR_FUNCTION_UNSUPPORTED

The requested function was not found or is otherwise unsupported.

XR_ERROR_FEATURE_UNSUPPORTED

The requested feature is not supported.

XR_ERROR_EXTENSION_NOT_PRESENT

A requested extension is not supported.

XR_ERROR_LIMIT_REACHED

The runtime supports no more of the requested resource.

XR_ERROR_SIZE_INSUFFICIENT

The supplied size was smaller than required.

XR_ERROR_HANDLE_INVALID

A supplied object handle was invalid.

XR_ERROR_INSTANCE_LOST

The XrInstance was lost or could not be found. It will need to be destroyed and optionally recreated.

XR_ERROR_SESSION_RUNNING

The session is already running.

XR_ERROR_SESSION_NOT_RUNNING

The session is not yet running.

XR_ERROR_SESSION_LOST

The XrSession was lost. It will need to be destroyed and optionally recreated.

XR_ERROR_SYSTEM_INVALID

The provided XrSystemId was invalid.

XR_ERROR_PATH_INVALID

The provided XrPath was not valid.

XR_ERROR_PATH_COUNT_EXCEEDED

The maximum number of supported semantic paths has been reached.

XR_ERROR_PATH_FORMAT_INVALID

The semantic path character format is invalid.

XR_ERROR_PATH_UNSUPPORTED

The semantic path is unsupported.

XR_ERROR_LAYER_INVALID

The layer was NULL or otherwise invalid.

XR_ERROR_LAYER_LIMIT_EXCEEDED

The number of specified layers is greater than the supported number.

XR_ERROR_SWAPCHAIN_RECT_INVALID

The image rect was negatively sized or otherwise invalid.

XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED

The image format is not supported by the runtime or platform.

XR_ERROR_ACTION_TYPE_MISMATCH

The API used to retrieve an action’s state does not match the action’s type.

XR_ERROR_SESSION_NOT_READY

The session is not in the ready state.

XR_ERROR_SESSION_NOT_STOPPING

The session is not in the stopping state.

XR_ERROR_TIME_INVALID

The provided XrTime was zero, negative, or out of range.

XR_ERROR_REFERENCE_SPACE_UNSUPPORTED

The specified reference space is not supported by the runtime or system.

XR_ERROR_FILE_ACCESS_ERROR

The file could not be accessed.

XR_ERROR_FILE_CONTENTS_INVALID

The file’s contents were invalid.

XR_ERROR_FORM_FACTOR_UNSUPPORTED

The specified form factor is not supported by the current runtime or platform.

XR_ERROR_FORM_FACTOR_UNAVAILABLE

The specified form factor is supported, but the device is currently not available, e.g. not plugged in or powered off.

XR_ERROR_API_LAYER_NOT_PRESENT

A requested API layer is not present or could not be loaded.

XR_ERROR_CALL_ORDER_INVALID

The call was made without having made a previously required call.

XR_ERROR_GRAPHICS_DEVICE_INVALID

The given graphics device is not in a valid state. The graphics device could be lost or initialized without meeting graphics requirements.

XR_ERROR_POSE_INVALID

The supplied pose was invalid with respect to the requirements.

XR_ERROR_INDEX_OUT_OF_RANGE

The supplied index was outside the range of valid indices.

XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

The specified view configuration type is not supported by the runtime or platform.

XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED

The specified environment blend mode is not supported by the runtime or platform.

XR_ERROR_NAME_DUPLICATED

The name provided was a duplicate of an already-existing resource.

XR_ERROR_NAME_INVALID

The name provided was invalid.

XR_ERROR_ACTIONSET_NOT_ATTACHED

A referenced action set is not attached to the session.

XR_ERROR_ACTIONSETS_ALREADY_ATTACHED

The session already has attached action sets.

XR_ERROR_LOCALIZED_NAME_DUPLICATED

The localized name provided was a duplicate of an already-existing resource.

XR_ERROR_LOCALIZED_NAME_INVALID

The localized name provided was invalid.

XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING

The xrGetGraphicsRequirements* call was not made before calling xrCreateSession.

XR_ERROR_RUNTIME_UNAVAILABLE

The loader was unable to find or load a runtime.

XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR

xrSetAndroidApplicationThreadKHR failed as thread id is invalid. (Added by the XR_KHR_android_thread_settings extension)

XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR

xrSetAndroidApplicationThreadKHR failed setting the thread attributes/priority. (Added by the XR_KHR_android_thread_settings extension)

2.10.1. Convenience Macros

// Provided by XR_VERSION_1_0
#define XR_SUCCEEDED(result) ((result) >= 0)

A convenience macro that can be used to test if a function succeeded. This may be a qualified success such as XR_FRAME_DISCARDED.

// Provided by XR_VERSION_1_0
#define XR_FAILED(result) ((result) < 0)

A convenience macro that can be used to test if a function has failed in some way.

// Provided by XR_VERSION_1_0
#define XR_UNQUALIFIED_SUCCESS(result) ((result) == 0)

A convenience macro that can be used to test a function’s failure. The XR_UNQUALIFIED_SUCCESS macro is a convenience macro which may be used to compare an XrResult to 0 (XR_SUCCESS) exclusively.

2.10.2. Validation

Except as noted below or in individual API specifications, valid API usage may be required by the runtime. Runtimes may choose to validate some API usage and return an appropriate error code.

Application developers should use validation layers to catch and eliminate errors during development. Once validated, applications should not enable validation layers by default.

If a function returns a run time error, unless otherwise specified any output parameters will have undefined contents, except that if the output parameter is a structure with type and next fields, those fields will be unmodified. Any output structures chained from next will also have undefined contents, except that the type and next will be unmodified.

Unless otherwise specified, errors do not affect existing OpenXR objects. Objects that have already been successfully created may still be used by the application.

XrResult code returns may be added to a given function in future versions of the specification. Runtimes must return only XrResult codes from the set documented for the given application API version.

Runtimes must ensure that incorrect usage by an application does not affect the integrity of the operating system, the API implementation, or other API client applications in the system, and does not allow one application to access data belonging to another application.

2.11. Handles

Objects which are allocated by the runtime on behalf of applications are represented by handles. Handles are opaque identifiers for objects whose lifetime is controlled by applications via the create and destroy functions. Example handle types include XrInstance, XrSession, and XrSwapchain. Handles which have not been destroyed are unique for a given application process, but may be reused after being destroyed. Unless otherwise specified, a successful handle creation function call returns a new unique handle. Unless otherwise specified, handles are implicitly destroyed when their parent handle is destroyed. Applications may destroy handles explicitly before the parent handle is destroyed, and should do so if no longer needed, in order to conserve resources. Runtimes may detect XR_NULL_HANDLE and other invalid handles passed where a valid handle is required and return XR_ERROR_HANDLE_INVALID. However, runtimes are not required to do so unless otherwise specified, and so use of any invalid handle may result in undefined behavior. When a function has an optional handle parameter, XR_NULL_HANDLE must be used unless passing a valid handle.

All functions that take a handle parameter may return XR_ERROR_HANDLE_INVALID.

Handles form a hierarchy in which child handles fall under the validity and lifetime of parent handles. For example, to create an XrSwapchain handle, applications must call xrCreateSwapchain and pass an XrSession handle. Thus XrSwapchain is a child handle to XrSession.

2.12. Object Handle Types

The type of an object handle used in a function is usually determined by the specification of that function, as discussed in Valid Usage for Object Handles. However, some functions accept or return object handle parameters where the type of the object handle is unknown at execution time and is not specified in the description of the function itself. For these functions, the XrObjectType may be used to explicitly specify the type of a handle.

For example, an information-gathering or debugging mechanism implemented in a runtime extension or API layer extension may return a list of object handles that are generated by the mechanism’s operation. The same mechanism may also return a parallel list of object handle types that allow the recipient of this information to easily determine the types of the handles.

In general, anywhere an object handle of more than one type can occur, the object handle type may be provided to indicate its type.

// Provided by XR_VERSION_1_0
typedef enum XrObjectType {
    XR_OBJECT_TYPE_UNKNOWN = 0,
    XR_OBJECT_TYPE_INSTANCE = 1,
    XR_OBJECT_TYPE_SESSION = 2,
    XR_OBJECT_TYPE_SWAPCHAIN = 3,
    XR_OBJECT_TYPE_SPACE = 4,
    XR_OBJECT_TYPE_ACTION_SET = 5,
    XR_OBJECT_TYPE_ACTION = 6,
    XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
} XrObjectType;

The XrObjectType enumeration defines values, each of which corresponds to a specific OpenXR handle type. These values can be used to associate debug information with a particular type of object through one or more extensions.

The following table defines XrObjectType and OpenXR Handle relationships:

XrObjectType OpenXR Handle Type

XR_OBJECT_TYPE_UNKNOWN

Unknown/Undefined Handle

XR_OBJECT_TYPE_INSTANCE

XrInstance

XR_OBJECT_TYPE_SESSION

XrSession

XR_OBJECT_TYPE_SWAPCHAIN

XrSwapchain

XR_OBJECT_TYPE_SPACE

XrSpace

XR_OBJECT_TYPE_ACTION_SET

XrActionSet

XR_OBJECT_TYPE_ACTION

XrAction

2.13. Buffer Size Parameters

Functions with input/output buffer parameters take on either parameter form or struct form, looking like one of the following examples, with the element type being float in this case:

Parameter form:

XrResult xrFunction(uint32_t elementCapacityInput, uint32_t* elementCountOutput, float* elements);

Struct form:

XrResult xrFunction(XrBuffer* buffer);

struct XrBuffer {
    uint32_t              elementCapacityInput;
    uint32_t              elementCountOutput;
    float*                elements;
};

A two-call idiom may be employed, first calling xrFunction (with a valid elementCountOutput pointer if in parameter form), but passing NULL as elements and 0 as elementCapacityInput, to retrieve the required buffer size as number of elements (number of floats in this example). After allocating a buffer at least as large as elementCountOutput (in a struct) or the value pointed to by elementCountOutput (as parameters), a pointer to the allocated buffer should be passed as elements, along with the buffer’s length in elementCapacityInput, to a second call to xrFunction to perform the retrieval of the data. In case that elements is a struct with type and next fields, the application must set the type to the correct value as well as next either to NULL or a struct with extension related data in which type and next also need to be well defined.

In the following discussion, "set elementCountOutput" should be interpreted as "set the value pointed to by elementCountOutput" in parameter form and "set the value of elementCountOutput" in struct form. These functions have the below-listed behavior with respect to the buffer size parameters:

Buffer Size Parameter Behavior
  • The element capacity and count arguments precede the array to which they refer, in argument order.

  • elementCapacityInput specifies the capacity in number of elements of the buffer to be written, or 0 to indicate a request for the required buffer size.

  • Independent of elementCapacityInput or elements parameters, the function sets elementCountOutput. elementCountOutput must be a valid pointer if the function uses parameter form.

  • It is valid to pass 0 for the elementCapacityInput parameter (i.e. capacity of 0 does not return XR_ERROR_SIZE_INSUFFICIENT). The function sets elementCountOutput to the required size in number of elements.

  • If 0 is passed for the elementCapacityInput parameter, the elements parameter is ignored (any value passed is considered valid usage).

  • Where the elementCapacityInput is non-zero but less than required, the function sets elementCountOutput to the required capacity, and must return XR_ERROR_SIZE_INSUFFICIENT. The data in the array elements is undefined.

  • Where the elementCapacityInput is non-zero and the function returns successfully, the function sets elementCountOutput to the count of the elements that have been written to elements.

  • Upon a failure for reasons unrelated to the element array capacity, the contents of the values pointed to by elementCountOutput and elements are undefined.

  • In the case that the element array refers to a string (is of type char*), elementCapacityInput and elementCountOutput refer to the string strlen plus 1 for a NULL terminator.

Some functions fill multiple buffers in one call. For these functions, the elementCapacityInput, elementCountOutput and elements parameters or fields are repeated, once per buffer, with different prefixes. In that case, the semantics above still apply, with the additional behavior that if any elementCapacityInput parameter or field is set to 0 by the application, the runtime must treat all elementCapacityInput values as if they were set to 0. If any elementCapacityInput value is too small to fit all elements of the buffer, XR_ERROR_SIZE_INSUFFICIENT must be returned, and the data in all buffers is undefined.

2.14. Time

Time is represented by a 64-bit signed integer representing nanoseconds (XrTime). The passage of time must be monotonic and not real-time (i.e. wall clock time). Thus the time is always increasing at a constant rate and is unaffected by clock changes, time zones, daylight savings, etc.

2.14.1. XrTime

typedef int64_t XrTime;

XrTime is a base value type that represents time as a signed 64-bit integer, representing the monotonically-increasing count of nanoseconds that have elapsed since a runtime-chosen epoch. XrTime always represents the time elapsed since that constant epoch, rather than a duration or a time point relative to some moving epoch such as vsync time, etc. Durations are instead represented by XrDuration.

A single runtime must use the same epoch for all simultaneous applications. Time must be represented the same regardless of multiple processors or threads present in the system.

The period precision of time reported by the runtime is runtime-dependent, and may change. One nanosecond is the finest possible period precision. A runtime may, for example, report time progression with only microsecond-level granularity.

Time must not be assumed to correspond to a system clock time.

Unless specified otherwise, zero or a negative value is not a valid XrTime, and related functions must return error XR_ERROR_TIME_INVALID. Applications must not initialize such XrTime fields to a zero value. Instead, applications should always assign XrTime fields to the meaningful point in time they are choosing to reason about, such as a frame’s predicted display time, or an action’s last change time.

The behavior of a runtime is undefined when time overflows beyond the maximum positive value that can be represented by an XrTime. Runtimes should choose an epoch that minimizes the chance of overflow. Runtimes should also choose an epoch that minimizes the chance of underflow below 0 for applications performing a reasonable amount of historical pose lookback. For example, if the runtime chooses an epoch relative to its startup time, it should push the epoch into the past by enough time to avoid applications performing reasonable pose lookback from reaching a negative XrTime value.

An application cannot assume that the system’s clock and the runtime’s clock will maintain a constant relationship across frames and should avoid storing such an offset, as this may cause time drift. Applications should instead always use time interop functions to convert a relevant time point across the system’s clock and the runtime’s clock using extensions, for example, XR_KHR_win32_convert_performance_counter_time or XR_KHR_convert_timespec_time.

2.15. Duration

Duration refers to an elapsed period of time, as opposed to an absolute timepoint.

2.15.1. XrDuration

typedef int64_t XrDuration;

The difference between two timepoints is a duration, and thus the difference between two XrTime values is an XrDuration value.

Functions that refer to durations use XrDuration as opposed to XrTime.

// Provided by XR_VERSION_1_0
#define XR_NO_DURATION 0

For the case of timeout durations, XR_NO_DURATION may be used to indicate that the timeout is immediate.

// Provided by XR_VERSION_1_0
#define XR_INFINITE_DURATION 0x7fffffffffffffffLL

XR_INFINITE_DURATION is a special value that may be used to indicate that the timeout never occurs. A timeout with a duration that refers to the past has the same effect as a timeout of XR_NO_DURATION.

2.16. Prediction Time Limits

Some functions involve prediction. For example, xrLocateViews accepts a display time for which to return the resulting data. Prediction times provided by applications may refer to time in the past or the future. Times in the past may be interpolated historical data. Runtimes have different practical limits with respect to how far forward or backward prediction times can be accurate. There is no prescribed forward limit the application can successfully request predictions for, though predictions may become less accurate as they get farther into the future. With respect to backward prediction, the application can pass a prediction time equivalent to the timestamp of the most recently received pose plus as much as 50 milliseconds in the past to retrieve accurate historical data. Requested times predating this time window, or requested times predating the earliest received pose, may result in a best effort data whose accuracy reduced or unspecified.

2.17. Colors

The XrColor4f structure is defined as:

// Provided by XR_VERSION_1_0
typedef struct XrColor4f {
    float    r;
    float    g;
    float    b;
    float    a;
} XrColor4f;
Member Descriptions
  • r is the red component of the color.

  • g is the green component of the color.

  • b is the blue component of the color.

  • a is the alpha component of the color.

Unless otherwise specified, colors are encoded as linear (not with sRGB nor other gamma compression) values with individual components being in the range of 0.0 through 1.0, and without the RGB components being premultiplied by the alpha component.

If color encoding is specified as being premultiplied by the alpha component, the RGB components are set to zero if the alpha component is zero.

2.18. Coordinate System

This API uses a Cartesian right-handed coordinate system.

right handed
Figure 1. Right Handed Coordinate System

The conventions for mapping coordinate axes of any particular space to meaningful directions depend on and are documented with the description of the space.

The API uses 2D, 3D, and 4D floating-point vectors to describe points and directions in a space.

A two-dimensional vector is defined by the XrVector2f structure:

typedef struct XrVector2f {
    float    x;
    float    y;
} XrVector2f;
Member Descriptions
  • x is the x coordinate of the vector.

  • y is the y coordinate of the vector.

If used to represent physical distances (rather than e.g. normalized direction) and not otherwise specified, values must be in meters.

A three-dimensional vector is defined by the XrVector3f structure:

typedef struct XrVector3f {
    float    x;
    float    y;
    float    z;
} XrVector3f;
Member Descriptions
  • x is the x coordinate of the vector.

  • y is the y coordinate of the vector.

  • z is the z coordinate of the vector.

If used to represent physical distances (rather than e.g. velocity or angular velocity) and not otherwise specified, values must be in meters.

A four-dimensional or homogeneous vector is defined by the XrVector4f structure:

// Provided by XR_VERSION_1_0
typedef struct XrVector4f {
    float    x;
    float    y;
    float    z;
    float    w;
} XrVector4f;
Member Descriptions
  • x is the x coordinate of the vector.

  • y is the y coordinate of the vector.

  • z is the z coordinate of the vector.

  • w is the w coordinate of the vector.

If used to represent physical distances, x, y, and z values must be in meters.

Rotation is represented by a unit quaternion defined by the XrQuaternionf structure:

typedef struct XrQuaternionf {
    float    x;
    float    y;
    float    z;
    float    w;
} XrQuaternionf;
Member Descriptions
  • x is the x coordinate of the quaternion.

  • y is the y coordinate of the quaternion.

  • z is the z coordinate of the quaternion.

  • w is the w coordinate of the quaternion.

A pose is defined by the XrPosef structure:

typedef struct XrPosef {
    XrQuaternionf    orientation;
    XrVector3f       position;
} XrPosef;
Member Descriptions
  • orientation is an XrQuaternionf representing the orientation within a space.

  • position is an XrVector3f representing position within a space.

A construct representing a position and orientation within a space, with position expressed in meters, and orientation represented as a unit quaternion. When using XrPosef the rotation described by orientation is always applied before the translation described by position.

A runtime must return XR_ERROR_POSE_INVALID if the orientation norm deviates by more than 1% from unit length.

2.19. Common Object Types

Some types of OpenXR objects are used in multiple structures. Those include the XrVector*f and types specified above but also the following structures: offset, extents and rectangle.

Offsets are used to describe the magnitude of an offset in two dimensions.

A floating-point offset is defined by the structure:

// Provided by XR_VERSION_1_0
typedef struct XrOffset2Df {
    float    x;
    float    y;
} XrOffset2Df;
Member Descriptions
  • x the floating-point offset in the x direction.

  • y the floating-point offset in the y direction.

This structure is used for component values that may be fractional (floating-point). If used to represent physical distances, values must be in meters.

An integer offset is defined by the structure:

typedef struct XrOffset2Di {
    int32_t    x;
    int32_t    y;
} XrOffset2Di;
Member Descriptions
  • x the integer offset in the x direction.

  • y the integer offset in the y direction.

This variant is for representing discrete values such as texels. For representing physical distances, the floating-point variant must be used instead.

Extents are used to describe the size of a rectangular region in two dimensions.

A two-dimensional floating-point extent is defined by the structure:

// Provided by XR_VERSION_1_0
typedef struct XrExtent2Df {
    float    width;
    float    height;
} XrExtent2Df;
Member Descriptions
  • width the floating-point width of the extent.

  • height the floating-point height of the extent.

This structure is used for component values that may be fractional (floating-point). If used to represent physical distances, values must be in meters.

The width and height value must be non-negative.

A two-dimensional integer extent is defined by the structure:

typedef struct XrExtent2Di {
    int32_t    width;
    int32_t    height;
} XrExtent2Di;
Member Descriptions
  • width the integer width of the extent.

  • height the integer height of the extent.

This variant is for representing discrete values such as texels. For representing physical distances, the floating-point variant must be used instead.

The width and height value must be non-negative.

Rectangles are used to describe a specific rectangular region in two dimensions. Rectangles must include both an offset and an extent defined in the same units. For instance, if a rectangle is in meters, both offset and extent must be in meters.

A rectangle with floating-point values is defined by the structure:

// Provided by XR_VERSION_1_0
typedef struct XrRect2Df {
    XrOffset2Df    offset;
    XrExtent2Df    extent;
} XrRect2Df;
Member Descriptions
  • offset is the XrOffset2Df specifying the rectangle offset.

  • extent is the XrExtent2Df specifying the rectangle extent.

This structure is used for component values that may be fractional (floating-point).

The offset is the position of the rectangle corner with minimum value coordinates. The other three corners are computed by adding the XrExtent2Di::width to the x offset, XrExtent2Di::height to the y offset, or both.

A rectangle with integer values is defined by the structure:

typedef struct XrRect2Di {
    XrOffset2Di    offset;
    XrExtent2Di    extent;
} XrRect2Di;
Member Descriptions
  • offset is the XrOffset2Di specifying the integer rectangle offset.

  • extent is the XrExtent2Di specifying the integer rectangle extent.

This variant is for representing discrete values such as texels. For representing physical distances, the floating-point variant must be used instead.

The offset is the position of the rectangle corner with minimum value coordinates. The other three corners are computed by adding the XrExtent2Di::width to the x offset, XrExtent2Di::height to the y offset, or both.

2.20. Angles

Where a value is provided as a function parameter or as a structure member and will be interpreted as an angle, the value is defined to be in radians.

Field of view (FoV) is defined by the structure:

typedef struct XrFovf {
    float    angleLeft;
    float    angleRight;
    float    angleUp;
    float    angleDown;
} XrFovf;
Member Descriptions
  • angleLeft is the angle of the left side of the field of view. For a symmetric field of view this value is negative.

  • angleRight is the angle of the right side of the field of view.

  • angleUp is the angle of the top part of the field of view.

  • angleDown is the angle of the bottom part of the field of view. For a symmetric field of view this value is negative.

Angles to the right of the center and upwards from the center are positive, and angles to the left of the center and down from the center are negative. The total horizontal field of view is angleRight minus angleLeft, and the total vertical field of view is angleUp minus angleDown. For a symmetric FoV, angleRight and angleUp will have positive values, angleLeft will be -angleRight, and angleDown will be -angleUp.

The angles must be specified in radians, and must be between -π/2 and π/2 exclusively.

When angleLeft > angleRight, the content of the view must be flipped horizontally. When angleDown > angleUp, the content of the view must be flipped vertically.

2.21. Boolean Values

typedef uint32_t XrBool32;

Boolean values used by OpenXR are of type XrBool32 and are 32-bits wide as suggested by the name. The only valid values are the following:

Enumerant Descriptions
  • XR_TRUE represents a true value.

  • XR_FALSE represents a false value.

#define XR_TRUE                           1

#define XR_FALSE                          0

2.22. Events

Events are messages sent from the runtime to the application.

2.22.1. Event Polling

These events are placed in a queue and the application must read from the queue with regularity. Events are read from the queue one at a time via xrPollEvent. Every event is identified by an individual struct, with each struct beginning with an XrEventDataBaseHeader.

Example 1. Proper Method for Receiving OpenXR Event Data
XrInstance instance; // previously initialized

// Initialize an event buffer to hold the output.
XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
XrResult result = xrPollEvent(instance, &event);
if (result == XR_SUCCESS) {
    switch (event.type) {
        case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
            const XrEventDataSessionStateChanged& session_state_changed_event =
            	*reinterpret_cast<XrEventDataSessionStateChanged*>(&event);
            // ...
            break;
        }
        case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
            const XrEventDataInstanceLossPending& instance_loss_pending_event =
            	*reinterpret_cast<XrEventDataInstanceLossPending*>(&event);
            // ...
            break;
        }
    }
}
xrPollEvent

// Provided by XR_VERSION_1_0
XrResult xrPollEvent(
    XrInstance                                  instance,
    XrEventDataBuffer*                          eventData);

xrPollEvent polls for the next event and returns an event if one is available. xrPollEvent returns immediately regardless of whether an event was available. The event (if present) is unilaterally removed from the queue if a valid XrInstance is provided. On return the eventData parameter is filled with the event’s data and the type field is changed to the event’s type. Runtimes may create valid next chains depending on enabled extensions, but they must guarantee that any such chains point only to objects which fit completely within the original XrEventDataBuffer pointed to by eventData.

Parameter Descriptions
Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

  • XR_EVENT_UNAVAILABLE

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

The runtime must discard queued events which contain destroyed or otherwise invalid handles.

Table 2. Event Descriptions
Event Description

XrEventDataEventsLost

event queue has overflowed and some events were lost

XrEventDataInstanceLossPending

application is about to lose the instance

XrEventDataInteractionProfileChanged

active input form factor for one or more top level user paths has changed

XrEventDataReferenceSpaceChangePending

runtime will begin operating with updated space bounds

XrEventDataSessionStateChanged

application has changed lifecycle state

The XrEventDataBaseHeader structure is defined as:

// Provided by XR_VERSION_1_0
typedef struct XrEventDataBaseHeader {
    XrStructureType    type;
    const void*        next;
} XrEventDataBaseHeader;
Parameter Descriptions
  • type is the XrStructureType of this structure. This base structure itself has no associated XrStructureType value.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

The XrEventDataBaseHeader is a generic structure used to identify the common event data elements.

Upon receipt, the XrEventDataBaseHeader pointer should be type-cast to a pointer of the appropriate event data based on the type parameter.

Valid Usage (Implicit)
  • type must be one of the following XrStructureType values: XR_TYPE_EVENT_DATA_EVENTS_LOST, XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING, XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED, XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING, XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR

  • next must be NULL or a valid pointer to the next structure in a structure chain

The XrEventDataBuffer is a structure passed to xrPollEvent large enough to contain any returned event data element. The maximum size is specified by XR_MAX_EVENT_DATA_SIZE.

It is sufficient to clear the type and next parameters of an XrEventDataBuffer when passing it as an input to xrPollEvent.

An XrEventDataBuffer may be type-cast to an XrEventDataBaseHeader pointer or a pointer to any other appropriate event data based on the type parameter.

typedef struct XrEventDataBuffer {
    XrStructureType    type;
    const void*        next;
    uint8_t            varying[4000];
} XrEventDataBuffer;
Parameter Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • varying is a fixed sized output buffer big enough to hold returned data elements for all specified event data types.

Valid Usage (Implicit)

XR_MAX_EVENT_DATA_SIZE is the maximum size of an XrEventDataBuffer.

// Provided by XR_VERSION_1_0
#define XR_MAX_EVENT_DATA_SIZE sizeof(XrEventDataBuffer)
XrEventDataEventsLost

The XrEventDataEventsLost structure is defined as:

// Provided by XR_VERSION_1_0
typedef struct XrEventDataEventsLost {
    XrStructureType    type;
    const void*        next;
    uint32_t           lostEventCount;
} XrEventDataEventsLost;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • lostEventCount is the number of events which have overflowed since the last call to xrPollEvent.

Receiving the XrEventDataEventsLost event structure indicates that the event queue overflowed and some events were removed at the position within the queue at which this event was found.

Valid Usage (Implicit)

Other event structures are defined in later chapters in the context where their definition is most relevant.

2.23. System resource lifetime

The creator of an underlying system resource is responsible for ensuring the resource’s lifetime matches the lifetime of the associated OpenXR handle.

Resources passed as inputs from the application to the runtime when creating an OpenXR handle should not be freed while that handle is valid. A runtime must not free resources passed as inputs or decrease their reference counts (if applicable) from the initial value. For example, the graphics device handle (or pointer) passed in to xrCreateSession in XrGraphicsBinding* structure should be kept alive when the corresponding XrSession handle is valid, and should be freed by the application after the XrSession handle is destroyed.

Resources created by the runtime should not be freed by the application, and the application should maintain the same reference count (if applicable) at the destruction of the OpenXR handle as it had at its creation. For example, the ID3D*Texture2D objects in the XrSwapchainImageD3D* are created by the runtime and associated with the lifetime of the XrSwapchain handle. The application should not keep additional reference counts on any ID3D*Texture2D objects past the lifetime of the XrSwapchain handle, or make extra reference count decrease after destroying the XrSwapchain handle.

3. API Initialization

Before using an OpenXR runtime, an application must initialize it by creating an XrInstance object. The following functions are useful for gathering information about the API layers and extensions installed on the system and creating the instance.

3.1. Exported Functions

A dynamically linked library (.dll or .so) that implements the API loader must export all core OpenXR API functions. However, the application can gain access to extension functions by obtaining pointers to these functions through the use of xrGetInstanceProcAddr.

3.2. Function Pointers

Function pointers for all OpenXR functions can be obtained with the function xrGetInstanceProcAddr.

// Provided by XR_VERSION_1_0
XrResult xrGetInstanceProcAddr(
    XrInstance                                  instance,
    const char*                                 name,
    PFN_xrVoidFunction*                         function);
Parameter Descriptions
  • instance is the instance that the function pointer will be compatible with, or NULL for functions not dependent on any instance.

  • name is the name of the function to obtain.

  • function is the address of the function pointer to get.

xrGetInstanceProcAddr itself is obtained in a platform- and loader- specific manner. Typically, the loader library will export this function as a function symbol, so applications can link against the loader library, or load it dynamically and look up the symbol using platform-specific APIs. Loaders must export function symbols for all core OpenXR functions. Because of this, applications that use only the core OpenXR functions have no need to use xrGetInstanceProcAddr.

Because an application can call xrGetInstanceProcAddr before creating an instance, xrGetInstanceProcAddr returns a valid function pointer when the instance parameter is XR_NULL_HANDLE and the name parameter is one of the following strings:

xrGetInstanceProcAddr must return XR_ERROR_HANDLE_INVALID if name is not one of the above strings and instance is XR_NULL_HANDLE. xrGetInstanceProcAddr may return XR_ERROR_HANDLE_INVALID if name is not one of the above strings and instance is invalid but not XR_NULL_HANDLE.

xrGetInstanceProcAddr must return XR_ERROR_FUNCTION_UNSUPPORTED if instance is a valid instance and the string specified in name is not the name of an OpenXR core or enabled extension function.

If name is the name of an extension function, then the result returned by xrGetInstanceProcAddr will depend upon how the instance was created. If instance was created with the related extension’s name appearing in the XrInstanceCreateInfo::enabledExtensionNames array, then xrGetInstanceProcAddr returns a valid function pointer. If the related extension’s name did not appear in the XrInstanceCreateInfo::enabledExtensionNames array during the creation of instance, then xrGetInstanceProcAddr returns XR_ERROR_FUNCTION_UNSUPPORTED. Because of this, function pointers returned by xrGetInstanceProcAddr using one XrInstance may not be valid when used with objects related to a different XrInstance.

The returned function pointer is of type PFN_xrVoidFunction, and must be cast to the type of the function being queried.

The table below defines the various use cases for xrGetInstanceProcAddr and return value (“fp” is “function pointer”) for each case.

Table 3. xrGetInstanceProcAddr behavior
instance parameter name parameter return value

*

NULL

undefined

invalid instance

*

undefined

NULL

xrEnumerateInstanceExtensionProperties

fp

NULL

xrEnumerateApiLayerProperties

fp

NULL

xrCreateInstance

fp

NULL

* (any name not covered above)

NULL

instance

core OpenXR function

fp1

instance

enabled extension function for instance

fp1

instance

* (any name not covered above)

NULL

1

The returned function pointer must only be called with a handle (the first parameter) that is instance or a child of instance.

Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_FUNCTION_UNSUPPORTED

  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

  • XR_ERROR_OUT_OF_MEMORY

typedef void (XRAPI_PTR *PFN_xrVoidFunction)(void);
Parameter Descriptions
  • no parameters.

PFN_xrVoidFunction is a generic function pointer type returned by queries, specifically those to xrGetInstanceProcAddr.

4. Instance

XR_DEFINE_HANDLE(XrInstance)

An OpenXR instance is an object that allows an OpenXR application to communicate with an OpenXR runtime. The application accomplishes this communication by calling xrCreateInstance and receiving a handle to the resulting XrInstance object.

The XrInstance object stores and tracks OpenXR-related application state, without storing any such state in the application’s global address space. This allows the application to create multiple instances as well as safely encapsulate the application’s OpenXR state since this object is opaque to the application. OpenXR runtimes may limit the number of simultaneous XrInstance objects that may be created and used, but they must support the creation and usage of at least one XrInstance object per process.

Physically, this state may be stored in any of the OpenXR loader, OpenXR API layers or the OpenXR runtime components. The exact storage and distribution of this saved state is implementation-dependent, except where indicated by this specification.

The tracking of OpenXR state in the instance allows the streamlining of the API, where the intended instance is inferred from the highest ascendant of an OpenXR function’s target object. For example, in:

myResult = xrEndFrame(mySession, &myEndFrameDescription);

the XrSession object was created from an XrInstance object. The OpenXR loader typically keeps track of the XrInstance that is the parent of the XrSession object in this example and directs the function to the runtime associated with that instance. This tracking of OpenXR objects eliminates the need to specify an XrInstance in every OpenXR function.

4.1. API Layers and Extensions

Additional functionality may be provided by API layers or extensions. An API layer must not add or modify the definition of OpenXR functions, while an extension may do so.

The set of API layers to enable is specified when creating an instance, and those API layers are able to intercept any functions dispatched to that instance or any of its child objects.

Example API layers may include (but are not limited to):

  • an API layer to dump out OpenXR API calls

  • an API layer to perform OpenXR validation

To determine what set of API layers are available, OpenXR provides the xrEnumerateApiLayerProperties function:

// Provided by XR_VERSION_1_0
XrResult xrEnumerateApiLayerProperties(
    uint32_t                                    propertyCapacityInput,
    uint32_t*                                   propertyCountOutput,
    XrApiLayerProperties*                       properties);
Parameter Descriptions
  • propertyCapacityInput is the capacity of the properties array, or 0 to indicate a request to retrieve the required capacity.

  • propertyCountOutput is a pointer to the count of properties written, or a pointer to the required capacity in the case that propertyCapacityInput is insufficient.

  • properties is a pointer to an array of XrApiLayerProperties structures, but can be NULL if propertyCapacityInput is 0.

  • See the Buffer Size Parameters section for a detailed description of retrieving the required properties size.

The list of available layers may change at any time due to actions outside of the OpenXR runtime, so two calls to xrEnumerateApiLayerProperties with the same parameters may return different results, or retrieve different propertyCountOutput values or properties contents.

Once an instance has been created, the layers enabled for that instance will continue to be enabled and valid for the lifetime of that instance, even if some of them become unavailable for future instances.

Valid Usage (Implicit)
  • propertyCountOutput must be a pointer to a uint32_t value

  • If propertyCapacityInput is not 0, properties must be a pointer to an array of propertyCapacityInput XrApiLayerProperties structures

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_OUT_OF_MEMORY

  • XR_ERROR_SIZE_INSUFFICIENT

The XrApiLayerProperties structure is defined as:

typedef struct XrApiLayerProperties {
    XrStructureType    type;
    void*              next;
    char               layerName[XR_MAX_API_LAYER_NAME_SIZE];
    XrVersion          specVersion;
    uint32_t           layerVersion;
    char               description[XR_MAX_API_LAYER_DESCRIPTION_SIZE];
} XrApiLayerProperties;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • layerName is a string specifying the name of the API layer. Use this name in the XrInstanceCreateInfo::enabledApiLayerNames array to enable this API layer for an instance.

  • specVersion is the API version the API layer was written to, encoded as described in the API Version Numbers and Semantics section.

  • layerVersion is the version of this API layer. It is an integer, increasing with backward compatible changes.

  • description is a string providing additional details that can be used by the application to identify the API layer.

Valid Usage (Implicit)

To enable a layer, the name of the layer should be added to XrInstanceCreateInfo::enabledApiLayerNames when creating an XrInstance.

Loader implementations may provide mechanisms outside this API for enabling specific API layers. API layers enabled through such a mechanism are implicitly enabled, while API layers enabled by including the API layer name in XrInstanceCreateInfo::enabledApiLayerNames are explicitly enabled. Except where otherwise specified, implicitly enabled and explicitly enabled API layers differ only in the way they are enabled. Explicitly enabling an API layer that is implicitly enabled has no additional effect.

Instance extensions are able to affect the operation of the instance and any of its child objects. As stated earlier, extensions can expand the OpenXR API and provide new functions or augment behavior.

Examples of extensions may be (but are not limited to):

Extension Examples
  • an extension to include OpenXR functions to work with a new graphics API

  • an extension to expose debug information via a callback

The application can determine the available instance extensions by calling xrEnumerateInstanceExtensionProperties:

// Provided by XR_VERSION_1_0
XrResult xrEnumerateInstanceExtensionProperties(
    const char*                                 layerName,
    uint32_t                                    propertyCapacityInput,
    uint32_t*                                   propertyCountOutput,
    XrExtensionProperties*                      properties);
Parameter Descriptions
  • layerName is either NULL or a pointer to a string naming the API layer to retrieve extensions from, as returned by xrEnumerateApiLayerProperties.

  • propertyCapacityInput is the capacity of the properties array, or 0 to indicate a request to retrieve the required capacity.

  • propertyCountOutput is a pointer to the count of properties written, or a pointer to the required capacity in the case that propertyCapacityInput is insufficient.

  • properties is a pointer to an array of XrExtensionProperties structures, but can be NULL if propertyCapacityInput is 0.

  • See the Buffer Size Parameters section for a detailed description of retrieving the required properties size.

Because the list of available layers may change externally between calls to xrEnumerateInstanceExtensionProperties, two calls may retrieve different results if a layerName is available in one call but not in another. The extensions supported by a layer may also change between two calls, e.g. if the layer implementation is replaced by a different version between those calls.

Valid Usage (Implicit)
  • If layerName is not NULL, layerName must be a null-terminated UTF-8 string

  • propertyCountOutput must be a pointer to a uint32_t value

  • If propertyCapacityInput is not 0, properties must be a pointer to an array of propertyCapacityInput XrExtensionProperties structures

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_OUT_OF_MEMORY

  • XR_ERROR_SIZE_INSUFFICIENT

  • XR_ERROR_RUNTIME_UNAVAILABLE

  • XR_ERROR_API_LAYER_NOT_PRESENT

The XrExtensionProperties structure is defined as:

typedef struct XrExtensionProperties {
    XrStructureType    type;
    void*              next;
    char               extensionName[XR_MAX_EXTENSION_NAME_SIZE];
    uint32_t           extensionVersion;
} XrExtensionProperties;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • extensionName is a NULL terminated string specifying the name of the extension.

  • extensionVersion is the version of this extension. It is an integer, incremented with backward compatible changes.

Valid Usage (Implicit)

4.2. Instance Lifecycle

The xrCreateInstance function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrCreateInstance(
    const XrInstanceCreateInfo*                 createInfo,
    XrInstance*                                 instance);
Parameter Descriptions
  • createInfo points to an instance of XrInstanceCreateInfo controlling creation of the instance.

  • instance points to an XrInstance handle in which the resulting instance is returned.

xrCreateInstance creates the XrInstance, then enables and initializes global API layers and extensions requested by the application. If an extension is provided by an API layer, both the API layer and extension must be specified at xrCreateInstance time. If a specified API layer cannot be found, no XrInstance will be created and the function will return XR_ERROR_API_LAYER_NOT_PRESENT. Likewise, if a specified extension cannot be found, the call must return XR_ERROR_EXTENSION_NOT_PRESENT and no XrInstance will be created. Additionally, some runtimes may limit the number of concurrent instances that may be in use. If the application attempts to create more instances than a runtime can simultaneously support, xrCreateInstance may return XR_ERROR_LIMIT_REACHED.

If the XrApplicationInfo::applicationName is the empty string the runtime must return XR_ERROR_NAME_INVALID.

If the XrInstanceCreateInfo structure contains a platform-specific extension for a platform other than the target platform, XR_ERROR_INITIALIZATION_FAILED may be returned. If a mandatory platform-specific extension is defined for the target platform but no matching extension struct is provided in XrInstanceCreateInfo the runtime must return XR_ERROR_INITIALIZATION_FAILED.

Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_OUT_OF_MEMORY

  • XR_ERROR_LIMIT_REACHED

  • XR_ERROR_RUNTIME_UNAVAILABLE

  • XR_ERROR_NAME_INVALID

  • XR_ERROR_INITIALIZATION_FAILED

  • XR_ERROR_EXTENSION_NOT_PRESENT

  • XR_ERROR_API_VERSION_UNSUPPORTED

  • XR_ERROR_API_LAYER_NOT_PRESENT

The XrInstanceCreateInfo structure is defined as:

typedef struct XrInstanceCreateInfo {
    XrStructureType          type;
    const void*              next;
    XrInstanceCreateFlags    createFlags;
    XrApplicationInfo        applicationInfo;
    uint32_t                 enabledApiLayerCount;
    const char* const*       enabledApiLayerNames;
    uint32_t                 enabledExtensionCount;
    const char* const*       enabledExtensionNames;
} XrInstanceCreateInfo;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • createFlags is a bitmask of XrInstanceCreateFlags that identifies options that apply to the creation.

  • applicationInfo is an instance of XrApplicationInfo. This information helps runtimes recognize behavior inherent to classes of applications. XrApplicationInfo is defined in detail below.

  • enabledApiLayerCount is the number of global API layers to enable.

  • enabledApiLayerNames is a pointer to an array of enabledApiLayerCount strings containing the names of API layers to enable for the created instance. See the API Layers And Extensions section for further details.

  • enabledExtensionCount is the number of global extensions to enable.

  • enabledExtensionNames is a pointer to an array of enabledExtensionCount strings containing the names of extensions to enable.

Valid Usage (Implicit)
  • type must be XR_TYPE_INSTANCE_CREATE_INFO

  • next must be NULL or a valid pointer to the next structure in a structure chain. See also: XrInstanceCreateInfoAndroidKHR

  • createFlags must be 0

  • applicationInfo must be a valid XrApplicationInfo structure

  • If enabledApiLayerCount is not 0, enabledApiLayerNames must be a pointer to an array of enabledApiLayerCount null-terminated UTF-8 strings

  • If enabledExtensionCount is not 0, enabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated UTF-8 strings

The XrInstanceCreateInfo::createFlags member is of the following type, and contains a bitwise-OR of zero or more of the bits defined in XrInstanceCreateFlagBits.

typedef XrFlags64 XrInstanceCreateFlags;

Valid bits for XrInstanceCreateFlags are defined by XrInstanceCreateFlagBits.

// Flag bits for XrInstanceCreateFlags

There are currently no instance creation flag bits defined. This is reserved for future use.

The XrApplicationInfo structure is defined as:

typedef struct XrApplicationInfo {
    char         applicationName[XR_MAX_APPLICATION_NAME_SIZE];
    uint32_t     applicationVersion;
    char         engineName[XR_MAX_ENGINE_NAME_SIZE];
    uint32_t     engineVersion;
    XrVersion    apiVersion;
} XrApplicationInfo;
Member Descriptions
  • applicationName is a non-empty string containing the name of the application.

  • applicationVersion is an unsigned integer variable containing the developer-supplied version number of the application.

  • engineName is a string containing the name of the engine (if any) used to create the application. It may be empty to indicate no specified engine.

  • engineVersion is an unsigned integer variable containing the developer-supplied version number of the engine used to create the application. May be zero to indicate no specified engine.

  • apiVersion is the version of this API against which the application will run, encoded as described in the API Version Numbers and Semantics section. If the runtime does not support the requested apiVersion it must return XR_ERROR_API_VERSION_UNSUPPORTED.

Valid Usage (Implicit)
  • applicationName must be a null-terminated UTF-8 string whose length is less than or equal to XR_MAX_APPLICATION_NAME_SIZE

  • engineName must be a null-terminated UTF-8 string whose length is less than or equal to XR_MAX_ENGINE_NAME_SIZE

Note

When using the OpenXR API to implement a reusable engine that will be used by many applications, engineName should be set to a unique string that identifies the engine, and engineVersion should encode a representation of the engine’s version. This way, all applications that share this engine version will provide the same engineName and engineVersion to the runtime. The engine should then enable individual applications to choose their specific applicationName and applicationVersion, enabling one application to be distinguished from another application.

When using the OpenXR API to implement an individual application without a shared engine, the input engineName should be left empty and engineVersion should be set to 0. The applicationName should then be filled in with a unique string that identifies the app and the applicationVersion should encode a representation of the application’s version.

The xrDestroyInstance function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrDestroyInstance(
    XrInstance                                  instance);

The xrDestroyInstance function is used to destroy an XrInstance.

Parameter Descriptions
  • instance is the handle to the instance to destroy.

XrInstance handles are destroyed using xrDestroyInstance. When an XrInstance is destroyed, all handles that are children of that XrInstance are also destroyed.

Valid Usage (Implicit)
Thread Safety
  • Access to instance, and any child handles, must be externally synchronized

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_HANDLE_INVALID

4.3. Instance Information

The xrGetInstanceProperties function provides information about the instance and the associated runtime.

// Provided by XR_VERSION_1_0
XrResult xrGetInstanceProperties(
    XrInstance                                  instance,
    XrInstanceProperties*                       instanceProperties);
Parameter Descriptions

The instanceProperties parameter must be filled out by the runtime in response to this call, with information as defined in XrInstanceProperties.

Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

The XrInstanceProperties structure is defined as:

typedef struct XrInstanceProperties {
    XrStructureType    type;
    void*              next;
    XrVersion          runtimeVersion;
    char               runtimeName[XR_MAX_RUNTIME_NAME_SIZE];
} XrInstanceProperties;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • runtimeVersion is the runtime’s version (not necessarily related to an OpenXR API version), expressed in the format of XR_MAKE_VERSION.

  • runtimeName is the name of the runtime.

Valid Usage (Implicit)

4.4. Platform-Specific Instance Creation

Some amount of data required for instance creation is exposed through chained structures defined in extensions. These structures may be optional or even required for instance creation on specific platforms, but not on other platforms. Separating off platform-specific functionality into extension structures prevents the primary XrInstanceCreateInfo structure from becoming too bloated with unnecessary information.

See the List of Extensions appendix for the list of available extensions and their related structures. These structures expand the XrInstanceCreateInfo parent struct using the XrInstanceCreateInfo::next member. The specific list of structures that may be used for extending XrInstanceCreateInfo::next can be found in the "Valid Usage (Implicit)" block immediately following the definition of the structure.

4.4.1. The Instance Lost Error

The XR_ERROR_INSTANCE_LOST error indicates that the XrInstance has become unusable. This can happen if a critical runtime process aborts, if the connection to the runtime is otherwise no longer available, or if the runtime encounters an error during any function execution which prevents it from being able to support further function execution. Once XR_ERROR_INSTANCE_LOST is first returned, it must henceforth be returned by all non-destroy functions that involve an XrInstance or child handle type until the instance is destroyed. Applications must destroy the XrInstance. Applications may then attempt to continue by recreating all relevant OpenXR objects, starting with a new XrInstance. A runtime may generate an XrEventDataInstanceLossPending event when instance loss is detected.

4.4.2. XrEventDataInstanceLossPending

// Provided by XR_VERSION_1_0
typedef struct XrEventDataInstanceLossPending {
    XrStructureType    type;
    const void*        next;
    XrTime             lossTime;
} XrEventDataInstanceLossPending;

Receiving the XrEventDataInstanceLossPending event structure indicates that the application is about to lose the indicated XrInstance at the indicated lossTime in the future. The application should call xrDestroyInstance and relinquish any instance-specific resources. This typically occurs to make way for a replacement of the underlying runtime, such as via a software update.

After the application has destroyed all of its instances and their children and waited past the specified time, it may then re-try xrCreateInstance in a loop waiting for whatever maintenance the runtime is performing to complete. The runtime will return XR_ERROR_RUNTIME_UNAVAILABLE from xrCreateInstance as long as it is unable to create the instance. Once the runtime has returned and is able to continue, it must resume returning XR_SUCCESS from xrCreateInstance if valid data is passed in.

Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • lossTime is the absolute time at which the indicated instance will be considered lost and become unusable.

Valid Usage (Implicit)

4.5. Instance Enumerated Type String Functions

Applications often want to turn certain enum values from the runtime into strings for use in log messages, to be localized in UI, or for various other reasons. OpenXR provides functions that turn common enum types into UTF-8 strings for use in applications.

// Provided by XR_VERSION_1_0
XrResult xrResultToString(
    XrInstance                                  instance,
    XrResult                                    value,
    char                                        buffer[XR_MAX_RESULT_STRING_SIZE]);
Parameter Descriptions
  • instance is the handle of the instance to ask for the string.

  • value is the XrResult value to turn into a string.

  • buffer is the buffer that will be used to return the string in.

Returns the text version of the provided XrResult value as a UTF-8 string.

In all cases the returned string must be one of:

Result String Return Values
  • The literal string defined for the provide numeric value in the core spec or extension. (e.g. the value 0 results in the string XR_SUCCESS)

  • XR_UNKNOWN_SUCCESS_ concatenated with the positive result number expressed as a decimal number.

  • XR_UNKNOWN_FAILURE_ concatenated with the negative result number expressed as a decimal number.

Valid Usage (Implicit)
  • instance must be a valid XrInstance handle

  • value must be a valid XrResult value

  • buffer must be a character array of length XR_MAX_RESULT_STRING_SIZE

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

The xrStructureTypeToString function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrStructureTypeToString(
    XrInstance                                  instance,
    XrStructureType                             value,
    char                                        buffer[XR_MAX_STRUCTURE_NAME_SIZE]);
Parameter Descriptions
  • instance is the handle of the instance to ask for the string.

  • value is the XrStructureType value to turn into a string.

  • buffer is the buffer that will be used to return the string in.

Returns the text version of the provided XrStructureType value as a UTF-8 string.

In all cases the returned string must be one of:

Structure Type String Return Values
  • The literal string defined for the provide numeric value in the core spec or extension. (e.g. the value of XR_TYPE_INSTANCE_CREATE_INFO results in the string XR_TYPE_INSTANCE_CREATE_INFO)

  • XR_UNKNOWN_STRUCTURE_TYPE_ concatenated with the structure type number expressed as a decimal number.

Valid Usage (Implicit)
  • instance must be a valid XrInstance handle

  • value must be a valid XrStructureType value

  • buffer must be a character array of length XR_MAX_STRUCTURE_NAME_SIZE

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

5. System

This API separates the concept of physical systems of XR devices from the logical objects that applications interact with directly. A system represents a collection of related devices in the runtime, often made up of several individual hardware components working together to enable XR experiences. An XrSystemId is returned by xrGetSystem representing the system of devices the runtime will use to support a given form factor. Each system may include: a VR/AR display, various forms of input (gamepad, touchpad, motion controller), and other trackable objects.

The application uses the system to create a session, which can then be used to accept input from the user and output rendered frames. The application also provides a default set of bindings from its actions to any number of input sources. The runtime may use this action information to activate only a subset of devices and avoid wasting resources on devices that are not in use. Exactly which devices are active once an XR system is selected will depend on the features provided by the runtime, and may vary from runtime to runtime. For example, a runtime that is capable of mapping from one tracking system’s space to another’s may support devices from multiple tracking systems simultaneously.

5.1. Form Factors

The first step in selecting a system is for the application to request its desired form factor. The form factor defines how the display(s) moves in the environment relative to the user’s head and how the user will interact with the XR experience. A runtime may support multiple form factors, such as on a mobile phone that supports both slide-in VR headset experiences and handheld AR experiences.

While an application’s core XR rendering may span across form factors, its user interface will often be written to target a particular form factor, requiring explicit tailoring to function well on other form factors. For example, screen-space UI designed for a handheld phone will produce an uncomfortable experience for users if presented in screen-space on an AR headset.

typedef enum XrFormFactor {
    XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY = 1,
    XR_FORM_FACTOR_HANDHELD_DISPLAY = 2,
    XR_FORM_FACTOR_MAX_ENUM = 0x7FFFFFFF
} XrFormFactor;

The predefined form factors which may be supported by OpenXR runtimes are:

Enumerant Descriptions
  • XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY. The tracked display is attached to the user’s head. The user cannot touch the display itself. A VR headset would be an example of this form factor.

  • XR_FORM_FACTOR_HANDHELD_DISPLAY. The tracked display is held in the user’s hand, independent from the user’s head. The user may be able to touch the display, allowing for screen-space UI. A mobile phone running an AR experience using pass-through video would be an example of this form factor.

5.2. Getting the XrSystemId

XR_DEFINE_ATOM(XrSystemId)

An XrSystemId is an opaque atom used by the runtime to identify a system. The value XR_NULL_SYSTEM_ID is considered an invalid system.

// Provided by XR_VERSION_1_0
#define XR_NULL_SYSTEM_ID 0

The only XrSystemId value defined to be constant across all instances is the invalid system XR_NULL_SYSTEM_ID. No supported system is associated with XR_NULL_SYSTEM_ID. Unless explicitly permitted, it should not be passed to API calls or used as a structure attribute when a valid XrSystemId is required.

The xrGetSystem function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrGetSystem(
    XrInstance                                  instance,
    const XrSystemGetInfo*                      getInfo,
    XrSystemId*                                 systemId);
Parameter Descriptions
  • instance is the handle of the instance from which to get the information.

  • getInfo is a pointer to an XrSystemGetInfo structure containing the application’s requests for a system.

  • systemId is the returned XrSystemId.

To get an XrSystemId, an application specifies its desired form factor to xrGetSystem and gets the runtime’s XrSystemId associated with that configuration.

If the form factor is supported but temporarily unavailable, xrGetSystem must return XR_ERROR_FORM_FACTOR_UNAVAILABLE. A runtime may return XR_SUCCESS on a subsequent call for a form factor it previously returned XR_ERROR_FORM_FACTOR_UNAVAILABLE. For example, connecting or warming up hardware might cause an unavailable form factor to become available.

Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

  • XR_ERROR_FORM_FACTOR_UNSUPPORTED

  • XR_ERROR_FORM_FACTOR_UNAVAILABLE

The XrSystemGetInfo structure is defined as:

typedef struct XrSystemGetInfo {
    XrStructureType    type;
    const void*        next;
    XrFormFactor       formFactor;
} XrSystemGetInfo;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR.

  • formFactor is the XrFormFactor requested by the application.

The XrSystemGetInfo structure specifies attributes about a system as desired by an application.

Valid Usage (Implicit)
XrInstance instance; // previously initialized

XrSystemGetInfo system_get_info = {XR_TYPE_SYSTEM_GET_INFO};
system_get_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;

XrSystemId systemId;
CHK_XR(xrGetSystem(instance, &system_get_info, &systemId));

// create session
// create swapchains
// begin session

// main loop

// end session
// destroy session

// no access to hardware after this point

5.3. System Properties

The xrGetSystemProperties function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrGetSystemProperties(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    XrSystemProperties*                         properties);
Parameter Descriptions
  • instance is the instance from which systemId was retrieved.

  • systemId is the XrSystemId whose properties will be queried.

  • properties points to an instance of the XrSystemProperties structure, that will be filled with returned information.

An application can call xrGetSystemProperties to retrieve information about the system such as vendor ID, system name, and graphics and tracking properties.

Valid Usage (Implicit)
Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

  • XR_ERROR_OUT_OF_MEMORY

  • XR_ERROR_SYSTEM_INVALID

The XrSystemProperties structure is defined as:

typedef struct XrSystemProperties {
    XrStructureType               type;
    void*                         next;
    XrSystemId                    systemId;
    uint32_t                      vendorId;
    char                          systemName[XR_MAX_SYSTEM_NAME_SIZE];
    XrSystemGraphicsProperties    graphicsProperties;
    XrSystemTrackingProperties    trackingProperties;
} XrSystemProperties;
Member Descriptions
  • type is the XrStructureType of this structure.

  • next is NULL or a pointer to the next structure in a structure chain.

  • vendorId is a unique identifier for the vendor of the system.

  • systemId is the XrSystemId identifying the system.

  • systemName is a string containing the name of the system.

  • graphicsProperties is an XrSystemGraphicsProperties structure specifying the system graphics properties.

  • trackingProperties is an XrSystemTrackingProperties structure specifying system tracking properties.

Valid Usage (Implicit)

The runtime must report a valid vendor ID for the system. The vendor ID must be either the USB vendor ID defined for the physical device or a Khronos vendor ID.

The XrSystemGraphicsProperties structure is defined as:

typedef struct XrSystemGraphicsProperties {
    uint32_t    maxSwapchainImageHeight;
    uint32_t    maxSwapchainImageWidth;
    uint32_t    maxLayerCount;
} XrSystemGraphicsProperties;
Member Descriptions
  • maxSwapchainImageHeight is the maximum swapchain image pixel height supported by this system.

  • maxSwapchainImageWidth is the maximum swapchain image pixel width supported by this system.

  • maxLayerCount is the maximum number of composition layers supported by this system. The runtime must support at least XR_MIN_COMPOSITION_LAYERS_SUPPORTED layers.

// Provided by XR_VERSION_1_0
#define XR_MIN_COMPOSITION_LAYERS_SUPPORTED 16

XR_MIN_COMPOSITION_LAYERS_SUPPORTED defines the minimum number of composition layers that a conformant runtime must support. A runtime must return the XrSystemGraphicsProperties::maxLayerCount at least the value of XR_MIN_COMPOSITION_LAYERS_SUPPORTED.

The XrSystemTrackingProperties structure is defined as:

typedef struct XrSystemTrackingProperties {
    XrBool32    orientationTracking;
    XrBool32    positionTracking;
} XrSystemTrackingProperties;
Member Descriptions
  • orientationTracking is set to XR_TRUE to indicate the system supports orientational tracking of the view pose(s), XR_FALSE otherwise.

  • positionTracking is set to XR_TRUE to indicate the system supports positional tracking of the view pose(s), XR_FALSE otherwise.

6. Path Tree and Semantic Paths

OpenXR incorporates an internal semantic path tree model, also known as the path tree, with entities associated with nodes organized in a logical tree and referenced by path name strings structured like a filesystem path or URL. The path tree unifies a number of concepts used in this specification and a runtime may add additional nodes as implementation details. As a general design principle, the most application-facing paths should have semantic and hierarchical meaning in their name. Thus, these paths are often referred to as semantic paths. However, path names in the path tree model may not all have the same level or kind of semantic meaning.

In regular use in an application, path name strings are converted to instance-specific XrPath values which are used in place of path strings. The mapping between XrPath values and their corresponding path name strings may be considered to be tracked by the runtime in a one-to-one mapping in addition to the natural tree structure of the referenced entities. Runtimes may use any internal implementation that satisfies the requirements.

Formally, the runtime maintains an instance-specific bijective mapping between well-formed path name strings and valid XrPath (uint64_t) values. These XrPath values are only valid within a single XrInstance, and applications must not share these values between instances. Applications must instead use the string representation of a path in their code and configuration, and obtain the correct corresponding XrPath at runtime in each XrInstance. The term path or semantic path may refer interchangeably to either the path name string or its associated XrPath value within an instance when context makes it clear which type is being discussed.

Given that path trees are a unifying model in this specification, the entities referenced by paths can be of diverse types. For example, they may be used to represent physical device or sensor components, which may be of various component types. They may also be used to represent frames of reference that are understood by the application and the runtime, as defined by an XrSpace. Additionally, to permit runtime re-configuration and support hardware-independent development, any syntactically-valid path string may be used to retrieve a corresponding XrPath without error given sufficient resources, even if no logical or hardware entity currently corresponds to that path at the time of the call. Later retrieval of the associated path string of such an XrPath using xrPathToString should succeed if the other requirements of that call are met. However, using such an XrPath in a later call to any other API function may result in an error if no entity of the type required by the call is available at the path at that later time. A runtime should permit the entity referenced by a path to vary over time to naturally reflect varying system configuration and hardware availability.

6.1. Path Atom Type

XR_DEFINE_ATOM(XrPath)

The XrPath is an atom that connects an application with a single path, within the context of a single instance. There is a bijective mapping between well-formed path strings and atoms in use. This atom is used — in place of the path name string it corresponds to — to retrieve state and perform other operations.

As an XrPath is only shorthand for a well-formed path string, they have no explicit life cycle.

Lifetime is implicitly managed by the XrInstance. An XrPath must not be used unless it is received at execution time from the runtime in the context of a particular XrInstance. Therefore, with the exception of XR_NULL_PATH, XrPath values must not be specified as constant values in applications: the corresponding path string should be used instead. During the lifetime of a given XrInstance, the XrPath associated with that instance with any given well-formed path must not vary, and similarly the well-formed path string that corresponds to a given XrPath in that instance must not vary. An XrPath that is received from one XrInstance may not be used with another. Such an invalid use may be detected and result in an error being returned, or it may result in undefined behavior.

Well-written applications should typically use a small, bounded set of paths in practice. However, the runtime should support looking up the XrPath for a large number of path strings for maximum compatibility. Runtime implementers should keep in mind that applications supporting diverse systems may look up path strings in a quantity exceeding the number of non-empty entities predicted or provided by any one runtime’s own path tree model, and this is not inherently an error. However, system resources are finite and thus runtimes may signal exhaustion of resources dedicated to these associations under certain conditions.

When discussing the behavior of runtimes at these limits, a new XrPath refers to an XrPath value that, as of some point in time, has neither been received by the application nor tracked internally by the runtime. In this case, since an application has not yet received the value of such an XrPath, the runtime has not yet made any assertions about its association with any path string. In this context, new only refers to the fact that the mapping has not necessarily been made constant for a given value/path string pair for the remaining life of the associated instance by being revealed to the application. It does not necessarily imply creation of the entity, if any, referred to by such a path. Similarly, it does not imply the absence of such an entity prior to that point. Entities in the path tree have varied lifetime that is independent from the duration of the mapping from path string to XrPath.

For flexibility, the runtime may internally track or otherwise make constant, in instance or larger scope, any mapping of a path string to an XrPath value even before an application would otherwise receive that value, thus making it no longer new by the above definition.

When the runtime’s resources to track the path string-XrPath mapping are exhausted, and the application makes an API call that would have otherwise retrieved a new XrPath as defined above, the runtime must return XR_ERROR_PATH_COUNT_EXCEEDED. This includes both explicit calls to xrStringToPath as well as other calls that retrieve an XrPath in any other way.

The runtime should support creating as many paths as memory will allow and must return XR_ERROR_PATH_COUNT_EXCEEDED from relevant functions when no more can be created.

// Provided by XR_VERSION_1_0
#define XR_NULL_PATH 0

The only XrPath value defined to be constant across all instances is the invalid path XR_NULL_PATH. No well-formed path string is associated with XR_NULL_PATH. Unless explicitly permitted, it should not be passed to API calls or used as a structure attribute when a valid XrPath is required.

6.2. Well-Formed Path Strings

Even though they look similar, semantic paths are not file paths. To avoid confusion with file path directory traversal conventions, many file path conventions are explicitly disallowed from well-formed path name strings.

A well-formed path name string must conform to the following rules:

  • Path name strings must be constructed entirely from characters on the following list.

    • Lower case ASCII letters: a-z

    • Numeric digits: 0-9

    • Dash: -

    • Underscore: _

    • Period: .

    • Forward Slash: /

  • Path name strings must start with a single forward slash character.

  • Path name strings must not end with a forward slash character.

  • Path name strings must not contain two or more adjacent forward slash characters.

  • Path name strings must not contain two forward slash characters that are separated by only period characters.

  • Path name strings must not contain only period characters following the final forward slash character in the string.

  • The maximum string length for a path name string, including the terminating \0 character, is defined by XR_MAX_PATH_LENGTH.

6.2.1. xrStringToPath

The xrStringToPath function is defined as:

// Provided by XR_VERSION_1_0
XrResult xrStringToPath(
    XrInstance                                  instance,
    const char*                                 pathString,
    XrPath*                                     path);
Parameter Descriptions
  • instance is an instance previously created.

  • pathString is the path name string to retrieve the associated XrPath for.

  • path is the output parameter, which must point to an XrPath. Given a well-formed path name string, this will be populated with an opaque value that is constant for that path string during the lifetime of that instance.

xrStringToPath retrieves the XrPath value for a well-formed path string. If such a value had not yet been assigned by the runtime to the provided path string in this XrInstance, one must be assigned at this point. All calls to this function with the same XrInstance and path string must retrieve the same XrPath value. Upon failure, xrStringToPath must return an appropriate XrResult, and may set the output parameter to XR_NULL_PATH. See Path Atom Type for the conditions under which an error may be returned when this function is given a valid XrInstance and a well-formed path string.

If the runtime’s resources are exhausted and it cannot create the path, a return value of XR_ERROR_PATH_COUNT_EXCEEDED must be returned. If the application specifies a string that is not a well-formed path string, XR_ERROR_PATH_FORMAT_INVALID must be returned.

A return value of XR_SUCCESS from xrStringToPath may not necessarily imply that the runtime has a component or other source of data that will be accessible through that semantic path. It only means that the path string supplied was well-formed and that the retrieved XrPath maps to the given path string within and during the lifetime of the XrInstance given.
Valid Usage (Implicit)
  • instance must be a valid XrInstance handle

  • pathString must be a null-terminated UTF-8 string

  • path must be a pointer to an XrPath value

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

  • XR_ERROR_PATH_FORMAT_INVALID

  • XR_ERROR_PATH_COUNT_EXCEEDED

6.2.2. xrPathToString

// Provided by XR_VERSION_1_0
XrResult xrPathToString(
    XrInstance                                  instance,
    XrPath                                      path,
    uint32_t                                    bufferCapacityInput,
    uint32_t*                                   bufferCountOutput,
    char*                                       buffer);
Parameter Descriptions
  • instance is an instance previously created.

  • path is the valid XrPath value to retrieve the path string for.

  • bufferCapacityInput is the capacity of the buffer, or 0 to indicate a request to retrieve the required capacity.

  • bufferCountOutput is a pointer to the count of characters written to buffer (including the terminating '\0'), or a pointer to the required capacity in the case that bufferCapacityInput is insufficient.

  • buffer is a pointer to an application-allocated buffer that will be filled with the semantic path string. It can be NULL if bufferCapacityInput is 0.

  • See Buffer Size Parameters chapter for a detailed description of retrieving the required buffer size.

xrPathToString retrieves the path name string associated with an XrPath, in the context of a given XrInstance, in the form of a NULL terminated string placed into a caller-allocated buffer. Since the mapping between a well-formed path name string and an XrPath is bijective, there will always be exactly one string for each valid XrPath value. This can be useful if the calling application receives an XrPath value that they had not previously retrieved via xrStringToPath. During the lifetime of the given XrInstance, the path name string retrieved by this function for a given valid XrPath will not change. For invalid paths, including XR_NULL_PATH, XR_ERROR_PATH_INVALID must be returned.

Valid Usage (Implicit)
  • instance must be a valid XrInstance handle

  • bufferCountOutput must be a pointer to a uint32_t value

  • If bufferCapacityInput is not 0, buffer must be a pointer to an array of bufferCapacityInput char values

Return Codes
Success
  • XR_SUCCESS

Failure
  • XR_ERROR_VALIDATION_FAILURE

  • XR_ERROR_RUNTIME_FAILURE

  • XR_ERROR_HANDLE_INVALID

  • XR_ERROR_INSTANCE_LOST

  • XR_ERROR_SIZE_INSUFFICIENT

  • XR_ERROR_PATH_INVALID

6.3. Reserved Paths

In order for some uses of semantic paths to work consistently across runtimes, it is necessary to standardize several paths and require each runtime to use the same paths or patterns of paths for certain classes of usage. Those paths are as follows.

6.3.1. /user paths

Some paths are used to refer to entities that are filling semantic roles in the system. These paths are all under the /user subtree.

The reserved user paths are:

Reserved Semantic Paths
  • /user/hand/left represents the user’s left hand. It might be tracked using a controller or other device in the user’s left hand, or tracked without the user holding anything, e.g. using computer vision.

  • /user/hand/right represents the user’s right hand in analog to the left hand.

  • /user/head represents inputs on the user’s head, often from a device such as a head-mounted display. To reason about the user’s head, see the XR_REFERENCE_SPACE_TYPE_VIEW reference space.

  • /user/gamepad is a two-handed gamepad device held by the user.

  • /user/treadmill is a treadmill or other locomotion-targeted input device.

Runtimes are not required to provide interaction at all of these paths. For instance, in a system with no hand tracking, only /user/head would be active for interaction. In a system with only one controller, the runtime may provide access to that controller via either /user/hand/left or /user/hand/right as it deems appropriate.

The runtime may change the devices referred to by /user/hand/left and /user/hand/right at any time.

If more than two hand-held controllers or devices are active, the runtime must determine which two are accessible as /user/hand/left and /user/hand/right.

6.3.2. Input subpaths

Devices on the source side of the input system need to define paths for each component that can be bound to an action. This section describes the naming conventions for those input components. Runtimes must ignore input source paths that use identifiers and component names that do not appear in this specification or otherwise do not follow the pattern specified below.

Each input source path must match the following pattern:

  • …/input/<identifier>[_<location>][/<component>]

Identifiers are often the label on the component or related to the type and location of the component.

When specifying a suggested binding there are several cases where the component part of the path can be determined automatically. See Suggested Bindings for more details.

See Interaction Profiles for examples of input subpaths.

Standard identifiers
  • trackpad - A 2D input source that usually includes click and touch component.

  • thumbstick - A small 2D joystick that is meant to be used with the user’s thumb. These sometimes include click and/or touch components.

  • joystick - A 2D joystick that is meant to be used with the user’s entire hand, such as a flight stick. These generally do not have click component, but might have touch components.

  • trigger - A 1D analog input component that returns to a rest state when the user stops interacting with it. These sometime include touch and/or click components.

  • throttle - A 1D analog input component that remains in position when the user stops interacting with it.

  • trackball - A 2D relative input source. These sometimes include click components.

  • pedal - A 1D analog input component that is similar to a trigger but meant to be operated by a foot

  • system - A button with the specialised meaning that it enables the user to access system-level functions and UI. Input data from system buttons is generally used internally by runtimes and may not be available to applications.

  • dpad_up, dpad_down, dpad_left, and dpad_right - A set of buttons arranged in a plus shape.

  • diamond_up, diamond_down, diamond_left, and diamond_right - Gamepads often have a set of four buttons arranged in a diamond shape. The labels on those buttons vary from gamepad to gamepad, but their arrangement is consistent. These names are used for the A/B/X/Y buttons on a Xbox controller, and the square/cross/circle/triangle button on a PlayStation controller.

  • a, b, x, y, start, home, end, select - Standalone buttons are named for their physical labels. These are the standard identifiers for such buttons. Extensions may add new identifiers as detailed in the next section. Groups of four buttons in a diamond shape should use the diamond-prefix names above instead of using the labels on the buttons themselves.

  • volume_up, volume_down, mute_mic, play_pause, menu, view, back - Some other standard controls are often identified by icons. These are their standard names.

  • thumbrest - Some controllers have a place for the user to rest their thumb.

  • shoulder - A button that is usually pressed with the index finger and is often positioned above a trigger.

  • squeeze - An input source that indicates that the user is squeezing their fist closed. This could be a simple button or act more like a trigger. Sources with this identifier should either follow button or trigger conventions for their components.

  • wheel - A steering wheel.

Standard pose identifiers

Input sources whose orientation and/or position are tracked also expose pose identifiers.

Standard pose identifiers for tracked hands or motion controllers as represented by /user/hand/left and /user/hand/right are: