304 lines
14 KiB
Plaintext
304 lines
14 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 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.
|
|
|
|
To query the available layers, call:
|
|
|
|
include::../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.
|
|
|
|
include::../validity/protos/vkEnumerateInstanceLayerProperties.txt[]
|
|
|
|
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 sname:VkLayerProperties structure is defined as:
|
|
|
|
include::../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.
|
|
|
|
Device layers can: be enumerated by calling:
|
|
|
|
include::../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.
|
|
|
|
include::../validity/protos/vkEnumerateDeviceLayerProperties.txt[]
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
To query the available instance extensions, call:
|
|
|
|
include::../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.
|
|
|
|
include::../validity/protos/vkEnumerateInstanceExtensionProperties.txt[]
|
|
|
|
When 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.
|
|
|
|
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.
|
|
|
|
To query the extensions available to a given physical device, call:
|
|
|
|
include::../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, as described below.
|
|
* pname:pProperties is either `NULL` or a pointer to an array of
|
|
slink:VkExtensionProperties structures.
|
|
|
|
include::../validity/protos/vkEnumerateDeviceExtensionProperties.txt[]
|
|
|
|
When 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.
|
|
|
|
For both flink:vkEnumerateInstanceExtensionProperties and
|
|
flink:vkEnumerateDeviceExtensionProperties, 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.
|
|
|
|
The sname:VkExtensionProperties structure is defined as:
|
|
|
|
include::../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 an 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 "Vulkan Loader Specification and Architecture Overview" document,
|
|
which may be found at the following web page:
|
|
|
|
* https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.13/loader/LoaderAndLayerInterface.md
|
|
|
|
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.
|
|
====
|