// Copyright (c) 2016-2024, The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[fundamentals]]
== Fundamentals

[[fundamentals-api-version-numbers-and-semantics]]
=== API Version Numbers and Semantics


[open,refpage='XrVersion',type='basetypes',desc='Type indicating multi-part version packed into 64-bit integer']
--
Multi-part version numbers are used in several places in the OpenXR API.

include::{generated}/api/basetypes/XrVersion.adoc[]

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
basetype: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]
.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 continues where
the last minor version left off, making patch versions unique inside major
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 during an update to any of the major, minor,
or patch version numbers:

.Scenarios Which May Cause a Version Change

[cols="<.^,^.^,^.^,^.^,options="header"]
|=======================================================================
| __**Reason**__ | __**Major Version**__ | __**Minor Version**__ | __**Patch Version**__
| __Extensions Added/Removed* __        {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
| __Spec-Optional Behavior Changed* __  {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
| __Spec Required Behavior Changed* __  {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
    | must: not{set:cellbgcolor:lightcoral}
| __Core Interfaces Added* __           {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
    | must: not{set:cellbgcolor:lightcoral}
| __Weak Deprecation* __                {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | may: {set:cellbgcolor:lightgreen}
    | must: not{set:cellbgcolor:lightcoral}
| __Strong Deprecation* __              {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | must: not{set:cellbgcolor:lightcoral}
    | must: not{set:cellbgcolor:lightcoral}
| __Core Interfaces Changed/Removed* __ {set:cellbgcolor:white}
    | may: {set:cellbgcolor:lightgreen}
    | must: not{set:cellbgcolor:lightcoral}
    | must: not{set:cellbgcolor:lightcoral}
|=======================================================================

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

[cols="<.<35%e,<.^65%",frame="topbot",grid="none"]
|=======================================================================
| Extensions Added/Removed {set:cellbgcolor:white}
   | 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
     normative language 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, lower
     latency, 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.
|=======================================================================

[[fundamentals-string-encoding]]
=== String Encoding

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

[[fundamentals-threading-behavior]]
=== 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.

include::{generated}/hostsynctable/parameters.adoc[]
include::{generated}/hostsynctable/parameterlists.adoc[]
include::{generated}/hostsynctable/implicit.adoc[]

[[fundamentals-multiprocessing-behavior]]
=== 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.

[[fundamentals-runtime]]
=== 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.

[[fundamentals-extensions]]
=== 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
flink:xrEnumerateInstanceExtensionProperties function.
Once an application determines which extensions are supported, it can:
enable some subset of them during the call to flink: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 "code: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:
** "code:KHR" for Khronos extensions, supported by multiple vendors.
** "code:EXT" for non-Khronos extensions supported by multiple vendors.
* An underscore "code:_".
* 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: apiext: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 and configured for inclusion
in this document at the time of this specification being generated appears
in the
ifndef::HAS_DEPRECATED_EXTENSIONS[]
<<extension-appendices-list, List of Extensions>>
endif::HAS_DEPRECATED_EXTENSIONS[]
ifdef::HAS_DEPRECATED_EXTENSIONS[]
<<extension-appendices-list, List of Current Extensions>>
endif::HAS_DEPRECATED_EXTENSIONS[]
appendix at the end of this document.

[[fundamentals-api-layers]]
=== 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 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.

==== Examples of API Layers

===== Validation Layer
The layered API approach employed by OpenXR allows for potentially expensive
validation of correct API usage to be implemented in a "validation" layer.
Such a layer allows the application developer to develop their application
with a validation layer active to ensure that the application is using the
API correctly.
A 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 a 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 a validation layer to allow the application to run in a production
environment without repeatedly incurring the validation expense.
(Note that some validation of correct API usage is required to be
implemented by the runtime.)

===== 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.

==== 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
```

==== Activating API Layers

===== Application Activation
Applications can: determine the API layers that are available to them by
calling the flink: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 flink: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.

==== API Layer Extensions
API layers may: implement OpenXR functions that are not 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
<<fundamentals-extensions,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 flink: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
flink:xrEnumerateApiLayerProperties.
After verifying an API layer of interest exists, the application then
should: call flink:xrEnumerateInstanceExtensionProperties and provide the
API layer name as the first parameter.
This will return the list of extensions implemented by that API layer.

[[fundamentals-type-aliasing]]
=== 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 assume that the actual type matches the declared
type in some configurations, and may: be so configured by default at common
optimization levels.
In such a compiler configured with that assumption, violating the assumption
may: produce undefined behavior.
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, slink:XrFrameEndInfo::pname:layers is an array of type
code:const slink:XrCompositionLayerBaseHeader code:* code:const.
However, each element of the array must: be of one of the specific layer
types, such as slink:XrCompositionLayerQuad.
Similarly, flink:xrEnumerateSwapchainImages accepts an array of
slink:XrSwapchainImageBaseHeader, whereas the actual type passed must: be an
array of a type such as
ifdef::XR_KHR_vulkan_enable[]
slink:XrSwapchainImageVulkanKHR.
endif::XR_KHR_vulkan_enable[]
ifndef::XR_KHR_vulkan_enable[]
`XrSwapchainImageVulkanKHR`.
endif::XR_KHR_vulkan_enable[]

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

[open,refpage='XR_MAY_ALIAS',type='defines',desc='Convenience macro to annotate types and pointers affirmatively known to alias']
--
include::{generated}/api/defines/XR_MAY_ALIAS.adoc[]

As a convenience, some types and pointers that are known at specification
time to alias values of different types have been annotated with the
dlink: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 is defined to a 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.

ifdef::doctype-manpage[]
// This link is redundant in the full spec, but important in the extracted refpages.
See <<type-aliasing,Type Aliasing>> for full discussion of pointer aliasing
in OpenXR.
endif::[]
--

[[fundamentals-valid-usage]]
=== 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.

[[fundamentals-implicit-valid-usage]]
==== 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.

[[fundamentals-valid-usage-for-object-handles]]
==== 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 all of the following conditions
hold:

.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.
* 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 dlink:XR_NULL_HANDLE, which has the integer
value code:0.

[[fundamentals-valid-usage-for-pointers]]
==== 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.


[[fundamentals-valid-usage-for-enumerated-types]]
==== 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.

[[fundamentals-valid-usage-for-flags]]
==== Valid Usage for Flags
[open,refpage='XrFlags64',desc='OpenXR bitmasks',type='basetypes',xrefs='XrInstanceCreateFlags XrSessionCreateFlags XrSwapchainCreateFlags XrSwapchainUsageFlags XrViewStateFlags XrCompositionLayerFlags XrSpaceLocationFlags']
--
A collection of flags is represented by a bitmask using the type
basetype:XrFlags64:

include::{generated}/api/basetypes/XrFlags64.adoc[]

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

Any stext: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 code: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
  stext:Xr*Flags type as the stext:Xr*Flags member or parameter.
  (Valid flag values may: also be defined by extensions but will appear in
  the specification with all other valid flag values for that type.)
* 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.
****

[[fundamentals-valid-usage-for-structure-types]]
==== Valid Usage for Structure Types

Any parameter that is a structure containing a pname:type member must: have
a value of pname:type which is a valid elink: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 code: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
****

[[fundamentals-valid-usage-for-structure-pointer-chains]]
==== Valid Usage for Structure Pointer Chains

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

In order to use a structure type defined by an extension in a pname:next
chain, the proper extension must: have been previously enabled during
flink:xrCreateInstance.
A runtime must: ignore all unrecognized structures in a pname: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
ifndef::HAS_DEPRECATED_EXTENSIONS[]
<<extension-appendices-list, List of Extensions>>.
endif::HAS_DEPRECATED_EXTENSIONS[]
ifdef::HAS_DEPRECATED_EXTENSIONS[]
<<extension-appendices-list, List of Current Extensions>>.
endif::HAS_DEPRECATED_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:

[open,refpage='XrBaseInStructure',desc='Convenience type for iterating (read only)',type='structs',xrefs='XrBaseOutStructure']
--

The slink:XrBaseInStructure structure is defined as:
include::{generated}/api/structs/XrBaseInStructure.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
  This base structure itself has no associated elink:XrStructureType value.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
****

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

[open,refpage='XrBaseOutStructure',desc='Convenience type for iterating (mutable)',type='structs',xrefs='XrBaseInStructure']
--

The slink:XrBaseOutStructure structure is defined as:
include::{generated}/api/structs/XrBaseOutStructure.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
  This base structure itself has no associated elink:XrStructureType value.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
****

slink: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.

[[fundamentals-next-chain-structure-uniqueness]]
===== 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 pname: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 pname: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 pname: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.

[[fundamentals-valid-usage-for-nested-structures]]
==== 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.

[[fundamentals-return-codes]]
=== 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.
****

[open,refpage='XrResult',desc='Result codes',type='enums']
--

include::{generated}/api/enums/XrResult.adoc[]

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

The following are common suffixes shared across many of the return codes:

* etext:_INVALID: The specified handle, atom, or value is formatted
  incorrectly, or the specified handle was never created or has been
  destroyed.
* etext:_UNSUPPORTED: The specified handle, atom, enumerant, or value is
  formatted correctly but cannot be used for the lifetime of this function's
  parent handle.
* etext:_UNAVAILABLE: The specified handle, atom, enumerant, or value is
  supported by the handle taken by this function, but is not usable at this
  moment.

// NOTE: this anchor referenced by name in generated validity statements.
[[fundamentals-successcodes]]
ifdef::doctype-manpage[]
=== Success Codes
endif::doctype-manpage[]
ifndef::doctype-manpage[]
// Cannot have a section title in a delimited block
**Success Codes**
endif::doctype-manpage[]

// Generated from comment attributes in XML
include::{generated}/api/enums/XrResult.success.comments.adoc[]

// NOTE: this anchor referenced by name in generated validity statements.
[[fundamentals-errorcodes]]
ifdef::doctype-manpage[]
=== Error Codes
endif::doctype-manpage[]
ifndef::doctype-manpage[]
// Cannot have a section title in a delimited block
**Error Codes**
endif::doctype-manpage[]

// Generated from comment attributes in XML
include::{generated}/api/enums/XrResult.error.comments.adoc[]

--

==== Convenience Macros

[open,refpage='XR_SUCCEEDED',desc='Success convenience macro',type='defines',xrefs='XR_FAILED XR_UNQUALIFIED_SUCCESS']
--
include::{generated}/api/defines/XR_SUCCEEDED.adoc[]

A convenience macro that can: be used to test if a function succeeded.
Note that this evaluates to true for all success codes, including a
qualified success such as ename:XR_FRAME_DISCARDED.
--

[open,refpage='XR_FAILED',desc='Failure convenience macro',type='defines',xrefs='XR_SUCCEEDED XR_UNQUALIFIED_SUCCESS']
--
include::{generated}/api/defines/XR_FAILED.adoc[]

A convenience macro that can: be used to test if a function has failed in
some way.
It evaluates to true for all failure codes.
--

[open,refpage='XR_UNQUALIFIED_SUCCESS',desc='Unqualified success convenience macro',type='defines',xrefs='XR_FAILED XR_SUCCEEDED']
--
include::{generated}/api/defines/XR_UNQUALIFIED_SUCCESS.adoc[]

A convenience macro that can be used to test a function's failure.
The dlink:XR_UNQUALIFIED_SUCCESS macro evaluates to true exclusively when
the provided elink:XrResult is equal to ename:XR_SUCCESS (code:0).
--

==== 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.

elink:XrResult code returns may: be added to a given function in future
versions of the specification.
Runtimes must: return only elink: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.

[[fundamentals-handles]]
=== 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 slink:XrInstance, slink:XrSession, and
slink: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 dlink:XR_NULL_HANDLE and other invalid handles passed
where a valid handle is required and return ename: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, dlink:XR_NULL_HANDLE
must: be passed by the application if it does not pass a valid handle.

All functions that take a handle parameter may: return
ename: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 slink:XrSwapchain handle, applications must call
flink:xrCreateSwapchain and pass an slink:XrSession handle.
Thus slink:XrSwapchain is a child handle of slink:XrSession.

[[fundamentals-object-handle-types]]
=== 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
<<fundamentals-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 elink: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.

[open,refpage='XrObjectType',desc='Specify an enumeration to track object handle types',type='enums']
--
include::{generated}/api/enums/XrObjectType.adoc[]

The elink: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 elink:XrObjectType and OpenXR Handle
relationships in the core specification:

[width="80%",cols="<35,<23",options="header"]
|=======================
| elink:XrObjectType                         | OpenXR Handle Type
| ename:XR_OBJECT_TYPE_UNKNOWN               | Unknown/Undefined Handle
| ename:XR_OBJECT_TYPE_INSTANCE              | slink:XrInstance
| ename:XR_OBJECT_TYPE_SESSION               | slink:XrSession
| ename:XR_OBJECT_TYPE_SWAPCHAIN             | slink:XrSwapchain
| ename:XR_OBJECT_TYPE_SPACE                 | slink:XrSpace
| ename:XR_OBJECT_TYPE_ACTION_SET            | slink:XrActionSet
| ename:XR_OBJECT_TYPE_ACTION                | slink:XrAction
|=======================
--

[[fundamentals-buffer-size-parameters]]
=== Buffer Size Parameters

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

Parameter form:

[source,listing]
----
XrResult xrFunction(uint32_t elementCapacityInput, uint32_t* elementCountOutput, float* elements);
----

Structure form:

[source,listing]
----
XrResult xrFunction(XrBuffer* buffer);

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

A "two-call idiom" should: be employed by the application, first calling
fname:xrFunction (with a valid pname:elementCountOutput pointer if in
parameter form), but passing code:NULL as pname:elements and code:0 as
pname: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 pname:elementCountOutput (in
a structure) or the value pointed to by pname:elementCountOutput (as
parameters), a pointer to the allocated buffer should: be passed as
pname:elements, along with the buffer's length in
pname:elementCapacityInput, to a second call to fname:xrFunction to perform
the retrieval of the data.
If the element type of pname:elements is a structure with pname:type and
pname:next fields, the application must: set the pname:type to the correct
value, and must: set pname:next to a valid value.
A valid value for pname:next is generally either code:NULL or another
structure with related data, in which pname:type and pname:next are also
valid, recursively.
(See <<fundamentals-valid-usage-for-structure-pointer-chains>> for details.)

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

.Buffer Size Parameter Behavior
****
* The pname:elementCapacityInput and pname:elementCountOutput arguments
  precede the array to which they refer, in argument order.
* pname:elementCapacityInput specifies the capacity in number of elements of
  the buffer to be written, or code:0 to indicate a request for the required
  buffer size.
* Independent of pname:elementCapacityInput or pname:elements parameters,
  the application must: pass a valid pointer for pname:elementCountOutput if
  the function uses parameter form.
* Independent of pname:elementCapacityInput or pname:elements parameters,
  the function sets pname:elementCountOutput.
* The application may: pass code:0 for the pname:elementCapacityInput
  parameter, to indicate a request for the required array size.
  That is, passing a capacity of code:0 does not return
  ename:XR_ERROR_SIZE_INSUFFICIENT.
  In this case, the following two points apply.
** The function must: set pname:elementCountOutput to the required size in
   number of elements.
** The pname:elements parameter is ignored (any value passed is considered
   valid usage).
* If the pname:elementCapacityInput is non-zero but less than required, the
  function must: set pname:elementCountOutput to the required capacity, and
  must: return ename:XR_ERROR_SIZE_INSUFFICIENT.
  After the function returns, the data in the array pname:elements is
  undefined.
* If the pname:elementCapacityInput is non-zero and the function returns
  successfully, the function sets pname:elementCountOutput to the count of
  the elements that have been written to pname:elements.
* If the function fails for reasons unrelated to the element array capacity,
  the contents of the values of (or pointed to by) pname:elementCountOutput
  and pname:elements are undefined.
* For clarity, if the element array refers to a string (pname:element is of
  type code:char*), pname:elementCapacityInput and pname:elementCountOutput
  refer to the string code:strlen plus code:1 for a code:NULL terminator.
****

Some functions have a given pname:elementCapacityInput and
pname:elementCountOutput associated with more than one element array (i.e.
parallel arrays).
In this case, the capacity/count and all its associated arrays will share a
common prefix.
All of the preceding general requirements continue to apply.

Some functions fill multiple element arrays of varying sizes in one call.
For these functions, the pname:elementCapacityInput,
pname:elementCountOutput, and pname:elements array parameters or fields are
repeated with different prefixes.
In this case, all of the preceding general requirements still apply, with
these additional requirements:

* If the application sets **any** pname:elementCapacityInput parameter or
  field to code:0, the runtime must: treat **all**
  pname:elementCapacityInput values as if they were set to code:0.
* If all pname:elementCapacityInput values are non-zero but **any** is
  insufficient to fit all elements of its corresponding array, the runtime
  must: return ename:XR_ERROR_SIZE_INSUFFICIENT.
  As in the case of the single array, the data in all arrays is undefined
  when ename:XR_ERROR_SIZE_INSUFFICIENT is returned.

[[fundamentals-time]]
=== Time

Time is represented by a 64-bit signed integer representing nanoseconds
(basetype: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.

==== XrTime

[open,refpage='XrTime',desc='Basic type for time',type='basetypes',xrefs='XrDuration']
--
include::{generated}/api/basetypes/XrTime.adoc[]

basetype: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.
basetype: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 basetype: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
basetype:XrTime, and related functions must: return error
ename:XR_ERROR_TIME_INVALID.
Applications must: not initialize such basetype:XrTime fields to a zero
value.
Instead, applications should: always assign basetype: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 basetype: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 basetype: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,
apiext:XR_KHR_win32_convert_performance_counter_time or
apiext:XR_KHR_convert_timespec_time.
--

[[fundamentals-duration]]
=== Duration

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

==== XrDuration

[open,refpage='XrDuration',desc='Bounded range of time',type='basetypes',xrefs='XrTime XR_NO_DURATION XR_INFINITE_DURATION']
--
include::{generated}/api/basetypes/XrDuration.adoc[]

The difference between two timepoints is a duration, and thus the difference
between two basetype:XrTime values is an basetype:XrDuration value.
basetype:XrDuration is a base value type that represents duration as a
signed 64-bit integer, representing the signed number of nanoseconds between
two timepoints.

Functions that refer to durations use basetype:XrDuration as opposed to
basetype:XrTime.
When an basetype:XrDuration is used as a timeout parameter, the constants
dlink:XR_NO_DURATION and dlink:XR_INFINITE_DURATION have special meaning.
A timeout with a duration that refers to the past (that is, a negative
duration) must: be interpreted as a timeout of dlink:XR_NO_DURATION.

The interpretation of zero and negative durations in non-timeout uses is
specified along with each such use.
--

[open,refpage='XR_NO_DURATION',desc='Constant for no duration/immediate timeout',type='defines',xrefs='XrDuration XR_INFINITE_DURATION']
--
include::{generated}/api/defines/XR_NO_DURATION.adoc[]

For the case of timeout durations, dlink:XR_NO_DURATION can: be used to
indicate that the timeout is immediate.
--

[open,refpage='XR_INFINITE_DURATION',desc='Constant for infinite duration/never times out',type='defines',xrefs='XrDuration XR_NO_DURATION']
--
include::{generated}/api/defines/XR_INFINITE_DURATION.adoc[]

dlink:XR_INFINITE_DURATION is a special value that can: be used to indicate
that the timeout never occurs.
--

[[fundamentals-prediction-time-limits]]
=== Prediction Time Limits

Some functions involve prediction.
For example, flink: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 code: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.


[[fundamentals-colors]]
=== Colors

[open,refpage='XrColor3f',desc='Color Vector',type='structs']
--

The slink:XrColor3f structure is defined as:
include::{generated}/api/structs/XrColor3f.adoc[]

.Member Descriptions
****
* pname:r is the red component of the color.
* pname:g is the green component of the color.
* pname:b is the blue 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.
--

[open,refpage='XrColor4f',desc='Color Vector',type='structs']
--

The slink:XrColor4f structure is defined as:
include::{generated}/api/structs/XrColor4f.adoc[]

.Member Descriptions
****
* pname:r is the red component of the color.
* pname:g is the green component of the color.
* pname:b is the blue component of the color.
* pname: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.
--

[[fundamentals-coordinate-system]]
=== Coordinate System

This API uses a Cartesian right-handed coordinate system.

image::images/right-handed.svg[opts=inline, align="center", title="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.

[open,refpage='XrVector2f',desc='Two-dimensional vector',type='structs',xrefs='XrVector3f XrVector4f XrQuaternionf XrPosef']
--
A two-dimensional vector is defined by the slink:XrVector2f structure:
include::{generated}/api/structs/XrVector2f.adoc[]

.Member Descriptions
****
* pname:x is the x coordinate of the vector.
* pname: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.
--

[open,refpage='XrVector3f',desc='Three-dimensional vector',type='structs',xrefs='XrVector2f XrVector4f XrQuaternionf XrPosef']
--
A three-dimensional vector is defined by the slink:XrVector3f structure:
include::{generated}/api/structs/XrVector3f.adoc[]

.Member Descriptions
****
* pname:x is the x coordinate of the vector.
* pname:y is the y coordinate of the vector.
* pname: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.
--

[open,refpage='XrVector4f',desc='Four-dimensional vector',type='structs',xrefs='XrVector2f XrVector3f XrQuaternionf XrPosef']
--

A four-dimensional or homogeneous vector is defined by the slink:XrVector4f
structure:
include::{generated}/api/structs/XrVector4f.adoc[]

.Member Descriptions
****
* pname:x is the x coordinate of the vector.
* pname:y is the y coordinate of the vector.
* pname:z is the z coordinate of the vector.
* pname:w is the w coordinate of the vector.
****

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

[open,refpage='XrQuaternionf',desc='Unit Quaternion',type='structs',xrefs='XrVector2f XrVector3f XrVector4f XrPosef']
--

Rotation is represented by a unit quaternion defined by the
slink:XrQuaternionf structure:
include::{generated}/api/structs/XrQuaternionf.adoc[]

.Member Descriptions
****
* pname:x is the x coordinate of the quaternion.
* pname:y is the y coordinate of the quaternion.
* pname:z is the z coordinate of the quaternion.
* pname:w is the w coordinate of the quaternion.
****

--

[open,refpage='XrPosef',desc='Location and orientation in a space.',type='structs',xrefs='XrVector2f XrVector3f XrVector4f XrQuaternionf']
--

A pose is defined by the slink:XrPosef structure:
include::{generated}/api/structs/XrPosef.adoc[]

.Member Descriptions
****
* pname:orientation is an slink:XrQuaternionf representing the orientation
  within a space.
* pname:position is an slink: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 slink:XrPosef the rotation described by pname:orientation is
always applied before the translation described by pname:position.

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

--

[[fundamentals-common-data-types]]
=== Common Data Types

Some OpenXR data types are used in multiple structures.
Those include the stext:XrVector*f family of types, the spatial types
specified above, and the following categories of structures:

* offset
* extents
* rectangle
* field of view

**Offsets** are used to describe the direction and distance of an offset in
two dimensions.

[open,refpage='XrOffset2Df',desc='Float offset in two dimensions',type='structs',xrefs='XrExtent2Df XrRect2Df']
--

A floating-point offset is defined by the structure:
include::{generated}/api/structs/XrOffset2Df.adoc[]

.Member Descriptions
****
* pname:x is the floating-point offset in the x direction.
* pname:y is the floating-point offset in the y direction.
****

This structure is used for component values that may be real numbers,
represented with single-precision floating point.
For representing offsets in discrete values, such as texels, the integer
variant slink:XrOffset2Di is used instead.

If used to represent physical distances, values must: be in meters.

// empty, included for consistency
include::{generated}/validity/structs/XrOffset2Df.adoc[]
--

[open,refpage='XrOffset2Di',desc='Offset in two dimensions',type='structs',xrefs='XrOffset2Df XrExtent2Di XrRect2Di']
--

An integer offset is defined by the structure:
include::{generated}/api/structs/XrOffset2Di.adoc[]

.Member Descriptions
****
* pname:x is the integer offset in the x direction.
* pname:y is 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
slink:XrOffset2Df is used instead.

// empty, included for consistency
include::{generated}/validity/structs/XrOffset2Di.adoc[]
--

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


[open,refpage='XrExtent2Df',desc='Extent in two dimensions',type='structs',xrefs='XrOffset2Df XrRect2Df']
--

A two-dimensional floating-point extent is defined by the structure:
include::{generated}/api/structs/XrExtent2Df.adoc[]

.Member Descriptions
****
* pname:width is the floating-point width of the extent.
* pname:height is the floating-point height of the extent.
****

This structure is used for component values that may be real numbers,
represented with single-precision floating point.
For representing extents in discrete values, such as texels, the integer
variant slink:XrExtent2Di is used instead.

If used to represent physical distances, values must: be in meters.

The pname:width and pname:height value must: be non-negative.

// empty, included for consistency
include::{generated}/validity/structs/XrExtent2Df.adoc[]
--



[open,refpage='XrExtent3Df',type='structs',desc='Represents the dimensions of an axis-aligned rectangular prism',xrefs='XrExtent2Df XrExtent2Di']
--
The slink:XrExtent3Df structure is defined as:

include::{generated}/api/structs/XrExtent3Df.adoc[]

.Member Descriptions
****
* pname:width is the floating-point width of the extent (x).
* pname:height is the floating-point height of the extent (y).
* pname:depth is the floating-point depth of the extent (z).
****

This structure is used for component values that may be real numbers,
represented with single-precision floating point.

If used to represent physical distances, values must: be in meters.
The width, height, and depth values must: be non-negative.

// empty, included for consistency
include::{generated}/validity/structs/XrExtent3Df.adoc[]
--

[open,refpage='XrExtent2Di',desc='Extent in two dimensions',type='structs',xrefs='XrOffset2Di XrRect2Di']
--

A two-dimensional integer extent is defined by the structure:
include::{generated}/api/structs/XrExtent2Di.adoc[]

.Member Descriptions
****
* pname:width is the integer width of the extent.
* pname:height is the integer height of the extent.
****

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

The pname:width and pname:height value must: be non-negative.

// empty, included for consistency
include::{generated}/validity/structs/XrExtent2Di.adoc[]
--

**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.

[open,refpage='XrRect2Df',desc='Rect in two dimensions, floating-point values',type='structs',xrefs='XrRect2Di XrOffset2Df XrExtent2Df']
--

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

include::{generated}/api/structs/XrRect2Df.adoc[]

.Member Descriptions
****
* pname:offset is the slink:XrOffset2Df specifying the rectangle offset.
* pname:extent is the slink:XrExtent2Df specifying the rectangle extent.
****

This structure is used for component values that may be real numbers,
represented with single-precision floating point.

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

// empty, included for consistency
include::{generated}/validity/structs/XrRect2Df.adoc[]
--


[open,refpage='XrRect2Di',desc='Rect in two dimensions, integer values',type='structs',xrefs='XrRect2Df XrOffset2Di XrExtent2Di']
--

A rectangle with integer values is defined by the structure:

include::{generated}/api/structs/XrRect2Di.adoc[]

.Member Descriptions
****
* pname:offset is the slink:XrOffset2Di specifying the integer rectangle
  offset.
* pname:extent is the slink:XrExtent2Di specifying the integer rectangle
  extent.
****

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

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

[open,refpage='XrSpheref',desc='Describe a sphere bounds',type='structs',xrefs='']
--
An slink:XrSpheref structure describes the center and radius of a sphere
bounds.

include::{generated}/api/structs/XrSpheref.adoc[]

.Member Descriptions
****
* pname:center is an slink:XrPosef representing the pose of the center of
  the sphere within the reference frame of the corresponding slink:XrSpace.
* pname:radius is the finite non-negative radius of the sphere.
****

The runtime must: return ename:XR_ERROR_VALIDATION_FAILURE if pname:radius
is not a finite positive value.

include::{generated}/validity/structs/XrSpheref.adoc[]
--

[open,refpage='XrBoxf',desc='Describe a scene oriented box',type='structs',xrefs='']
--
An slink:XrBoxf structure describes the pose and extents of an oriented box.

include::{generated}/api/structs/XrBoxf.adoc[]

.Member Descriptions
****
* pname:center is an slink:XrPosef defining the center position and
  orientation of the oriented bounding box bound within the reference frame
  of the corresponding slink:XrSpace.
* pname:extents is an slink:XrExtent3Df defining the edge-to-edge length of
  the box along each dimension with pname:center as the center.
****

The runtime must: return ename:XR_ERROR_VALIDATION_FAILURE if width, height
or depth values are negative.

include::{generated}/validity/structs/XrBoxf.adoc[]
--

[open,refpage='XrFrustumf',desc='Describe a scene frustum',type='structs',xrefs='']
--
An slink:XrFrustumf structure describes the pose, field of view, and far
distance of a frustum.

include::{generated}/api/structs/XrFrustumf.adoc[]

.Member Descriptions
****
* pname:pose is an slink:XrPosef defining the position and orientation of
  the tip of the frustum within the reference frame of the corresponding
  slink:XrSpace.
* pname:fov is an slink:XrFovf for the four sides of the frustum where
  `angleLeft` and `angleRight` are along the X axis and `angleUp` and
  `angleDown` are along the Y axis of the frustum space.
* pname:nearZ is the positive distance of the near plane of the frustum
  bound along the -Z direction of the frustum space.
* pname:farZ is the positive distance of the far plane of the frustum bound
  along the -Z direction of the frustum space.
****

The runtime must: return ename:XR_ERROR_VALIDATION_FAILURE if pname:farZ is
less than or equal to zero.

The runtime must: return ename:XR_ERROR_VALIDATION_FAILURE if pname:nearZ is
less than zero.

See slink:XrFovf for validity requirements on pname:fov.

include::{generated}/validity/structs/XrFrustumf.adoc[]
--

[open,refpage='XrUuid',desc='Universally Unique Identifier',type='structs',xrefs='']
--
The slink:XrUuid structure is a 128-bit Universally Unique Identifier and is
defined as:

include::{generated}/api/structs/XrUuid.adoc[]

.Member Descriptions
****
* pname:data is a 128-bit Universally Unique Identifier.
****

The structure is composed of 16 octets, with the size and order of the
fields defined in
link:https://www.rfc-editor.org/rfc/rfc4122.html#section-4.1.2[RFC 4122
section 4.1.2].

include::{generated}/validity/structs/XrUuid.adoc[]
--




[[fundamentals-angles]]
=== 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.


[open,refpage='XrFovf',desc='Field of view',type='structs']
--
Field of view (FoV) is defined by the structure:
include::{generated}/api/structs/XrFovf.adoc[]

.Member Descriptions
****
* pname:angleLeft is the angle of the left side of the field of view.
  For a symmetric field of view this value is negative.
* pname:angleRight is the angle of the right side of the field of view.
* pname:angleUp is the angle of the top part of the field of view.
* pname: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 pname:angleRight minus
pname:angleLeft, and the total vertical field of view is pname:angleUp minus
pname:angleDown.
For a symmetric FoV, pname:angleRight and pname:angleUp will have positive
values, pname:angleLeft will be -pname:angleRight, and pname:angleDown will
be -pname:angleUp.

The angles must: be specified in radians, and must: be between [eq]#-{pi}/2#
and [eq]#{pi}/2# exclusively.

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

[[fundamentals-boolean-values]]
=== Boolean Values

[open,refpage='XrBool32',desc='Boolean value',type='basetypes',xrefs='XR_TRUE XR_FALSE']
--
include::{generated}/api/basetypes/XrBool32.adoc[]

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


.Enumerant Descriptions
****
* ename:XR_TRUE represents a true value.
* ename:XR_FALSE represents a false value.
****
--

[open,refpage='XR_TRUE',desc='True enum/define',type='enums',xrefs='XrBool32 XR_FALSE']
--
include::{generated}/api/enums/XR_TRUE.adoc[]
--

[open,refpage='XR_FALSE',desc='False enum/define',type='enums',xrefs='XrBool32 XR_TRUE']
--
include::{generated}/api/enums/XR_FALSE.adoc[]
--

[[fundamentals-events]]
=== Events

Events are messages sent from the runtime to the application.

[[fundamentals-event-polling]]
==== Event Polling
Events are placed in a queue within the runtime.
The application must: read from the queue with regularity.
Events are read from the queue one at a time via flink:xrPollEvent.
Every type of event is identified by an individual structure type, with each
such structure beginning with an slink:XrEventDataBaseHeader.

[example]
.Proper Method for Receiving OpenXR Event Data
====

[source,C++]
----
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

[open,refpage='xrPollEvent',desc='Polls for events',type='protos',xrefs='XrInstance XrEventDataBuffer']
--
The flink:xrPollEvent function is defined as:

include::{generated}/api/protos/xrPollEvent.adoc[]

.Parameter Descriptions
****
* pname:instance is a valid slink:XrInstance.
* pname:eventData is a pointer to a valid slink:XrEventDataBuffer.
****

flink:xrPollEvent polls for the next event and returns an event if one is
available.
flink:xrPollEvent returns immediately regardless of whether an event was
available.
The event (if present) is unilaterally removed from the queue if a valid
slink:XrInstance is provided.
On return, the pname: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 slink:XrEventDataBuffer pointed to by
pname:eventData.


The runtime must: discard queued events which contain destroyed or otherwise
invalid handles.
The runtime must: not return events containing handles that have been
destroyed or are otherwise invalid at the time of the call to
flink:xrPollEvent.

include::{generated}/validity/protos/xrPollEvent.adoc[]

.Event Descriptions
[cols=",",options="header",]
|=======================================================================
|Event |Description
|slink:XrEventDataEventsLost
|event queue has overflowed and some events were lost
|slink:XrEventDataInstanceLossPending
|application is about to lose the instance
|slink:XrEventDataInteractionProfileChanged
|current interaction profile for one or more top level user paths has changed
|slink:XrEventDataReferenceSpaceChangePending
|runtime will begin operating with updated definitions or bounds for a reference space
|slink:XrEventDataSessionStateChanged
|the application's session has changed lifecycle state
|=======================================================================

--

[open,refpage='XrEventDataBaseHeader',desc='Base header for an event',type='structs',xrefs='xrPollEvent']
--
The slink:XrEventDataBaseHeader structure is defined as:
include::{generated}/api/structs/XrEventDataBaseHeader.adoc[]

.Parameter Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
  This base structure itself has no associated elink:XrStructureType value.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR.
****

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

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

include::{generated}/validity/structs/XrEventDataBaseHeader.adoc[]
--

[open,refpage='XrEventDataBuffer',desc='Event buffer',type='structs',xrefs='xrPollEvent XrEventDataBaseHeader']
--

include::{generated}/api/structs/XrEventDataBuffer.adoc[]

.Parameter Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR.
* pname:varying is a fixed sized output buffer big enough to hold returned
  data elements for all specified event data types.
****

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

An application can: set (or reset) only the pname:type member and clear the
pname:next member of an slink:XrEventDataBuffer before passing it as an
input to flink:xrPollEvent.
The runtime must: ignore the contents of the pname:varying field and
overwrite it without reading it.

A pointer to an slink:XrEventDataBuffer may: be type-cast to an
slink:XrEventDataBaseHeader pointer, or a pointer to any other appropriate
event data based on the pname:type parameter.

include::{generated}/validity/structs/XrEventDataBuffer.adoc[]
--

[open,refpage='XR_MAX_EVENT_DATA_SIZE',desc='Maximum event data buffer size',type='defines',xrefs='XrEventDataBuffer']
--
include::{generated}/api/defines/XR_MAX_EVENT_DATA_SIZE.adoc[]

dlink:XR_MAX_EVENT_DATA_SIZE is the size of slink:XrEventDataBuffer,
including the size of the slink:XrEventDataBuffer::pname:type and
slink:XrEventDataBuffer::pname:next members.
--

===== XrEventDataEventsLost

[open,refpage='XrEventDataEventsLost',desc='Event indicating events were lost',type='structs',xrefs='xrPollEvent XrEventDataBaseHeader']
--

The slink:XrEventDataEventsLost structure is defined as:
include::{generated}/api/structs/XrEventDataEventsLost.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR.
* pname:lostEventCount is the number of events which have overflowed since
  the last call to flink:xrPollEvent.
****

Receiving the slink: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.

include::{generated}/validity/structs/XrEventDataEventsLost.adoc[]
--

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

[[fundamentals-resource-lifetime]]
=== 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
flink:xrCreateSession in `XrGraphicsBinding*` structure should: be kept
alive when the corresponding slink:XrSession handle is valid, and should: be
freed by the application after the slink: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
slink:XrSwapchain handle.
The application should: not keep additional reference counts on any
`ID3D*Texture2D` objects past the lifetime of the slink:XrSwapchain handle,
or make extra reference count decrease after destroying the
slink:XrSwapchain handle.
