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

:uri-extprocess: {uri-openxr-registry-root}/specs/1.1/extprocess.html

[[extensions]]
= API Layers & Extensions

This chapter describes required and recommended processes for writing formal
extensions and API layers for the OpenXR API.
It is concerned with mechanical processes and registration, while
fine-grained naming conventions are included in the <<naming,API Naming
Conventions chapter>>.
The organizational processes behind extension creation are in a separate
document, the {uri-extprocess}[OpenXR Working Group Extension Processes].

== Introduction

The Khronos extension registries and extension naming conventions serve
several purposes:

* Avoiding naming collisions between extensions developed by mutually
  unaware parties, both in the extension names themselves, as well as their
  token, command, and type names.
* Allocating enumerant values for tokens added by extensions.
* Creating a defined order between extensions.
  Extensions with higher numbers may have dependencies upon extensions with
  lower numbers, and must define any relevant interactions with
  lower-numbered extensions.
* Provides a central repository for documentation and header changes
  associated with extensions

Vulkan -- on which OpenXR leans heavily for its design -- introduced new
paradigms that required rethinking the existing design practices:

* API layers, and with them a focus on a more open ecosystem where
  non-Khronos members are expected to extend a Khronos API using the API
  layer mechanism.
* Namespaced constants (enumerations) that do not necessarily draw from a
  single global set of token values.

OpenXR continues to use the standards that were adopted by Vulkan, with some
adaptations.

== General Rules/Guidelines

Some general rules to simplify the specific rules below:

* Extensions and API layers must each have a globally unique name.
* All commands and tokens must have a globally unique name.
* Extensions can expose new commands, types, and/or tokens, but API layers
  must not.
** However, API layers can expose their own extensions, which in turn are
   allowed to expose new commands and tokens.
* All extensions must be registered with Khronos.
* Callbacks supplied by the application are discouraged in extensions.
  Prefer polling or event patterns.

[[extensions-naming-conventions]]
== Extension and API Layer Naming Conventions

Extensions and API layers have formal _names_.
These names are used in a variety of places:

* When specifying extensions and API layers to enable in the API.
* As a preprocessor symbol in the `openxr.h` and `openxr_platform.h` header
  files indicating that an extension interface is defined at compile time.
* To control building the OpenXR Specification from asciidoc source
  containing many extension, by explicitly enabling inclusion of one or more
  extensions.

[NOTE]
.Note
====
OpenXR uses a "`single-branch`" model in which extensions can optionally be
included or not from a single set of source documents.
In contrast with Vulkan, OpenXR also limits most extensions to modifying
text only in their own dedicated section: hand-written spec language in the
core of the spec does not conditionally depend on the enabled extensions.
The auto-generated files (for implicit valid usage, prototypes, etc.) do
reflect the enabled extensions.
However, these mentions are automatic and do not require any manual
maintenance outside of normal maintenance of the XML registry.

It is possible that some vendors will choose to maintain their own extension
branches -- vendors are not required to use the Khronos OpenXR Gitlab.
====

There is a rigid syntax for these names:

* Extensions are named with the syntax: `XR_<AUTHOR>_<name>`.
* API layers are named with the syntax: `XR_APILAYER_{AUTHOR|FQDN}_<name>`.

Both extensions and API layer names include a `XR_` prefix, as described in
the <<naming-preprocessor,Preprocessor Defines>> section above.
In addition, API layers add the `APILAYER_` prefix.

Extension and API layer names must both be valid C language identifiers.

[[extensions-naming-conventions-name-strings]]
=== Extension and API Layer Name Strings

The `<name>` portion of extension and API layer names is a concise name
describing the purpose or functionality of the extension or API layer.
The underscore (`_`) character is used as a delimiter between words.
Every character of the name must be in lower case.


=== Author IDs

Extension and API layer names also contain an _author ID_, indicated by
`AUTHOR` above, identifying the author of the extension/API layer.
This ID is a short, capitalized string identifying an author, such as a
Khronos member developing OpenXR implementations for their devices, or a
non-Khronos developer creating OpenXR API layers.
Author IDs must be registered with Khronos.

As with Vulkan, some authors have platform communities they wish to
distinguish between, and can register additional author IDs for that
purpose.
In the case of Vulkan, for example, Google has separate Android and Chrome
communities.

Details on how to register an author ID are provided below.
API layer authors not wishing to register an author ID with Khronos can
instead use a fully-qualified domain name (FQDN) as the ID.
The FQDN should be a domain name owned by the author.
FQDNs cannot be used for extensions, only for API layers.

* The following are examples of extension and API layer names, demonstrating
  the above syntax:
** Extension names all use the base prefix `XR_`.
** Khronos-ratified extensions add the reserved author ID `KHR`, and will
   use the prefix `XR_KHR_`.
** The following author IDs are reserved and must not be used:
*** `XR` - To avoid confusion with the top-level `XR_` prefix.
*** `OPENXR` - To avoid confusion with the name of the OpenXR API.
*** `LAYER` - Reserve similar to `APILAYER`.
*** `APILAYER` - To avoid confusion with the higher-level "`APILAYER`"
    prefix.
*** `KHRONOS` - To avoid confusion with the Khronos organization.
** Multi-author extensions that have not been ratified by Khronos (those
   developed via cooperation between, and intended to be supported by two or
   more registered authors) add the special author ID `EXT` to the base
   prefix, and will use the prefix `XR_EXT_`.
** Traditional author-specific extensions developed by one author (or one
   author in cooperation with non-authors) add the author ID to the base
   prefix.
   For example, NVIDIA will use the prefix `XR_NV_`, and Valve will use the
   prefix `XR_VALVE_`.
   Some authors can have additional registered author IDs for special
   purposes.
   For example, an Android extension developed by Google - but part of an
   Android open-source community project, and so not a proprietary Google
   extension - will use the author ID `ANDROID`.
** API Layer names follow the same conventions as extensions, but use the
   base prefix `XR_APILAYER_`.
** Because API layers need not be registered with Khronos, an alternative
   mechanism is needed to allow creating unique API layer names without
   registering an author ID.
   API layer authors that prefer not to register an author ID can instead
   use a fully-qualified domain name (FQDN) in reverse-order as an author
   ID, replacing `.` (period) with `_` (underscore) characters.
   The restriction that API layer names must be valid C identifiers means
   that some FQDNs cannot be used as part of API layer names.

[source,listing]
.Example
----
// Khronos extension name
XR_KHR_opengl_enable

// Multivendor extension name
XR_EXT_debug_utils

// Vendor API layer name using author ID LUNARG
XR_APILAYER_LUNARG_api_dump

// API layer name using the FQDN www.3dxcl.invalid instead of an author ID
XR_APILAYER_invalid_3dxcl_www_ourlayer
----

[NOTE]
.Note
====
To avoid linking to a nonexistent domain, the reserved TLD `.invalid` is
used in the example above.
====

[[extensions-naming]]
== Extension Function, Type, and Token Naming Conventions

Extensions may add new functions, types, and tokens, or collectively
"`entities`", to the OpenXR API.
These entities are given globally unique names by appending the author ID
defined above for the extension name as described in the
<<naming-extension-identifiers, Extension Identifier Naming Conventions>>
section above.

[[extensions-api-registry]]
== The OpenXR Registry

The canonical definition of the OpenXR APIs is kept in an XML file known as
the *OpenXR registry*.
The registry is kept in `specification/registry/xr.xml` of the
link:{uri-github-openxr-docs}[KhronosGroup/OpenXR-Docs] project.

The registry contains reserved author IDs, core and extension interface
definitions, definitions of individual commands and structures, and other
information which must be agreed on by all implementations.
The registry is used to maintain a single, consistent global namespace for
the registered entities, to generate the Khronos-supplied `openxr.h` and
related headers, and to create a variety of related documentation used in
generating the API specification and reference pages.
In addition, the broader OpenXR community also consumes this XML registry to
create tools, bindings, and other OpenXR-related software.

[[extensions-author-ID]]
== Registering an Author ID with Khronos

Previous to Vulkan, Khronos APIs could only officially be modified by
Khronos members.
In an effort to build a more flexible platform, OpenXR allows non-Khronos
developers to extend and modify the API via API layers and extensions in the
same manner as Khronos members.
However, extensions must still be registered with Khronos.
A mechanism for non-members to register API layers and extensions is
provided.

Extension authors will be able to create an account on GitHub and register
an author ID with Khronos through the
link:{uri-github-openxr-docs}[KhronosGroup/OpenXR-Docs] project.
The author ID must be used for any extensions that author registers.
The same mechanism will be used to request registration of extensions or API
layers with Khronos, as described below.

To reserve an author ID, propose a merge request against
<<extensions-api-registry,`xr.xml`>>.
The merge must add a `<tag>` XML tag and fill in the `name`, `author` and
+contact+ attributes with the requested author ID, the author's formal name
(e.g. company or project name), and contact email address, respectively.
The author ID will only be reserved once this merge request is accepted.

Please do not try to reserve author IDs which clearly belong to another
existing company or software project which may wish to develop OpenXR
extensions or API layers in the future, as a matter of courtesy and respect.
Khronos may decline to register author IDs that are not requested in good
faith.

[[extensions-vendor-id]]
== Registering a Vendor ID with Khronos

OpenXR implementers must report a valid vendor ID for their implementation
when queried by fname:xrGetSystemProperties, as described in the
link:{uri-openxr-ratified-spec}[OpenXR API Specification].
If there is no valid USB vendor ID defined for the physical device,
implementations must obtain a Khronos vendor ID.

Khronos vendor IDs are reserved in a similar fashion to
<<extensions-author-ID,author IDs>>.
While vendor IDs are not directly related to API extensions, the reservation
process is very similar and so is described in this section.

To reserve an Khronos vendor ID, you must first have a Khronos author ID.
Propose a merge request against <<extensions-api-registry,`xr.xml`>>.

The merge must add a `<vendorid>` tag and fill in the `name` and `id`
attributes.
The `name` attribute must be set to the author ID.
The `id` attribute must be the first sequentially available ID in the list
of `<vendorid>` tags.
The vendor ID will be reserved only once this merge request has been
accepted.

Please do not try to reserve vendor IDs unless you are making a good faith
effort to develop an OpenXR implementation and require one for that purpose.

== Registering Extensions

Extensions must be registered with Khronos.
Registration means:

* Receiving an extension number.
* Adding the extension name to the list in `xr.xml` and appearing on the
  Khronos registry website, which will link to associated documentation
  hosted on Khronos.
* For extensions which add to the OpenXR API, including definitions of those
  additions to `xr.xml`.

Registration for Khronos members is handled by filing a merge request in the
internal gitlab repository against the branch containing the core
specification against which the extension will be written.
The merge must modify `xr.xml` to define extension names, API interfaces,
and related information.
Registration is not complete until the registry maintainer (the
specification editor) has validated and accepted the merge.

Non-Khronos members who want to create extensions must register with Khronos
by creating a GitHub account, and registering their author ID and/or FQDNs
to that account.
They can then submit new extension registration requests by proposing merges
to `xr.xml`.
On acceptance of the merge, the extension will be registered, though its
specification need not be checked into the Khronos GitHub repository at that
point.

The registration process can be split into several steps to accommodate
extension number assignment prior to extension publication:

* Acquire an extension number.
  This is done by proposing a merge request against `xr.xml` similarly to
  how <<extensions-author-ID,author IDs are reserved>>.
  The merge should add a new `<extension>` tag at the end of the file with
  attributes specifying the proposed extension `name`, the next unused
  sequential extension `number`, and specifying `supported="disabled"`.
  The extension number will be reserved only once this merge request is
  accepted.
  See the <<mr-reserve-extension-number,example>> below.
* Develop and test the extension using the registered extension number.
* Publish the extension to Khronos using the previously registered extension
  number, by submitting merge requests defining the changes specific to the
  extension.
  Changes to both the specification source, and to `xr.xml` will be needed.
** Extension changes to the specification source must be limited to the
   added specification section as described in the
   <<extensions-documenting,Documenting Extensions>> section.
   (Their entities may be included in generated files incorporated into the
   final specification output document.) If, in a rare exception, such
   changes to the core source do need to occur, they must be protected by
   asciidoc conditionals.
** Changes to `xr.xml` must define the extension interfaces in the
   `<extension>` block, and must also change the `supported` attribute value
   of the `<extension>` to `supported="openxr"`.
** When publishing an extension, mark it as enabled by proposing a merge
   request changing the `supported` attribute value of the `<extension>` to
   `supported="openxr"`.
   Once the merge is accepted and the corresponding updated header with the
   new extension interface is committed to the intended release branch,
   publication is complete.
** Publishing on the <<openxr-docs,Khronos public GitHub repository>> is
   preferred whenever possible.
   Khronos members may instead create branches on Khronos' internal gitlab
   server, but those changes will eventually be mirrored to GitHub upon
   publication.
** Once the merge request defining an extension has been accepted into the
   intended release branch, publication is complete - although it may not be
   visible on GitHub until the next regular core Specification update is
   pushed out.

[[mr-reserve-extension-number]]
[example]
.Merge Request Reserving an Extension Number
====
The following is an example of what the contents of the change inside an MR
requesting an extension number reservation should look like:

[source,diff]
----
      <extension name="XR_KHR_android_create_instance" number="9" type="instance"
                 supported="openxr">
          <require>
              <enum value="1" name="XR_KHR_android_create_instance_SPEC_VERSION"/>
              <enum value="&quot;XR_KHR_android_create_instance&quot;"
                    name="XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME"/>
              <enum offset="0"  extends="XrStructureType"
                    name="XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR"/>
              <type name="XrInstanceCreateInfoAndroidKHR"/>
          </require>
      </extension>
+     <extension name="XR_KHR_extension_10" number="10"
+                contact="Rylie Pavlik @rpavlik" supported="disabled">
+        <require>
+           <enum value="1" name="XR_KHR_extension_10_SPEC_VERSION"/>
+           <enum value="&quot;XR_KHR_extension_10&quot;"
+                 name="XR_KHR_EXTENSION_10_EXTENSION_NAME"/>
+        </require>
+     </extension>
</extensions>
----

**NOTE:** Spacing has been changed to make it more readable in this
document.
When making your change, please follow the layout spacing in the actual
`xr.xml` document.

In the above example, the lines marked with '+' are the lines added by the
change.
Notice how the pending extension is now the last extension in the file and
`supported` is set to "disabled".
The latter detail ensures the extension isn't used by any of the tools which
use the `xr.xml` as a source.

====

[[extensions-documenting]]
== Documenting Extensions

Extensions are documented as added chapters to the OpenXR specification.
Changes specific to an extension are protected by asciidoc conditionals.
The changes are only visible in generated documentation when the
Specification is built with an asciidoc attribute of that name defined.
However, specifications generated from this branch will only include the
extension when the Makefile is invoked appropriately.

Generally, extensions do not add conditional text to the core of the
specification, although the generated files included in the core of the
specification automatically reflect the extensions enabled at build time.

[NOTE]
.Note
====
This is referred to as the "`single-branch`" model, in contrast to an
earlier model used by Vulkan where each extension lived in a separate branch
from the Vulkan 1.0 core Specification source.
====

For example, the `XR_KHR_opengl_enable` extension is documented in the
`main` branch of the GitHub
link:{uri-github-openxr-docs}[KhronosGroup/OpenXR-Docs] project and internal
GitLab.
However, specifications generated from this branch will only include the
extension when the Makefile is invoked appropriately.

Except for extraordinary cases, language defining extensions should be
localized into:

* modification of parts of `xr.xml` defining the extension interfaces.
* one or a small number of asciidoc include files.
  One must be named
  `specification/sources/chapters/extensions/__author__/__extension_name__.adoc`
  where `__author__` is the author/vendor tag in all lowercase, and
  `__extension_name__` is the extension name without the leading `XR_` and
  in all lowercase.
  This file will be conditionally and automatically included in the table of
  contents and generated specification documents and reference pages if
  enabled during a specification build.
  See below for more details.

=== Extension Documentation Names/Locations

All extension specification documentation can be found under the
`specification/sources/chapters/extensions` folder and should end with the
asciidoc extension (`.adoc`) The extension documentation should be named
based on the lower-case extension name, and without the `XR_` prefix.
For example, the specification documentation for the `XR_KHR_opengl_enable`
extension is called `khr_opengl_enable.adoc`.

Extensions are grouped in individual sub-folders based on the lower-case
author ID.
For example, Khronos ('KHR') extensions are grouped under the sub-folder
`khr`.
Therefore, the asciidoc files for the `XR_KHR_opengl_enable` extension can
be found in the `specification/sources/chapters/extensions/khr/` folder.
Likewise, if Valve Software were to create an extension called
`XR_VALVE_new_extension`, the documentation for that extension should be
placed in the 'valve' sub-folder under
`specification/sources/chapters/extensions/`.


=== Extension Documentation Conditions

If the extension asciidoc file for an extension is named correctly, and
placed in the correct folder, then the specification scripts will
automatically find that file when generating the requested version(s) of the
specification.
However, the extension file is not included in the specification unless the
following criteria have been met:

* The extension sections have been properly added to the registry (xr.xml)
  file.
* The extension has been enabled in the registry file by setting the
  `supported` field to a value of "openxr"
* The specification is built with the extension enabled
** NOTE: You may use the `specification/makeAllExts` shell script to build
   the specification with all extensions enabled.

Once these criteria have been met, the extension file will be included in
the specification build.


=== Specification and Extension Documentation Requirements

To create an extension, use an existing extension (such as
`XR_KHR_opengl_enable`) as an example, making sure to keep the following in
mind:

* In the preamble to the appendix, start with an asciidoc include of the
  automatically generated metadata information.
** This information includes the extension name string, type, number, and
   revision from xr.xml.
* Following the `include`, add as many of the following sections as are
  meaningful:
** Last Modified Date
** IP Status - Such as No known IP claims.
** Interactions and External Dependencies
*** May include requirements or interactions with optional OpenXR features
    and interactions (other than strictly requiring) with other OpenXR
    extensions.
*** Dependencies on OpenXR versions and extensions are automatically
    populated from the data in the registry XML.
** Contributors - Names and corporate affiliations of people who have made
   significant direct contributions to this extension.
** Overview - a brief introduction
** New Object Types - leave empty if none.
** New Flag Types - leave empty if none.
** New Enum Constants - leave empty if none.
   This is where you may add something like the following for additions to
   core enumerations - most often `XrStructureType`.
+
--
[source,asciidoc]
.Example Markup
----
*New Enum Constants*

elink:XrStructureType enumeration is extended with:

* ename:XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR
----
--
+
** New Enums - leave empty if none.
** New Structures - leave empty if none.
** New Functions - leave empty if none.
** Issues
** Version History - this must be formatted exactly as found in existing
   specifications, and updated when a "substantial" change is made.
   It is parsed by `xml_consistency` and cross-checked against the version
   enum in the XML registry.
+
--
[source,asciidoc]
.Example Markup
----
*Version History*

* Revision 1, 2019-07-12 (Rylie Pavlik, Collabora, Ltd.)
** A brief revision description goes here.
   Mark up entity names with back-ticks instead of the normal macros
   in the version history to prevent errors in case future revisions rename things.
* Revision 2, 2019-07-12 (Rylie Pavlik, Collabora, Ltd.)
** ... etc. ...
----
--
+
* Extensions usually make significant additions and changes to the OpenXR
  specification.
  However, these sections are **kept in the extension appendix** and not
  directly integrated into the spec.
  This is to keep the core specification text clean of any extensions.
* In every other place where the extension alters the behavior of the core
  Specification, clearly indicate the section in the extension appendix what
  is modified and in what way.
  Since the changes are not made to the specification language directly,
  care must be taken to make it abundantly clear what new behavior occurs
  when the extension is enabled versus when it is not.
* If two extensions interact, the asciidoc conditionals must be carefully
  structured so as to properly document the interactions if the
  specification is built with both extensions.
  Asciidoc conditionals allow "and" and "or" constructs (see:
  http://asciidoctor.org/docs/user-manual/#conditional-preprocessor-directives
  and
  http://asciidoctor.org/docs/user-manual/#checking-multiple-attributes-ifdef-and-ifndef-only).
+
--
[source,asciidoc]
.Example Markup
----
\ifdef::XR_KHR_foo[]
... discussion of XR_KHR_foo ...
\ifdef::XR_KHR_fum[]
... discussion of interactions between XR_KHR_foo and XR_KHR_fum ...
\endif::XR_KHR_fum[]
\endif::XR_KHR_foo[]

\ifdef::XR_KHR_fum[]
... discussion of XR_KHR_fum ...
\endif::XR_KHR_fum[]
----
--
* In cases where a new extension (A) modifies both core and an existing
  extension (B), if the new extension (A) becomes part of the core at a
  future release (i.e. is no longer an extension), the portion of the new
  extension that modified the existing extension (B) effectively becomes
  part of that existing extension.
  Thus, at the new core release, enabling the pre-existing extension (B)
  also enables the functionality that was previously enabled by enabling the
  previously-new extension (A).
* For vendor extensions, changes made to existing core Specification source
  files and to `xr.xml` all fall under the Contributor License Agreement.
  Vendors may: mark their own copyright on files added, and must: ensure
  that a copyright statement and SPDX license identifier tag indicating
  CC-BY-4.0 terms are present.
* In most cases, there will be one new file added to the specification:
  `extensions/__vendor__/__extension_name__.adoc`.
  If you need more than one new file in the `extensions/` directory, create
  a subdirectory named with the extension name and place the new files
  there.

=== Extension Lifecycle

Extensions have a very well-defined lifecycle.

Extensions start out as being "in development".
While in development, extensions can change greatly and are considered more
of a prototype and not intended for final use.
Once extension authors believe they are finished, the extension is approved
by the Khronos working group and becomes one of an "active" extension.
As OpenXR grows, new versions of the API will be released.

At this point, extensions can stay "active" for a while, but eventually each
extension will eventually go down one of 3 paths:

 1. An extension can be "promoted" into the core API
 2. An extension can be replaced (or "deprecated") by a newer extension
 3. An extension can be "retired" and have all support removed

==== Extension Promotion

When the OpenXR Working Group decides to release a new major or minor
version of the OpenXR API, they typically will meet and decide to pull in a
set of "active" extensions into the core API.
This process of pulling in extensions into the core API is called
`promotion`.
Extensions that are part of this process become "promoted" extensions.

An example of this behavior pattern in Vulkan is the release of Vulkan 1.1.
Vulkan 1.1 was created by pulling in many of the "active" Vulkan extensions
that were originally added to extend Vulkan 1.0.

Once an extension has been promoted, the original extension commands and
types still exist and may: still be used, especially when used with an older
version of the API.
However, if applications use the newer version of the API into which the
extension was promoted, the application should: switch to using the new core
commands and types.

Extension promotion is indicated in the OpenXR registry by adding the
"promotedto" tag to the extension definition header.
The value of the "promotedto" field should indicate what it was promoted
into.
For example, if the extension was promoted into OpenXR as part of OpenXR
1.1, the value should read `promotedto="XR_VERSION_1_1"`.

For example:

```
<extension name="XR_KHR_loader_init" number="89" type="instance" supported="openxr" promotedto="XR_VERSION_1_1">
   <require>
      <!-- ... -->
   </require>
</extension>
```

==== Extension Deprecation

Extensions are often developed because an author believes that the provided
functionality is the best way to perform some action or expose a new
feature.
However, due to the flexible nature of the API, someone may develop a better
way to expose the feature.
When this happens, the group may want to flag the original functionality in
some way that indicates it is no longer the best way to access the feature.
The way OpenXR does this is by labeling the extension as "deprecated".
"Deprecated" extensions are still exposed by at least some of the available
runtimes, but may disappear at some point in the future.
Because of this, runtimes may emit a warning indicating the application
should: be modified to use the newer behavior.

Extension deprecation is indicated in the OpenXR registry by adding the
"deprecatedby" tag to the extension definition header.
The value of the "deprecatedby" field should indicate which
extension/feature should now be used.
For example, if the `XR_KHR_metal_enable` extension was replaced by the
`XR_KHR_metal_enable2` extension, the value should read
`deprecatedby="XR_KHR_metal_enable2"`.

For example:

```
<extension name="XR_KHR_metal_enable" number="30" type="instance" protect="XR_USE_GRAPHICS_API_METAL" supported="openxr" deprecatedby="XR_KHR_metal_enable2">
   <require>
      ....
   </require>
</extension>
```

To make it clear which extensions are "active" and which are "deprecated",
all "deprecated" extensions are listed in a separate extension list in the
specification output documents.

==== Extension Retirement

Sometimes, extension functionality because useless.
This could be because hardware or software has changed in some way since the
extension was originally created that now makes the intended behavior
undesirable.
In this case, extension support will disappear from all runtimes and most
applications.
If this occurs, then when the OpenXR Working Group develops a new major
version of the OpenXR API, they may: choose to "retire" an extension and
remove it from that version of the specification.
From that point forward, the extension is considered "retired" and must: not
be used.

== Assigning Extension Token Values

Extensions can define their own enumeration types and assign any values to
their enumerants that they like.
Each enumeration has a private namespace, so collisions are not a problem.
However, when extending existing enumeration objects with new values, care
must be taken to preserve global uniqueness of values.
Enumerations which define new bits in a bitmask are treated specially as
described in <<extensions-reserving-bitmask-values,Reserving Bitmask
Values>> below.

Each extension is assigned a range of values that can be used to create
globally-unique enum values.
Most values will be negative numbers, but positive numbers are also
reserved.
The ability to create both positive and negative extension values is
necessary to enable extending enumerations such as etext:XrResult that
assign special meaning to negative and positive values.
Therefore, 1000 positive and 1000 negative values are reserved for each
extension.
Extensions must not define enum values outside their reserved range without
explicit permission from the owner of those values (e.g. from the author of
another extension whose range is infringed on, or from the Khronos Registrar
if the values do not belong to any extension's range).

[NOTE]
.Note
====
Typically, extensions use a unique offset for each enumeration constant they
add, yielding 1000 distinct token values per extension.
Since each enumeration object has its own namespace, if an extension needs
to add many enumeration constant values, it can reuse offsets on a per-type
basis.
====

The information needed to add new values to the XML are as follows:

* The **extension name** (e.g. `XR_KHR_opengl_enable`) that is adding the
  new enumeration constant.
* The existing enumeration **type** being extended (e.g.
  stext:XrStructureType).
* The name of the new enumeration **token** being added (e.g.
  etext:XR_TYPE_INSTANCE_CREATE_INFO).
* The **offset**, which is an integer between 0 and 999 relative to the base
  being used for the extension.
* The **direction** may be specified to indicate a negative value
  (`dir="-"`) when needed for negative etext:XrResult values indicating
  errors, like etext:XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR.
  The default direction is positive, if not specified.

Implicit is the registered number of an extension, which is used to create a
range of unused values offset against a global extension base value.
Individual enumerant values are calculated as offsets in that range.
Values are calculated as follows:

* [eq]#_base_value_ = 1000000000#
* [eq]#_range_size_ = 1000#
* [eq]#enum_offset(_extension_number_, _offset_) = _base_value_ {plus}
  (_extension_number_ - 1) {times} _range_size_ + _offset_#
* Positive values: [eq]#enum_offset(_extension_number_, _offset_})#
* Negative values: [eq]#-enum_offset(_extension_number_, _offset_})#

The exact syntax for specifying extension enumerant values is defined in the
`readme.pdf` specifying the format of `xr.xml`, and extension authors can
also refer to existing extensions for examples.

If an extension becomes part of core, the enumerant values should remain the
same as they were in the original extension, in order to maintain binary
compatibility with existing software.


[[extensions-reserving-bitmask-values]]
=== Reserving Bitmask Values

Enumerants which define bitmask values are a special case, since there are
only a small number of unused bits available for extensions.
For core OpenXR API and KHR extension bitmask types, reservations must be
approved by a vote of the OpenXR Working Group.
For EXT and vendor extension bitmask types, reservations must be approved by
the listed contact of the extension.
Bits are not reserved, and must not be used in a published implementation or
specification until the reservation is merged into
<<extensions-api-registry,+xr.xml+>> by the registry maintainer.
In general, this is not done in any future extensions: create a chained
structure with an entirely new bitmask field instead.
See also
https://www.khronos.org/registry/OpenXR/specs/1.1/extprocess.html#bitmasks[the
Extension Process discussion of this].


== Required Extension Tokens

In addition to any tokens specific to the functionality of an extension, all
extensions must define two additional tokens.

* `XR_extname_SPEC_VERSION` is an integer constant which is the revision of
  the extension named `XR_extname` (where `extname` is the capitalization of
  the actual extension name) in `openxr.h` or `openxr_platform.h` (the
  latter is used if a `protect` attribute is specified for the extension).
  This value begins at 1 with the initial version of an extension
  specification, and is incremented when changes are made.
  Note that the revision of an extension defined in `openxr.h` and the
  revision supported by the OpenXR implementation (the pname:specVersion
  field of the slink:XrExtensionProperties structure corresponding to the
  extension and returned by one of the
  <<extended-functionality-extensions,extension queries>>) may differ.
  The revision value indicates a patch version of the extension
  specification, and differences in this version number maintain full
  compatibility, as defined in the
  link:html/xrspec.html#fundamentals-versionnum[API Version Numbers and
  Semantics] section of the link:{uri-openxr-ratified-spec}[OpenXR API
  Specification].

[NOTE]
.Note
====
Any changes requiring the addition or removal of a type or command should be
done by creating a new extension.
The resulting extension should take care to include the appropriate
dependency information on the original extension.
====

* `XR_EXTNAME_EXTENSION_NAME` is a string constant which is the name of the
  extension (where `EXTNAME` is all upper-case)

For example, for the extension `XR_KHR_opengl_enable`, at the time of
writing the following definitions were in effect:

[source,c]
----
#define XR_KHR_opengl_enable_SPEC_VERSION 8
#define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable"
----


== Extension Handles, Objects, Enums, and Typedefs

Expanding on previous discussion, extensions can add values to existing
enums; and can add their own commands, enums, typedefs, etc.
This is done by adding to <<extensions-api-registry,+xr.xml+>>.
All such additions will be included in the `openxr.h` and related headers
supplied by Khronos.

If the extension adds a new handle to OpenXR, a corresponding value must: be
added to ename:XrObjectType in order to allow components to identify and
track objects of the new type.

The new enumeration value must: conform to the naming defined in the
<<extension-enumerant-names,Extension Enumerant Names>> section.
In this case, the type's etext:Xr prefix is replaced with the enum prefix
etext:XR_OBJECT_TYPE_, and the rest of the handle name is converted as
described in that section.

[source,asciidoc]
.Conversion of Handle to XrObjectType Examples:
----
 XrInstance               -> XR_OBJECT_TYPE_INSTANCE
 XrDebugUtilsMessengerEXT -> XR_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT
----

[NOTE]
.Note
====
Application developers are encouraged to be careful when using `switch`
statements with OpenXR API enums.
This is because extensions can add new values to existing enums.
The use of a `default:` statement, within a `switch`, may avoid future
compilation issues.
====

[[extension-function_prototypes]]
== Extension Function Prototypes

Function pointer declarations and function prototypes for all core OpenXR
API commands are included the `openxr.h` header file.
These come from the official XML specification of the OpenXR API hosted by
Khronos.

Function pointer declarations are also included in the `openxr.h` and
`openxr_platform.h` file for all commands defined by registered extensions.
**No** extension functions are part of the OpenXR ABI, and so by default, as
of OpenXR 1.0.15, extension function prototypes are not exposed in
`openxr.h` or `openxr_platform.h` unless a configuration define is enabled.

An extension can be considered platform specific, in which case its
interfaces appear in `openxr_platform.h` and are protected by `#ifdefs`.


== Accessing Extension Functions from Programs

flink:xrGetInstanceProcAddr can be used in order to obtain function pointer
addresses for core and extension commands (per the description in the
"`Command Function Pointers`" section of the
link:{uri-openxr-ratified-spec}[OpenXR API Specification]).
Different OpenXR API loaders can choose to statically export functions for
some or all of the core OpenXR API commands, and can statically export
functions for some or all extension commands.
If a loader statically exports a function, an application can link against
that function without needing to call one of the ftext:xrGetInstanceProcAddr
commands.

[NOTE]
.Note
====
The official OpenXR API loader for Android, Linux, and Windows exports
functions for all core OpenXR API functions, and no extension functions.
====


[[extensions-interactions]]
== Extension Interactions

Extensions can: modify existing commands in one or more of the following
ways:


=== Extending Command Structures

Extensions modifying the behavior of existing commands should provide
additional parameters by using the pname:next field of an existing
structure, pointing to a new structure defined by the extension, as
described in the "`Valid Usage`" section of the
link:{uri-openxr-ratified-spec}[OpenXR API Specification].
Extension structures defined by multiple extensions affecting the same
structure can be chained together in this fashion.
Any structure which can be chained in this fashion must begin with the
following two members:

["source","c++",title=""]
----
XrStructureType        type;
const void*            next;
----

If the structure is an output parameter, the pname:next pointer should be
non-`const`.

It is in principle possible for extensions to provide additional parameters
through alternate means, such as passing a handle parameter to a structure
with a pname:type defined by the extension, but this approach is discouraged
and should not be used.

When chaining multiple extensions to a structure, the implementation will
process the chain starting with the base parameter and proceeding through
each successive chained structure in turn.
Extensions should be defined to accept any order of chaining, and must
define their interactions with other extensions such that the results are
deterministic.
If an extension needs a specific ordering of its extension structure with
respect to other extensions in a chain to provide deterministic results, it
must define the required ordering and expected behavior as part of its
specification.

Validation of such extended structure chains is automatically generated from
the registry, as described in the description of attr:structextends in
link:{uri-schema-vulkan}[the registry schema document for Vulkan].

Take the following XML structure example:

```
<type category="struct" name="XrNewStructKHR" structextends="XrSessionCreateInfo">
   ...
</type>
```

In this case, the above block is indicating that the structure
`XrNewStructKHR` is valid for use in the pname:next chain of the
slink:XrSessionCreateInfo structure.


=== Extending Command Returns

Sometimes, extensions may: add additional return values to an existing
OpenXR command.
This is done by adding a special tag in the new extension's section of the
OpenXR registry file (`xr.xml`) in the following fashion:

```
<extend type="command" name="[command_name]" successcodes="[success_return_list]" errorcodes="[error_return_list]"/>
```

Where:

* `[command_name]` is the name of the command you are extending
** e.g. flink:xrCreateInstance, flink:xrDestroyInstance, etc.
* `successcodes="[success_return_list]"` is optional and will extend the
  command's existing `successcodes` values with the provided comma-delimited
  `[success_return_list]` values, but only when this extension is enabled as
  part of the specification build process.
** e.g. `successcodes="XR_SWAPCHAIN_IN_USE`
* `errorcodes="[error_return_list]"` is optional and will extend the
  command's existing `errorcodes` values with the provided comma-delimited
  `[error_return_list]` values, but only when this extension is enabled as
  part of the specification build process.
** e.g. `errorcodes="XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR`
