Extending Vulkan
New functionality may be added to Vulkan via either new extensions or new versions of the core, or new versions of an extension in some cases.
This chapter describes how Vulkan is versioned, how compatibility is affected between different versions, and compatibility rules that are followed by the Vulkan Working Group.
Functionality Levels
Functionality in Vulkan is divided into several different levels; global, instance-level, physical-device-level, and device-level.
- VkInstance and any objects created from a VkInstance other than VkPhysicalDevice are instance-level.
- VkPhysicalDevice is the only physical-device-level object.
- VkDevice and any objects created from a VkDevice are device-level.
The level of a command is the same as the level of its first parameter - if the first parameter is not a dispatchable handle, it is a global command. Different levels of functionality may be advertised in different ways.
Instance and Device Versions
Starting with Vulkan 1.1, there are separate versions advertised for the Vulkan instance, and for each device supported on the system. This allows a system with multiple devices to advertise all devices at their full capabilities, even if those devices do not support the same version of Vulkan.
The instance version indicates which global and instance-level functionality is supported, while each device version indicates the physical-device-level and device-level functionality supported.
The instance version can be queried by calling
vkEnumerateInstanceVersion.
Querying for this function via vkGetInstanceProcAddr will return
NULL on implementations that only support Vulkan 1.0 functionality.
The device version can be queried by calling
vkGetPhysicalDeviceProperties or vkGetPhysicalDeviceProperties2,
and is returned in VkPhysicalDeviceProperties::apiVersion,
encoded as described in Version Numbers.
Core Versions
The Vulkan Specification is regularly updated with bug fixes and clarifications. Occasionally new functionality is added to the core and at some point it is expected that there will be a desire to perform a large, breaking change to the API. In order to indicate to developers how and when these changes are made to the specification, and to provide a way to identify each set of changes, the Vulkan API maintains a version number.
Version Numbers
The Vulkan version number comprises four parts indicating the variant, major, minor and patch version of the Vulkan API Specification.
The variant indicates the variant of the Vulkan API supported by the implementation. This is always 0 for the Vulkan API.
The major version indicates a significant change in the API, which will encompass a wholly new version of the specification.
The minor version indicates the incorporation of new functionality into the core specification.
The patch version indicates bug fixes, clarifications, and language improvements have been incorporated into the specification.
Compatibility guarantees made about versions of the API sharing any of the same version numbers are documented in Core Versions
The version number is used in several places in the API. In each such use, the version numbers are packed into a 32-bit integer as follows:
- The variant is a 3-bit integer packed into bits 31-29.
- The major version is a 7-bit integer packed into bits 28-22.
- The minor version number is a 10-bit integer packed into bits 21-12.
- The patch version number is a 12-bit integer packed into bits 11-0.
Layers
When a layer is enabled, it inserts itself into the call chain for Vulkan commands the layer is interested in. Layers can be used for a variety of tasks that extend the base behavior of Vulkan beyond what is required by the specification - such as call logging, tracing, validation, or providing additional extensions.
Architecture of the Vulkan Loader Interfaces document for additional information.To enable a layer, the name of the layer should be added to the
ppEnabledLayerNames member of VkInstanceCreateInfo when creating
a VkInstance.
Loader implementations may provide mechanisms outside the Vulkan API for
enabling specific layers.
Layers enabled through such a mechanism are implicitly enabled, while
layers enabled by including the layer name in the ppEnabledLayerNames
member of VkInstanceCreateInfo are explicitly enabled.
Implicitly enabled layers are loaded before explicitly enabled layers, such
that implicitly enabled layers are closer to the application, and explicitly
enabled layers are closer to the driver.
Except where otherwise specified, implicitly enabled and explicitly enabled
layers differ only in the way they are enabled, and the order in which they
are loaded.
Explicitly enabling a layer that is implicitly enabled results in this layer
being loaded as an implicitly enabled layer; it has no additional effect.
The ppEnabledLayerNames and enabledLayerCount members of
VkDeviceCreateInfo are legacy and their values must be ignored by
implementations.
However, for compatibility, only an empty list of layers or a list that
exactly matches the sequence enabled at instance creation time are valid,
and validation layers should issue diagnostics for other cases.
Regardless of the enabled layer list provided in VkDeviceCreateInfo, the sequence of layers active for a device will be exactly the sequence of layers enabled when the parent instance was created.
Extensions
Extensions may define new Vulkan commands, structures, and enumerants.
For compilation purposes, the interfaces defined by registered extensions,
including new structures and enumerants as well as function pointer types
for new commands, are defined in the Khronos-supplied vulkan_core.h
together with the core API.
However, commands defined by extensions may not be available for static
linking - in which case function pointers to these commands should be
queried at runtime as described in Command Function Pointers.
Extensions may be provided by layers as well as by a Vulkan implementation.
Because extensions may extend or change the behavior of the Vulkan API,
extension authors should add support for their extensions to the Khronos
validation layers.
This is especially important for new commands whose parameters have been
wrapped by the validation layers.
See the Architecture of the Vulkan Loader Interfaces document for additional information.
ppEnabledExtensionNames member of VkInstanceCreateInfo when
creating a VkInstance.To enable a device extension, the name of the extension can be added to the
ppEnabledExtensionNames member of VkDeviceCreateInfo when
creating a VkDevice.Physical-Device-Level functionality does not have any enabling mechanism and
can be used as long as the VkPhysicalDevice supports the device
extension as determined by vkEnumerateDeviceExtensionProperties.Enabling an extension (with no further use of that extension) does not
change the behavior of functionality exposed by the core Vulkan API or any
other extension, other than making valid the use of the commands, enums and
structures defined by that extension.Valid Usage sections for individual commands and structures do not currently
contain which extensions have to be enabled in order to make their use
valid, although they might do so in the future.
It is defined only in the Valid Usage for Extensions section.Instance Extensions
Instance extensions add new global or instance-level functionality to the API, outside of the core specification. Instance extensions may also add physical-device-level functionality.
Device Extensions
Device extensions add new device-level functionality to the API, outside of the core specification. If Vulkan 1.1 or VK_KHR_get_physical_device_properties2 is required by the extension, it may also add new physical-device-level functionality.
Extension Dependencies
Some extensions are dependent on other extensions, or on specific core API versions, to function. To enable extensions with dependencies, any required extensions must also be enabled through the same API mechanisms when creating an instance with vkCreateInstance or a device with vkCreateDevice. Each extension which has such dependencies documents them in the appendix summarizing that extension.
If an extension is supported (as queried by vkEnumerateInstanceExtensionProperties or vkEnumerateDeviceExtensionProperties), then required extensions of that extension must also be supported for the same instance or physical device.
Any device extension that has an instance extension dependency that is not enabled by vkCreateInstance is considered to be unsupported, hence it must not be returned by vkEnumerateDeviceExtensionProperties for any VkPhysicalDevice child of the instance. Instance extensions do not have dependencies on device extensions.
If a required extension has been promoted to another extension or to a core API version, then as a general rule, the dependency is also satisfied by the promoted extension or core version. This will be true so long as any features required by the original extension are also required or enabled by the promoted extension or core version. However, in some cases an extension is promoted while making some of its features optional in the promoted extension or core version. In this case, the dependency may not be satisfied. The only way to be certain is to look at the descriptions of the original dependency and the promoted version in the Layers & Extensions and Core Revisions appendices.
vk.xml describing some aspects of promotion,
especially requires, promotedto and deprecatedby attributes of
<extension> tags.
However, the metadata does not yet fully describe this scenario.
In the future, we may extend the XML schema to describe the full set of
extensions and versions satisfying a dependency.
As discussed in more detail for Promotion below, when an extension is promoted it does not mean that a
mechanical substitution of an extension API by the corresponding promoted
API will work in exactly the same fashion; be supported at runtime; or even
exist.Compatibility Guarantees (Informative)
This section is marked as informal as there is no binding responsibility on implementations of the Vulkan API - these guarantees are however a contract between the Vulkan Working Group and developers using this Specification.
Core Versions
Each of the major, minor, and patch versions of the Vulkan specification provide different compatibility guarantees.
Patch Versions
A difference in the patch version indicates that a set of bug fixes or clarifications have been made to the Specification. Informative enums returned by Vulkan commands that will not affect the runtime behavior of a valid application may be added in a patch version (e.g. VkVendorId).
The specification’s patch version is strictly increasing for a given major version of the specification; any change to a specification as described above will result in the patch version being increased by 1. Patch versions are applied to all minor versions, even if a given minor version is not affected by the provoking change.
Specifications with different patch versions but the same major and minor version are fully compatible with each other - such that a valid application written against one will work with an implementation of another.
Minor Versions
Changes in the minor version of the specification indicate that new functionality has been added to the core specification. This will usually include new interfaces in the header, and may also include behavior changes and bug fixes. Core functionality may be marked as legacy in a minor version, but will not be obsoleted or removed.
The specification’s minor version is strictly increasing for a given major version of the specification; any change to a specification as described above will result in the minor version being increased by 1. Changes that can be accommodated in a patch version will not increase the minor version.
Specifications with a lower minor version are backwards compatible with an implementation of a specification with a higher minor version for core functionality and extensions issued with the KHR vendor tag. Vendor and multi-vendor extensions are not guaranteed to remain functional across minor versions, though in general they are with few exceptions - see Obsoletion for more information.
Major Versions
A difference in the major version of specifications indicates a large set of changes which will likely include interface changes, behavioral changes, removal of legacy functionality, and the modification, addition, or replacement of other functionality.
The specification’s major version is monotonically increasing; any change to the specification as described above will result in the major version being increased. Changes that can be accommodated in a patch or minor version will not increase the major version.
The Vulkan Working Group intends to only issue a new major version of the Specification in order to realize significant improvements to the Vulkan API that will necessarily require breaking compatibility.
A new major version will likely include a wholly new version of the specification to be issued - which could include an overhaul of the versioning semantics for the minor and patch versions. The patch and minor versions of a specification are therefore not meaningful across major versions. If a major version of the specification includes similar versioning semantics, it is expected that the patch and the minor version will be reset to 0 for that major version.
Extensions
A KHR extension must be able to be enabled alongside any other KHR extension, and for any minor or patch version of the core Specification beyond the minimum version it requires. A multi-vendor extension should be able to be enabled alongside any KHR extension or other multi-vendor extension, and for any minor or patch version of the core Specification beyond the minimum version it requires. A vendor extension should be able to be enabled alongside any KHR extension, multi-vendor extension, or other vendor extension from the same vendor, and for any minor or patch version of the core Specification beyond the minimum version it requires. A vendor extension may be able to be enabled alongside vendor extensions from another vendor.
The one other exception to this is if a vendor or multi-vendor extension is made obsolete by either a core version or another extension, which will be highlighted in the extension appendix.
Promotion
Extensions, or features of an extension, may be promoted to a new core version of the API, or a newer extension which an equal or greater number of implementors are in favor of.
When extension functionality is promoted, minor changes may be introduced, limited to the following:
- Naming
- Non-intrusive parameter changes
- Feature advertisement/enablement
- Combining structure parameters into larger structures
- Author ID suffixes changed or removed
Extensions that are promoted are listed as being promoted in their extension appendices, with reference to where they were promoted to.
When an extension is promoted, any backwards compatibility aliases which exist in the extension will not be promoted.
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR token defined by that extension
would be promoted to VK_COLOR_SPACE_SRGB_NONLINEAR.
However, the VK_COLORSPACE_SRGB_NONLINEAR_KHR token aliases
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR.
The VK_COLORSPACE_SRGB_NONLINEAR_KHR would not be promoted, because it
is a backwards compatibility alias that exists only due to a naming mistake
when the extension was initially published.Deprecation
Extensions may be marked as deprecated when they are no longer intended to be used by applications under certain conditions. Generally, a new feature will become available to solve the use case in another extension or core version of the API, but it is not guaranteed.
Extensions that are deprecated are listed as being deprecated in their extension appendices, with an explanation of the deprecation and any related features that are relevant.
Obsoletion
Occasionally, an extension will be marked as obsolete if a new version of the core API or a new extension is fundamentally incompatible with it. An obsoleted extension must not be used with the extension or core version that obsoleted it.
Extensions that are obsoleted are listed as being obsoleted in their extension appendices, with reference to what they were obsoleted by.
Aliases
When an extension is promoted or deprecated by a newer feature, some or all
of its functionality may be replicated into the newer feature.
Rather than duplication of all the documentation and definitions, the
specification instead identifies the identical commands and types as
aliases of one another.
Each alias is mentioned together with the definition it aliases, with the
older aliases marked as equivalents.
Each alias of the same command has identical behavior, and each alias of the
same type has identical meaning - they can be used interchangeably in an
application with no compatibility issues.
typedef the older aliases to the promoted types.For promoted command aliases, however, there are two separate command
definitions, due to the fact that the C99 ABI has no way to alias command
definitions without resorting to macros.
Calling either command will produce identical behavior within the bounds of
the specification, and should still invoke the same path in the
implementation.
Debug tools may use separate commands with different debug behavior; to
write the appropriate command name to an output log, for instance.Special Use Extensions
Some extensions exist only to support a specific purpose or specific class
of application.
These are referred to as special use extensions.
Use of these extensions in applications not meeting the special use criteria
is not recommended.
Special use cases are restricted, and only those defined below are used to describe extensions:
| Special Use | XML Tag | Full Description |
|---|---|---|
| CAD support | cadsupport | Extension is intended to support specialized functionality used by CAD/CAM applications. |
| D3D support | d3demulation | Extension is intended to support D3D emulation layers, and applications ported from D3D, by adding functionality specific to D3D. |
| Developer tools | devtools | Extension is intended to support developer tools such as capture-replay libraries. |
| Debugging tools | debugging | Extension is intended for use by applications when debugging. |
| OpenGL / ES support | glemulation | Extension is intended to support OpenGL and/or OpenGL ES emulation layers, and applications ported from those APIs, by adding functionality specific to those APIs. |
Special use extensions are identified in the metadata for each such
extension in the Layers & Extensions appendix, using the
name in the Special Use column above.
Special use extensions are also identified in vk.xml with the short name
in XML Tag column above, as described in the API Extensions
(extension tag) section of the registry schema
documentation.