Vulkan-Docs/doc/specs/vulkan/chapters/extensions.txt

376 lines
17 KiB
Plaintext

// Copyright (c) 2015-2016 The Khronos Group Inc.
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
[[extended-functionality]]
= Extended Functionality
Additional functionality may: be provided by layers or extensions.
A layer cannot: add or modify Vulkan commands, while an extension may: do
so.
The set of layers to enable is specified when creating an instance, and
those layers are able to intercept any Vulkan command dispatched to that
instance or any of its child objects.
Extensions can operate at either the instance or device _extension scope_.
Enabled instance extensions are able to affect the operation of the instance
and any of its child objects, while device extensions may: only be available
on a subset of physical devices, must: be individually enabled per-device,
and only affect the operation of the devices where they are enabled.
Examples of these might be:
* Whole API validation is an example of a layer.
* Debug capabilities might make a good instance extension.
* A layer that provides hardware-specific performance telemetry and
analysis could be a layer that is only active for devices created from
compatible physical devices.
* Functions to allow an application to use additional hardware features
beyond the core would be a good candidate for a device extension.
[[extended-functionality-layers]]
== Layers
When a layer is enabled, it inserts itself into the call chain for Vulkan
commands the layer is interested in.
A common use of layers is to validate application behavior during
development.
For example, the implementation will not check that Vulkan enums used by the
application fall within allowed ranges.
Instead, a validation layer would do those checks and flag issues.
This avoids a performance penalty during production use of the application
because those layers would not be enabled in production.
Vulkan layers may: wrap object handles (i.e. return a different handle value
to the application than that generated by the implementation).
This is generally discouraged, as it increases the probability of
incompatibilities with new extensions.
The validation layers wrap handles in order to track the proper use and
destruction of each object.
See the <<LoaderAndValidationLayers, "Vulkan Loader Specification and
Architecture Overview">> document for additional information.
// refBegin vkEnumerateInstanceLayerProperties Returns up to requested number of global layer properties
To query the available layers, call:
include::../api/protos/vkEnumerateInstanceLayerProperties.txt[]
* pname:pPropertyCount is a pointer to an integer related to the number of
layer properties available or queried, as described below.
* pname:pProperties is either `NULL` or a pointer to an array of
slink:VkLayerProperties structures.
If pname:pProperties is `NULL`, then the number of layer properties
available is returned in pname:pPropertyCount.
Otherwise, pname:pPropertyCount must: point to a variable set by the user to
the number of elements in the pname:pProperties array, and on return the
variable is overwritten with the number of structures actually written to
pname:pProperties.
If pname:pPropertyCount is less than the number of layer properties
available, at most pname:pPropertyCount structures will be written.
If pname:pPropertyCount is smaller than the number of layers available,
ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
indicate that not all the available layer properties were returned.
The list of available layers may change at any time due to actions outside
of the Vulkan implementation, so two calls to
fname:vkEnumerateInstanceLayerProperties with the same parameters may:
return different results, or retrieve different pname:pPropertyCount values
or pname:pProperties contents.
Once an instance has been created, the layers enabled for that instance will
continue to be enabled and valid for the lifetime of that instance, even if
some of them become unavailable for future instances.
include::../validity/protos/vkEnumerateInstanceLayerProperties.txt[]
// refBegin VkLayerProperties Structure specifying layer properties
The sname:VkLayerProperties structure is defined as:
include::../api/structs/VkLayerProperties.txt[]
* pname:layerName is a null-terminated UTF-8 string specifying the name of
the layer.
Use this name in the pname:ppEnabledLayerNames array passed in the
slink:VkInstanceCreateInfo structure to enable this layer for an
instance.
* pname:specVersion is the Vulkan version the layer was written to,
encoded as described in the <<fundamentals-versionnum,API Version
Numbers and Semantics>> section.
* pname:implementationVersion is the version of this layer.
It is an integer, increasing with backward compatible changes.
* pname:description is a null-terminated UTF-8 string providing additional
details that can: be used by the application to identify the layer.
include::../validity/structs/VkLayerProperties.txt[]
To enable a layer, the name of the layer should: be added to the
pname:ppEnabledLayerNames member of slink:VkInstanceCreateInfo when creating
a sname: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 pname:ppEnabledLayerNames
member of slink:VkInstanceCreateInfo are _explicitly enabled_.
Except where otherwise specified, implicitly enabled and explicitly enabled
layers differ only in the way they are enabled.
Explicitly enabling a layer that is implicitly enabled has no additional
effect.
[[extended-functionality-device-layer-deprecation]]
=== Device Layer Deprecation
Previous versions of this specification distinguished between instance and
device layers.
Instance layers were only able to intercept commands that operate on
sname:VkInstance and sname:VkPhysicalDevice, except they were not able to
intercept flink:vkCreateDevice.
Device layers were enabled for individual devices when they were created,
and could only intercept commands operating on that device or its child
objects.
Device-only layers are now deprecated, and this specification no longer
distinguishes between instance and device layers.
Layers are enabled during instance creation, and are able to intercept all
commands operating on that instance or any of its child objects.
At the time of deprecation there were no known device-only layers and no
compelling reason to create one.
In order to maintain compatibility with implementations released prior to
device-layer deprecation, applications should: still enumerate and enable
device layers.
The behavior of fname:vkEnumerateDeviceLayerProperties and valid usage of
the pname:ppEnabledLayerNames member of sname:VkDeviceCreateInfo maximizes
compatibility with applications written to work with the previous
requirements.
// refBegin vkEnumerateDeviceLayerProperties Returns properties of available physical device layers
To enumerate device layers, call:
include::../api/protos/vkEnumerateDeviceLayerProperties.txt[]
* pname:pPropertyCount is a pointer to an integer related to the number of
layer properties available or queried.
* pname:pProperties is either `NULL` or a pointer to an array of
slink:VkLayerProperties structures.
If pname:pProperties is `NULL`, then the number of layer properties
available is returned in pname:pPropertyCount.
Otherwise, pname:pPropertyCount must: point to a variable set by the user to
the number of elements in the pname:pProperties array, and on return the
variable is overwritten with the number of structures actually written to
pname:pProperties.
If pname:pPropertyCount is less than the number of layer properties
available, at most pname:pPropertyCount structures will be written.
If pname:pPropertyCount is smaller than the number of layers available,
ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
indicate that not all the available layer properties were returned.
The list of layers enumerated by fname:vkEnumerateDeviceLayerProperties
must: be exactly the sequence of layers enabled for the instance.
The members of sname:VkLayerProperties for each enumerated layer must: be
the same as the properties when the layer was enumerated by
fname:vkEnumerateInstanceLayerProperties.
include::../validity/protos/vkEnumerateDeviceLayerProperties.txt[]
The pname:ppEnabledLayerNames and pname:enabledLayerCount members of
sname:VkDeviceCreateInfo are deprecated 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 sname:VkDeviceCreateInfo,
the sequence of layers active for a device will be exactly the sequence of
layers enabled when the parent instance was created.
[[extended-functionality-extensions]]
== 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.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 <<initialization-functionpointers>>.
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 <<LoaderAndValidationLayers, "Vulkan Loader Specification and
Architecture Overview">> document for additional information.
// refBegin vkEnumerateInstanceExtensionProperties Returns up to requested number of global extension properties
To query the available instance extensions, call:
include::../api/protos/vkEnumerateInstanceExtensionProperties.txt[]
* pname:pLayerName is either `NULL` or a pointer to a null-terminated
UTF-8 string naming the layer to retrieve extensions from.
* pname:pPropertyCount is a pointer to an integer related to the number of
extension properties available or queried, as described below.
* pname:pProperties is either `NULL` or a pointer to an array of
slink:VkExtensionProperties structures.
When pname:pLayerName parameter is NULL, only extensions provided by the
Vulkan implementation or by implicitly enabled layers are returned.
When pname:pLayerName is the name of a layer, the instance extensions
provided by that layer are returned.
If pname:pProperties is `NULL`, then the number of extensions properties
available is returned in pname:pPropertyCount.
Otherwise, pname:pPropertyCount must: point to a variable set by the user to
the number of elements in the pname:pProperties array, and on return the
variable is overwritten with the number of structures actually written to
pname:pProperties.
If pname:pPropertyCount is less than the number of extension properties
available, at most pname:pPropertyCount structures will be written.
If pname:pPropertyCount is smaller than the number of extensions available,
ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
indicate that not all the available properties were returned.
Because the list of available layers may change externally between calls to
pname:vkEnumerateInstanceExtensionProperties, two calls may retrieve
different results if a pname:pLayerName is available in one call but not in
another.
The extensions supported by a layer may also change between two calls, e.g.
if the layer implementation is replaced by a different version between those
calls.
.Valid Usage
****
* If pname:pLayerName is not `NULL`, it must: be the name of a layer
returned by flink:vkEnumerateInstanceLayerProperties
****
include::../validity/protos/vkEnumerateInstanceExtensionProperties.txt[]
To enable an instance extension, the name of the extension should: be added
to the pname:ppEnabledExtensionNames member of slink:VkInstanceCreateInfo
when creating a sname:VkInstance.
Enabling an extension does not change 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.
// refBegin vkEnumerateDeviceExtensionProperties Returns properties of available physical device extensions
To query the extensions available to a given physical device, call:
include::../api/protos/vkEnumerateDeviceExtensionProperties.txt[]
* pname:physicalDevice is the physical device that will be queried.
* pname:pLayerName is either `NULL` or a pointer to a null-terminated
UTF-8 string naming the layer to retrieve extensions from.
* pname:pPropertyCount is a pointer to an integer related to the number of
extension properties available or queried, and is treated in the same
fashion as the
flink:vkEnumerateInstanceExtensionProperties::pname:pPropertyCount
parameter.
* pname:pProperties is either `NULL` or a pointer to an array of
slink:VkExtensionProperties structures.
When pname:pLayerName parameter is NULL, only extensions provided by the
Vulkan implementation or by implicitly enabled layers are returned.
When pname:pLayerName is the name of a layer, the device extensions provided
by that layer are returned.
.Valid Usage
****
* If pname:pLayerName is not `NULL`, it must: be the name of a layer
returned by flink:vkEnumerateDeviceLayerProperties
****
include::../validity/protos/vkEnumerateDeviceExtensionProperties.txt[]
// refBegin VkExtensionProperties Structure specifying a extension properties
The sname:VkExtensionProperties structure is defined as:
include::../api/structs/VkExtensionProperties.txt[]
* pname:extensionName is a null-terminated string specifying the name of
the extension.
* pname:specVersion is the version of this extension.
It is an integer, incremented with backward compatible changes.
include::../validity/structs/VkExtensionProperties.txt[]
[[extended-functionality-instance-extensions-and-devices]]
=== Instance Extensions and Device Extensions
Because an instance extension can affect the operation of an instance and
any of its child objects, the decision to expose functionality as an
instance extension or as a device extension is not always clear.
This section provides some guidelines and rules for when to expose new
functionality as an instance extension, device extension, or both.
The decision is influenced by whether extension functionality affects
instance-level objects (e.g. instances and physical devices) and commands,
or device-level objects (e.g. logical devices, queues, and command buffers)
and commands, or both.
In some cases, the decision is clear:
* Functionality that is restricted to the instance-level must: be
implemented as an instance extension.
* Functionality that is restricted to the device-level must: be
implemented as a device extension.
In other cases, the decision is not so clear:
* Global functionality that affects the entire Vulkan API, including
instance and device-level objects and commands, should: be an instance
extension.
* Device-level functionality that contains physical-device queries, can:
be implemented as an instance extension.
If some part of an instance extension's functionality might not be
available on all physical devices, the extension should: provide a query
to determine which physical devices provide the functionality.
* For a set of global functionality that provides new instance-level and
device-level commands, and can: be enabled for a subset of devices, it
is recommended that the functionality be partitioned across two
extensions--one for the instance-level functionality, and one for the
device-specific functionality.
In this latter case, it is generally recommended that the two extensions
have unique names.
Examples of instance extensions include:
* Logging of debug messages by any enabled layers for all Vulkan commands.
* Functionality creating new objects which are direct children of an
instance.
* Functionality creating new objects which are direct children of a
physical device and intended to work with any logical device created
from the physical device.
* Functionality adding new instance-level Vulkan commands that do not
affect any device-level commands.
[NOTE]
.Note
====
Instance extensions generally require support in the Vulkan loader.
This is especially true for commands that are dispatched from instances and
physical devices.
Additional information about supporting instance-level commands may be found
in the <<LoaderAndValidationLayers, _Vulkan Loader Specification and
Architecture Overview_>> document.
Please see the "Architectural overview of layers and loader" section for
information about how both instance-level and device-level commands are
supported and dispatched.
====