Copyright 2014-2020 The Khronos Group Inc.
This Specification is protected by copyright laws and contains material proprietary to Khronos. Except as described by these terms, it or any components may not be reproduced, republished, distributed, transmitted, displayed, broadcast or otherwise exploited in any manner without the express prior written permission of Khronos. Khronos grants a conditional copyright license to use and reproduce the unmodified Specification for any purpose, without fee or royalty, EXCEPT no licenses to any patent, trademark or other intellectual property rights are granted under these terms.
Khronos makes no, and expressly disclaims any, representations or warranties, express or implied, regarding this Specification, including, without limitation: merchantability, fitness for a particular purpose, non-infringement of any intellectual property, correctness, accuracy, completeness, timeliness, and reliability. Under no circumstances will Khronos, or any of its Promoters, Contributors or Members, or their respective partners, officers, directors, employees, agents or representatives be liable for any damages, whether direct, indirect, special or consequential damages for lost revenues, lost profits, or otherwise, arising from or in connection with these materials.
This Specification has been created under the Khronos Intellectual Property Rights Policy, which is Attachment A of the Khronos Group Membership Agreement available at https://www.khronos.org/files/member_agreement.pdf, and which defines the terms 'Scope', 'Compliant Portion', and 'Necessary Patent Claims'. Parties desiring to implement the Specification and make use of Khronos trademarks in relation to that implementation, and receive reciprocal patent license protection under the Khronos Intellectual Property Rights Policy must become Adopters and confirm the implementation as conformant under the process defined by Khronos for this Specification; see https://www.khronos.org/adopters.
This Specification contains substantially unmodified functionality from, and is a successor to, Khronos specifications including OpenGL, OpenGL ES and OpenCL.
Some parts of this Specification are purely informative and so are EXCLUDED from the Scope of this Specification. The Document Conventions section of the Introduction defines how these parts of the Specification are identified.
Where this Specification uses technical terminology, defined in the Glossary or otherwise, that refer to enabling technologies that are not expressly set forth in this Specification, those enabling technologies are EXCLUDED from the Scope of this Specification. For clarity, enabling technologies not disclosed with particularity in this Specification (e.g. semiconductor manufacturing technology, hardware architecture, processor architecture or microarchitecture, memory architecture, compiler technology, object oriented technology, basic operating system technology, compression technology, algorithms, and so on) are NOT to be considered expressly set forth; only those application program interfaces and data structures disclosed with particularity are included in the Scope of this Specification.
For purposes of the Khronos Intellectual Property Rights Policy as it relates to the definition of Necessary Patent Claims, all recommended or optional features, behaviors and functionality set forth in this Specification, if implemented, are considered to be included as Compliant Portions.
Where this Specification includes normative references to external documents, only the specifically identified sections of those external documents are INCLUDED in the Scope of this Specification. If not created by Khronos, those external documents may contain contributions from non-members of Khronos not covered by the Khronos Intellectual Property Rights Policy.
This document contains extensions which are not ratified by Khronos, and as such is not a ratified Specification, though it contains text from (and is a superset of) the ratified Vulkan Specification. The ratified versions of the Vulkan Specification can be found at https://www.khronos.org/registry/vulkan/specs/1.2/html/vkspec.html (core only) and https://www.khronos.org/registry/vulkan/specs/1.2-khr-extensions/html/vkspec.html (core with KHR extensions).
Vulkan and Khronos are registered trademarks of The Khronos Group Inc. ASTC is a trademark of ARM Holdings PLC; OpenCL is a trademark of Apple Inc.; and OpenGL and OpenGL ES are registered trademarks of Hewlett Packard Enterprise, all used under license by Khronos. All other product names, trademarks, and/or company names are used solely for identification and belong to their respective owners.
1. Introduction
This document, referred to as the “Vulkan Specification” or just the “Specification” hereafter, describes the Vulkan Application Programming Interface (API). Vulkan is a C99 API designed for explicit control of low-level graphics and compute functionality.
The canonical version of the Specification is available in the official Vulkan Registry (https://www.khronos.org/registry/vulkan/). The source files used to generate the Vulkan specification are stored in the Vulkan Documentation Repository (https://github.com/KhronosGroup/Vulkan-Docs). The source repository additionally has a public issue tracker and allows the submission of pull requests that improve the specification.
1.1. Document Conventions
The Vulkan specification is intended for use by both implementors of the API and application developers seeking to make use of the API, forming a contract between these parties. Specification text may address either party; typically the intended audience can be inferred from context, though some sections are defined to address only one of these parties. (For example, Valid Usage sections only address application developers). Any requirements, prohibitions, recommendations or options defined by normative terminology are imposed only on the audience of that text.
Note
Structure and enumerated types defined in extensions that were promoted to core in Vulkan 1.1 are now defined in terms of the equivalent Vulkan 1.1 interfaces. This affects the Vulkan Specification, the Vulkan header files, and the corresponding XML Registry. |
1.1.1. Normative Terminology
Within this specification, the key words must, required, should, recommended, may, and optional are to be interpreted as described in RFC 2119 - Key words for use in RFCs to Indicate Requirement Levels (https://www.ietf.org/rfc/rfc2119.txt). These key words are highlighted in the specification for clarity. In text addressing application developers, their use expresses requirements that apply to application behavior. In text addressing implementors, their use expresses requirements that apply to implementations.
In text addressing application developers, the additional key words can and cannot are to be interpreted as describing the capabilities of an application, as follows:
- can
-
This word means that the application is able to perform the action described.
- cannot
-
This word means that the API and/or the execution environment provide no mechanism through which the application can express or accomplish the action described.
These key words are never used in text addressing implementors.
Note
There is an important distinction between cannot and must not, as used in this Specification. Cannot means something the application literally is unable to express or accomplish through the API, while must not means something that the application is capable of expressing through the API, but that the consequences of doing so are undefined and potentially unrecoverable for the implementation (see Errors). |
Unless otherwise noted in the section heading, all sections and appendices in this document are normative.
1.1.2. Technical Terminology
The Vulkan Specification makes use of common engineering and graphics terms such as Pipeline, Shader, and Host to identify and describe Vulkan API constructs and their attributes, states, and behaviors. The Glossary defines the basic meanings of these terms in the context of the Specification. The Specification text provides fuller definitions of the terms and may elaborate, extend, or clarify the Glossary definitions. When a term defined in the Glossary is used in normative language within the Specification, the definitions within the Specification govern and supersede any meanings the terms may have in other technical contexts (i.e. outside the Specification).
1.1.3. Normative References
References to external documents are considered normative references if the Specification uses any of the normative terms defined in Normative Terminology to refer to them or their requirements, either as a whole or in part.
The following documents are referenced by normative sections of the specification:
IEEE. August, 2008. IEEE Standard for Floating-Point Arithmetic. IEEE Std 754-2008. https://dx.doi.org/10.1109/IEEESTD.2008.4610935 .
Andrew Garrard. Khronos Data Format Specification, version 1.3. https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html .
John Kessenich. SPIR-V Extended Instructions for GLSL, Version 1.00 (February 10, 2016). https://www.khronos.org/registry/spir-v/ .
John Kessenich, Boaz Ouriel, and Raun Krisch. SPIR-V Specification, Version 1.5, Revision 3, Unified (April 24, 2020). https://www.khronos.org/registry/spir-v/ .
Jon Leech. The Khronos Vulkan API Registry. https://www.khronos.org/registry/vulkan/specs/1.2/registry.html .
Jon Leech and Tobias Hector. Vulkan Documentation and Extensions: Procedures and Conventions. https://www.khronos.org/registry/vulkan/specs/1.2/styleguide.html .
Vulkan Loader Specification and Architecture Overview (August, 2016). https://github.com/KhronosGroup/Vulkan-Loader/blob/master/loader/LoaderAndLayerInterface.md .
2. Fundamentals
This chapter introduces fundamental concepts including the Vulkan architecture and execution model, API syntax, queues, pipeline configurations, numeric representation, state and state queries, and the different types of objects and shaders. It provides a framework for interpreting more specific descriptions of commands and behavior in the remainder of the Specification.
2.1. Host and Device Environment
The Vulkan Specification assumes and requires: the following properties of the host environment with respect to Vulkan implementations:
-
The host must have runtime support for 8, 16, 32 and 64-bit signed and unsigned twos-complement integers, all addressable at the granularity of their size in bytes.
-
The host must have runtime support for 32- and 64-bit floating-point types satisfying the range and precision constraints in the Floating Point Computation section.
-
The representation and endianness of these types on the host must match the representation and endianness of the same types on every physical device supported.
Note
Since a variety of data types and structures in Vulkan may be accessible by both host and physical device operations, the implementation should be able to access such data efficiently in both paths in order to facilitate writing portable and performant applications. |
2.2. Execution Model
This section outlines the execution model of a Vulkan system.
Vulkan exposes one or more devices, each of which exposes one or more queues which may process work asynchronously to one another. The set of queues supported by a device is partitioned into families. Each family supports one or more types of functionality and may contain multiple queues with similar characteristics. Queues within a single family are considered compatible with one another, and work produced for a family of queues can be executed on any queue within that family. This Specification defines four types of functionality that queues may support: graphics, compute, transfer, and sparse memory management.
Note
A single device may report multiple similar queue families rather than, or as well as, reporting multiple members of one or more of those families. This indicates that while members of those families have similar capabilities, they are not directly compatible with one another. |
Device memory is explicitly managed by the application. Each device may advertise one or more heaps, representing different areas of memory. Memory heaps are either device local or host local, but are always visible to the device. Further detail about memory heaps is exposed via memory types available on that heap. Examples of memory areas that may be available on an implementation include:
-
device local is memory that is physically connected to the device.
-
device local, host visible is device local memory that is visible to the host.
-
host local, host visible is memory that is local to the host and visible to the device and host.
On other architectures, there may only be a single heap that can be used for any purpose.
A Vulkan application controls a set of devices through the submission of command buffers which have recorded device commands issued via Vulkan library calls. The content of command buffers is specific to the underlying implementation and is opaque to the application. Once constructed, a command buffer can be submitted once or many times to a queue for execution. Multiple command buffers can be built in parallel by employing multiple threads within the application.
Command buffers submitted to different queues may execute in parallel or even out of order with respect to one another. Command buffers submitted to a single queue respect submission order, as described further in synchronization chapter. Command buffer execution by the device is also asynchronous to host execution. Once a command buffer is submitted to a queue, control may return to the application immediately. Synchronization between the device and host, and between different queues is the responsibility of the application.
2.2.1. Queue Operation
Vulkan queues provide an interface to the execution engines of a device. Commands for these execution engines are recorded into command buffers ahead of execution time. These command buffers are then submitted to queues with a queue submission command for execution in a number of batches. Once submitted to a queue, these commands will begin and complete execution without further application intervention, though the order of this execution is dependent on a number of implicit and explicit ordering constraints.
Work is submitted to queues using queue submission commands that typically
take the form vkQueue*
(e.g. vkQueueSubmit,
vkQueueBindSparse), and optionally take a list of semaphores upon
which to wait before work begins and a list of semaphores to signal once
work has completed.
The work itself, as well as signaling and waiting on the semaphores are all
queue operations.
Queue operations on different queues have no implicit ordering constraints, and may execute in any order. Explicit ordering constraints between queues can be expressed with semaphores and fences.
Command buffer submissions to a single queue respect submission order and other implicit ordering guarantees, but otherwise may overlap or execute out of order. Other types of batches and queue submissions against a single queue (e.g. sparse memory binding) have no implicit ordering constraints with any other queue submission or batch. Additional explicit ordering constraints between queue submissions and individual batches can be expressed with semaphores and fences.
Before a fence or semaphore is signaled, it is guaranteed that any previously submitted queue operations have completed execution, and that memory writes from those queue operations are available to future queue operations. Waiting on a signaled semaphore or fence guarantees that previous writes that are available are also visible to subsequent commands.
Command buffer boundaries, both between primary command buffers of the same or different batches or submissions as well as between primary and secondary command buffers, do not introduce any additional ordering constraints. In other words, submitting the set of command buffers (which can include executing secondary command buffers) between any semaphore or fence operations execute the recorded commands as if they had all been recorded into a single primary command buffer, except that the current state is reset on each boundary. Explicit ordering constraints can be expressed with explicit synchronization primitives.
There are a few implicit ordering guarantees between commands within a command buffer, but only covering a subset of execution. Additional explicit ordering constraints can be expressed with the various explicit synchronization primitives.
Note
Implementations have significant freedom to overlap execution of work submitted to a queue, and this is common due to deep pipelining and parallelism in Vulkan devices. |
Commands recorded in command buffers either perform actions (draw, dispatch, clear, copy, query/timestamp operations, begin/end subpass operations), set state (bind pipelines, descriptor sets, and buffers, set dynamic state, push constants, set render pass/subpass state), or perform synchronization (set/wait events, pipeline barrier, render pass/subpass dependencies). Some commands perform more than one of these tasks. State setting commands update the current state of the command buffer. Some commands that perform actions (e.g. draw/dispatch) do so based on the current state set cumulatively since the start of the command buffer. The work involved in performing action commands is often allowed to overlap or to be reordered, but doing so must not alter the state to be used by each action command. In general, action commands are those commands that alter framebuffer attachments, read/write buffer or image memory, or write to query pools.
Synchronization commands introduce explicit execution and memory dependencies between two sets of action commands, where the second set of commands depends on the first set of commands. These dependencies enforce that both the execution of certain pipeline stages in the later set occur after the execution of certain stages in the source set, and that the effects of memory accesses performed by certain pipeline stages occur in order and are visible to each other. When not enforced by an explicit dependency or implicit ordering guarantees, action commands may overlap execution or execute out of order, and may not see the side effects of each other’s memory accesses.
The device executes queue operations asynchronously with respect to the host. Control is returned to an application immediately following command buffer submission to a queue. The application must synchronize work between the host and device as needed.
2.3. Object Model
The devices, queues, and other entities in Vulkan are represented by Vulkan objects. At the API level, all objects are referred to by handles. There are two classes of handles, dispatchable and non-dispatchable. Dispatchable handle types are a pointer to an opaque type. This pointer may be used by layers as part of intercepting API commands, and thus each API command takes a dispatchable type as its first parameter. Each object of a dispatchable type must have a unique handle value during its lifetime.
Non-dispatchable handle types are a 64-bit integer type whose meaning is implementation-dependent, and may encode object information directly in the handle rather than acting as a reference to an underlying object. Objects of a non-dispatchable type may not have unique handle values within a type or across types. If handle values are not unique, then destroying one such handle must not cause identical handles of other types to become invalid, and must not cause identical handles of the same type to become invalid if that handle value has been created more times than it has been destroyed.
All objects created or allocated from a VkDevice
(i.e. with a
VkDevice
as the first parameter) are private to that device, and must
not be used on other devices.
2.3.1. Object Lifetime
Objects are created or allocated by vkCreate*
and vkAllocate*
commands, respectively.
Once an object is created or allocated, its “structure” is considered to
be immutable, though the contents of certain object types is still free to
change.
Objects are destroyed or freed by vkDestroy*
and vkFree*
commands, respectively.
Objects that are allocated (rather than created) take resources from an existing pool object or memory heap, and when freed return resources to that pool or heap. While object creation and destruction are generally expected to be low-frequency occurrences during runtime, allocating and freeing objects can occur at high frequency. Pool objects help accommodate improved performance of the allocations and frees.
It is an application’s responsibility to track the lifetime of Vulkan objects, and not to destroy them while they are still in use.
The ownership of application-owned memory is immediately acquired by any Vulkan command it is passed into. Ownership of such memory must be released back to the application at the end of the duration of the command, so that the application can alter or free this memory as soon as all the commands that acquired it have returned.
The following object types are consumed when they are passed into a Vulkan command and not further accessed by the objects they are used to create. They must not be destroyed in the duration of any API command they are passed into:
-
VkShaderModule
-
VkPipelineCache
-
VkValidationCacheEXT
A VkRenderPass
object passed as a parameter to create another object
is not further accessed by that object after the duration of the command it
is passed into.
A VkRenderPass
used in a command buffer follows the rules described
below.
A VkPipelineLayout
object must not be destroyed while any command
buffer that uses it is in the recording state.
VkDescriptorSetLayout
objects may be accessed by commands that
operate on descriptor sets allocated using that layout, and those descriptor
sets must not be updated with vkUpdateDescriptorSets after the
descriptor set layout has been destroyed.
Otherwise, a VkDescriptorSetLayout
object passed as a parameter to
create another object is not further accessed by that object after the
duration of the command it is passed into.
The application must not destroy any other type of Vulkan object until all uses of that object by the device (such as via command buffer execution) have completed.
The following Vulkan objects must not be destroyed while any command buffers using the object are in the pending state:
-
VkEvent
-
VkQueryPool
-
VkBuffer
-
VkBufferView
-
VkImage
-
VkImageView
-
VkPipeline
-
VkSampler
-
VkDescriptorPool
-
VkFramebuffer
-
VkRenderPass
-
VkCommandBuffer
-
VkCommandPool
-
VkDeviceMemory
-
VkDescriptorSet
-
VkIndirectCommandsLayoutNV
Destroying these objects will move any command buffers that are in the recording or executable state, and are using those objects, to the invalid state.
The following Vulkan objects must not be destroyed while any queue is executing commands that use the object:
-
VkFence
-
VkSemaphore
-
VkCommandBuffer
-
VkCommandPool
In general, objects can be destroyed or freed in any order, even if the object being freed is involved in the use of another object (e.g. use of a resource in a view, use of a view in a descriptor set, use of a pipeline library in another pipeline, use of a referenced pipeline for additional graphics shader groups in another pipeline, use of an object in a command buffer, binding of a memory allocation to a resource), as long as any object that uses the freed object is not further used in any way except to be destroyed or to be reset in such a way that it no longer uses the other object (such as resetting a command buffer). If the object has been reset, then it can be used as if it never used the freed object. An exception to this is when there is a parent/child relationship between objects. In this case, the application must not destroy a parent object before its children, except when the parent is explicitly defined to free its children when it is destroyed (e.g. for pool objects, as defined below).
VkCommandPool
objects are parents of VkCommandBuffer
objects.
VkDescriptorPool
objects are parents of VkDescriptorSet
objects.
VkDevice
objects are parents of many object types (all that take a
VkDevice
as a parameter to their creation).
The following Vulkan objects have specific restrictions for when they can be destroyed:
-
VkQueue
objects cannot be explicitly destroyed. Instead, they are implicitly destroyed when theVkDevice
object they are retrieved from is destroyed. -
Destroying a pool object implicitly frees all objects allocated from that pool. Specifically, destroying
VkCommandPool
frees allVkCommandBuffer
objects that were allocated from it, and destroyingVkDescriptorPool
frees allVkDescriptorSet
objects that were allocated from it. -
VkDevice
objects can be destroyed when allVkQueue
objects retrieved from them are idle, and all objects created from them have been destroyed. This includes the following objects:-
VkFence
-
VkSemaphore
-
VkEvent
-
VkQueryPool
-
VkBuffer
-
VkBufferView
-
VkImage
-
VkImageView
-
VkShaderModule
-
VkPipelineCache
-
VkPipeline
-
VkPipelineLayout
-
VkSampler
-
VkDescriptorSetLayout
-
VkDescriptorPool
-
VkFramebuffer
-
VkRenderPass
-
VkCommandPool
-
VkCommandBuffer
-
VkDeviceMemory
-
VkValidationCacheEXT
-
-
VkPhysicalDevice
objects cannot be explicitly destroyed. Instead, they are implicitly destroyed when theVkInstance
object they are retrieved from is destroyed. -
VkInstance
objects can be destroyed once allVkDevice
objects created from any of itsVkPhysicalDevice
objects have been destroyed.
2.3.2. External Object Handles
As defined above, the scope of object handles created or allocated from a
VkDevice
is limited to that logical device.
Objects which are not in scope are said to be external.
To bring an external object into scope, an external handle must be exported
from the object in the source scope and imported into the destination scope.
Note
The scope of external handles and their associated resources may vary according to their type, but they can generally be shared across process and API boundaries. |
2.4. Application Binary Interface
The mechanism by which Vulkan is made available to applications is platform- or implementation- defined. On many platforms the C interface described in this Specification is provided by a shared library. Since shared libraries can be changed independently of the applications that use them, they present particular compatibility challenges, and this Specification places some requirements on them.
Shared library implementations must use the default Application Binary
Interface (ABI) of the standard C compiler for the platform, or provide
customized API headers that cause application code to use the
implementation’s non-default ABI.
An ABI in this context means the size, alignment, and layout of C data
types; the procedure calling convention; and the naming convention for
shared library symbols corresponding to C functions.
Customizing the calling convention for a platform is usually accomplished by
defining calling
convention macros appropriately in vk_platform.h
.
On platforms where Vulkan is provided as a shared library, library symbols beginning with “vk” and followed by a digit or uppercase letter are reserved for use by the implementation. Applications which use Vulkan must not provide definitions of these symbols. This allows the Vulkan shared library to be updated with additional symbols for new API versions or extensions without causing symbol conflicts with existing applications.
Shared library implementations should provide library symbols for commands in the highest version of this Specification they support, and for Window System Integration extensions relevant to the platform. They may also provide library symbols for commands defined by additional extensions.
Note
These requirements and recommendations are intended to allow implementors to take advantage of platform-specific conventions for SDKs, ABIs, library versioning mechanisms, etc. while still minimizing the code changes necessary to port applications or libraries between platforms. Platform vendors, or providers of the de facto standard Vulkan shared library for a platform, are encouraged to document what symbols the shared library provides and how it will be versioned when new symbols are added. Applications should only rely on shared library symbols for commands in the minimum core version required by the application. vkGetInstanceProcAddr and vkGetDeviceProcAddr should be used to obtain function pointers for commands in core versions beyond the application’s minimum required version. |
2.5. Command Syntax and Duration
The Specification describes Vulkan commands as functions or procedures using C99 syntax. Language bindings for other languages such as C++ and JavaScript may allow for stricter parameter passing, or object-oriented interfaces.
Vulkan uses the standard C types for the base type of scalar parameters
(e.g. types from <stdint.h>
), with exceptions described below, or
elsewhere in the text when appropriate:
VkBool32
represents boolean True
and False
values, since C does
not have a sufficiently portable built-in boolean type:
// Provided by VK_VERSION_1_0
typedef uint32_t VkBool32;
VK_TRUE
represents a boolean True (integer 1) value, and
VK_FALSE
a boolean False (integer 0) value.
All values returned from a Vulkan implementation in a VkBool32
will
be either VK_TRUE
or VK_FALSE
.
Applications must not pass any other values than VK_TRUE
or
VK_FALSE
into a Vulkan implementation where a VkBool32
is
expected.
VkDeviceSize
represents device memory size and offset values:
// Provided by VK_VERSION_1_0
typedef uint64_t VkDeviceSize;
VkDeviceAddress
represents device buffer address values:
// Provided by VK_VERSION_1_0
typedef uint64_t VkDeviceAddress;
Commands that create Vulkan objects are of the form vkCreate*
and take
Vk*CreateInfo
structures with the parameters needed to create the
object.
These Vulkan objects are destroyed with commands of the form
vkDestroy*
.
The last in-parameter to each command that creates or destroys a Vulkan
object is pAllocator
.
The pAllocator
parameter can be set to a non-NULL
value such that
allocations for the given object are delegated to an application provided
callback; refer to the Memory Allocation chapter for
further details.
Commands that allocate Vulkan objects owned by pool objects are of the form
vkAllocate*
, and take Vk*AllocateInfo
structures.
These Vulkan objects are freed with commands of the form vkFree*
.
These objects do not take allocators; if host memory is needed, they will
use the allocator that was specified when their parent pool was created.
Commands are recorded into a command buffer by calling API commands of the
form vkCmd*
.
Each such command may have different restrictions on where it can be used:
in a primary and/or secondary command buffer, inside and/or outside a render
pass, and in one or more of the supported queue types.
These restrictions are documented together with the definition of each such
command.
The duration of a Vulkan command refers to the interval between calling the command and its return to the caller.
2.5.1. Lifetime of Retrieved Results
Information is retrieved from the implementation with commands of the form
vkGet*
and vkEnumerate*
.
Unless otherwise specified for an individual command, the results are invariant; that is, they will remain unchanged when retrieved again by calling the same command with the same parameters, so long as those parameters themselves all remain valid.
2.6. Threading Behavior
Vulkan is intended to provide scalable performance when used on multiple host threads. All commands support being called concurrently from multiple threads, but certain parameters, or components of parameters are defined to be externally synchronized. This means that the caller must guarantee that no more than one thread is using such a parameter at a given time.
More precisely, Vulkan commands use simple stores to update the state of Vulkan objects. A parameter declared as externally synchronized may have its contents updated at any time during the host execution of the command. If two commands operate on the same object and at least one of the commands declares the object to be externally synchronized, then the caller must guarantee not only that the commands do not execute simultaneously, but also that the two commands are separated by an appropriate memory barrier (if needed).
Note
Memory barriers are particularly relevant for hosts based on the ARM CPU architecture, which is more weakly ordered than many developers are accustomed to from x86/x64 programming. Fortunately, most higher-level synchronization primitives (like the pthread library) perform memory barriers as a part of mutual exclusion, so mutexing Vulkan objects via these primitives will have the desired effect. |
Similarly the application must avoid any potential data hazard of
application-owned memory that has its
ownership temporarily acquired
by a Vulkan command.
While the ownership of application-owned memory remains acquired by a
command the implementation may read the memory at any point, and it may
write non-const
qualified memory at any point.
Parameters referring to non-const
qualified application-owned memory
are not marked explicitly as externally synchronized in the Specification.
If an application is using deferred host operations in a command, and that operation is successfully deferred, object parameters and application-owned memory passed to that command may be accessed at any time until the deferred operation is complete.
Many object types are immutable, meaning the objects cannot change once they have been created. These types of objects never need external synchronization, except that they must not be destroyed while they are in use on another thread. In certain special cases mutable object parameters are internally synchronized, making external synchronization unnecessary. Any command parameters that are not labeled as externally synchronized are either not mutated by the command or are internally synchronized. Additionally, certain objects related to a command’s parameters (e.g. command pools and descriptor pools) may be affected by a command, and must also be externally synchronized. These implicit parameters are documented as described below.
Parameters of commands that are externally synchronized are listed below.
For VkPipelineCache objects created with flags
containing
VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT
, the above
table is extended with the pipelineCache
parameter to
vkCreate*Pipelines
being externally synchronized.
There are also a few instances where a command can take in a user allocated list whose contents are externally synchronized parameters. In these cases, the caller must guarantee that at most one thread is using a given element within the list at a given time. These parameters are listed below.
In addition, there are some implicit parameters that need to be externally
synchronized.
For example, all commandBuffer
parameters that need to be externally
synchronized imply that the commandPool
that was passed in when
creating that command buffer also needs to be externally synchronized.
The implicit parameters and their associated object are listed below.
2.7. Errors
Vulkan is a layered API. The lowest layer is the core Vulkan layer, as defined by this Specification. The application can use additional layers above the core for debugging, validation, and other purposes.
One of the core principles of Vulkan is that building and submitting command buffers should be highly efficient. Thus error checking and validation of state in the core layer is minimal, although more rigorous validation can be enabled through the use of layers.
The core layer assumes applications are using the API correctly. Except as documented elsewhere in the Specification, the behavior of the core layer to an application using the API incorrectly is undefined, and may include program termination. However, implementations must ensure that incorrect usage by an application does not affect the integrity of the operating system, the Vulkan implementation, or other Vulkan client applications in the system. In particular, any guarantees made by an operating system about whether memory from one process can be visible to another process or not must not be violated by a Vulkan implementation for any memory allocation. Vulkan implementations are not required to make additional security or integrity guarantees beyond those provided by the OS unless explicitly directed by the application’s use of a particular feature or extension.
Note
For instance, if an operating system guarantees that data in all its memory allocations are set to zero when newly allocated, the Vulkan implementation must make the same guarantees for any allocations it controls (e.g. VkDeviceMemory). Similarly, if an operating system guarantees that use-after-free of host allocations will not result in values written by another process becoming visible, the same guarantees must be made by the Vulkan implementation for device memory. |
If the protected memory feature is supported, the implementation provides additional guarantees when invalid usage occurs to prevent values in protected memory from being accessed or inferred outside of protected operations, as described in Protected Memory Access Rules.
Validation of correct API usage is left to validation layers. Applications should be developed with validation layers enabled, to help catch and eliminate errors. Once validated, released applications should not enable validation layers by default.
2.7.1. Valid Usage
Valid usage defines a set of conditions which must be met in order to achieve well-defined runtime behavior in an application. These conditions depend only on Vulkan state, and the parameters or objects whose usage is constrained by the condition.
Some valid usage conditions have dependencies on runtime limits or feature availability. It is possible to validate these conditions against Vulkan’s minimum supported values for these limits and features, or some subset of other known values.
Valid usage conditions do not cover conditions where well-defined behavior (including returning an error code) exists.
Valid usage conditions should apply to the command or structure where complete information about the condition would be known during execution of an application. This is such that a validation layer or linter can be written directly against these statements at the point they are specified.
Note
This does lead to some non-obvious places for valid usage statements. For instance, the valid values for a structure might depend on a separate value in the calling command. In this case, the structure itself will not reference this valid usage as it is impossible to determine validity from the structure that it is invalid - instead this valid usage would be attached to the calling command. Another example is draw state - the state setters are independent, and can cause a legitimately invalid state configuration between draw calls; so the valid usage statements are attached to the place where all state needs to be valid - at the draw command. |
Valid usage conditions are described in a block labelled “Valid Usage” following each command or structure they apply to.
2.7.2. Implicit Valid Usage
Some valid usage conditions apply to all commands and structures in the API, unless explicitly denoted otherwise for a specific command or structure. These conditions are considered implicit, and are described in a block labelled “Valid Usage (Implicit)” following each command or structure they apply to. Implicit valid usage conditions are described in detail below.
Valid Usage for Object Handles
Any input parameter to a command that is an object handle must be a valid object handle, unless otherwise specified. An object handle is valid if:
-
It has been created or allocated by a previous, successful call to the API. Such calls are noted in the Specification.
-
It has not been deleted or freed by a previous call to the API. Such calls are noted in the Specification.
-
Any objects used by that object, either as part of creation or execution, must also be valid.
The reserved values VK_NULL_HANDLE and NULL
can be used in place of
valid non-dispatchable handles and dispatchable handles, respectively, when
explicitly called out in the Specification.
Any command that creates an object successfully must not return these
values.
It is valid to pass these values to vkDestroy*
or vkFree*
commands, which will silently ignore these values.
Valid Usage for Pointers
Any parameter that is a pointer must be a valid pointer only if it is explicitly called out by a Valid Usage statement.
A pointer is “valid” if it points at memory containing values of the number and type(s) expected by the command, and all fundamental types accessed through the pointer (e.g. as elements of an array or as members of a structure) satisfy the alignment requirements of the host processor.
Valid Usage for Strings
Any parameter that is a pointer to char
must be a finite sequence of
values terminated by a null character, or if explicitly called out in the
Specification, can be NULL
.
Valid Usage for Enumerated Types
Any parameter of an enumerated type must be a valid enumerant for that type. A enumerant is valid if:
-
The enumerant is defined as part of the enumerated type.
-
The enumerant is not the special value (suffixed with
_MAX_ENUM
1) defined for the enumerated type.- 1
-
This special value exists only to ensure that C
enum
types are 32 bits in size. It is not part of the API, and should not be used by applications.
Any enumerated type returned from a query command or otherwise output from Vulkan to the application must not have a reserved value. Reserved values are values not defined by any extension for that enumerated type.
Note
This language is intended to accommodate cases such as “hidden” extensions known only to driver internals, or layers enabling extensions without knowledge of the application, without allowing return of values not defined by any extension. |
Note
Application developers are encouraged to be careful when using |
Valid Usage for Flags
A collection of flags is represented by a bitmask using the type
VkFlags
:
// Provided by VK_VERSION_1_0
typedef uint32_t VkFlags;
Bitmasks are passed to many commands and structures to compactly represent
options, but VkFlags
is not used directly in the API.
Instead, a Vk*Flags
type which is an alias of VkFlags
, and
whose name matches the corresponding Vk*FlagBits
that are valid for
that type, is used.
Any Vk*Flags
member or parameter used in the API as an input must be
a valid combination of bit flags.
A valid combination is either zero or the bitwise OR of valid bit flags.
A bit flag is valid if:
-
The bit flag is defined as part of the
Vk*FlagBits
type, where the bits type is obtained by taking the flag type and replacing the trailingFlags
withFlagBits
. For example, a flag value of type VkColorComponentFlags must contain only bit flags defined by VkColorComponentFlagBits. -
The flag is allowed in the context in which it is being used. For example, in some cases, certain bit flags or combinations of bit flags are mutually exclusive.
Any Vk*Flags
member or parameter returned from a query command or
otherwise output from Vulkan to the application may contain bit flags
undefined in its corresponding Vk*FlagBits
type.
An application cannot rely on the state of these unspecified bits.
Only the low-order 31 bits (bit positions zero through 30) are available for use as flag bits.
Note
This restriction is due to poorly defined behavior by C compilers given a C
enumerant value of |
Valid Usage for Structure Types
Any parameter that is a structure containing a sType
member must have
a value of sType
which is a valid VkStructureType value matching
the type of the structure.
Structure types supported by the Vulkan API include:
// Provided by VK_VERSION_1_0, VK_VERSION_1_0
typedef enum VkStructureType {
VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
// Provided by VK_VERSION_1_1
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003,
// Provided by VK_VERSION_1_2
VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004,
// Provided by VK_KHR_swapchain
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
// Provided by VK_KHR_swapchain
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_surface
VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_swapchain
VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_swapchain
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_swapchain
VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_swapchain
VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011,
// Provided by VK_KHR_swapchain with VK_VERSION_1_1, VK_KHR_device_group with VK_KHR_swapchain
VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012,
// Provided by VK_KHR_display
VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
// Provided by VK_KHR_display
VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
// Provided by VK_KHR_display_swapchain
VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
// Provided by VK_KHR_xlib_surface
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
// Provided by VK_KHR_xcb_surface
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
// Provided by VK_KHR_wayland_surface
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
// Provided by VK_KHR_android_surface
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
// Provided by VK_KHR_win32_surface
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
// Provided by VK_EXT_debug_report
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
// Provided by VK_AMD_rasterization_order
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000,
// Provided by VK_EXT_debug_marker
VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
// Provided by VK_EXT_debug_marker
VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
// Provided by VK_EXT_debug_marker
VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
// Provided by VK_NV_dedicated_allocation
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
// Provided by VK_NV_dedicated_allocation
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
// Provided by VK_NV_dedicated_allocation
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
// Provided by VK_EXT_transform_feedback
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000,
// Provided by VK_EXT_transform_feedback
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001,
// Provided by VK_EXT_transform_feedback
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002,
// Provided by VK_NVX_image_view_handle
VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000,
// Provided by VK_NVX_image_view_handle
VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001,
// Provided by VK_AMD_texture_gather_bias_lod
VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
// Provided by VK_GGP_stream_descriptor_surface
VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000,
// Provided by VK_NV_corner_sampled_image
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
// Provided by VK_NV_external_memory
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
// Provided by VK_NV_external_memory
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
// Provided by VK_NV_external_memory_win32
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
// Provided by VK_NV_external_memory_win32
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
// Provided by VK_NV_win32_keyed_mutex
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
// Provided by VK_EXT_validation_flags
VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
// Provided by VK_NN_vi_surface
VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
// Provided by VK_EXT_texture_compression_astc_hdr
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000,
// Provided by VK_EXT_astc_decode_mode
VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000,
// Provided by VK_EXT_astc_decode_mode
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001,
// Provided by VK_KHR_external_memory_win32
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000,
// Provided by VK_KHR_external_memory_win32
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001,
// Provided by VK_KHR_external_memory_win32
VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002,
// Provided by VK_KHR_external_memory_win32
VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003,
// Provided by VK_KHR_external_memory_fd
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000,
// Provided by VK_KHR_external_memory_fd
VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001,
// Provided by VK_KHR_external_memory_fd
VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002,
// Provided by VK_KHR_win32_keyed_mutex
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000,
// Provided by VK_KHR_external_semaphore_win32
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000,
// Provided by VK_KHR_external_semaphore_win32
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001,
// Provided by VK_KHR_external_semaphore_win32
VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002,
// Provided by VK_KHR_external_semaphore_win32
VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003,
// Provided by VK_KHR_external_semaphore_fd
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
// Provided by VK_KHR_external_semaphore_fd
VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
// Provided by VK_KHR_push_descriptor
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
// Provided by VK_EXT_conditional_rendering
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
// Provided by VK_EXT_conditional_rendering
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
// Provided by VK_EXT_conditional_rendering
VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
// Provided by VK_KHR_incremental_present
VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
// Provided by VK_NV_clip_space_w_scaling
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000,
// Provided by VK_EXT_display_surface_counter
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000,
// Provided by VK_EXT_display_control
VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
// Provided by VK_EXT_display_control
VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
// Provided by VK_EXT_display_control
VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
// Provided by VK_EXT_display_control
VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
// Provided by VK_GOOGLE_display_timing
VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000,
// Provided by VK_NVX_multiview_per_view_attributes
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000,
// Provided by VK_NV_viewport_swizzle
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000,
// Provided by VK_EXT_discard_rectangles
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
// Provided by VK_EXT_discard_rectangles
VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
// Provided by VK_EXT_conservative_rasterization
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
// Provided by VK_EXT_conservative_rasterization
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
// Provided by VK_EXT_depth_clip_enable
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000,
// Provided by VK_EXT_depth_clip_enable
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001,
// Provided by VK_EXT_hdr_metadata
VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
// Provided by VK_KHR_shared_presentable_image
VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
// Provided by VK_KHR_external_fence_win32
VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
// Provided by VK_KHR_external_fence_win32
VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
// Provided by VK_KHR_external_fence_win32
VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002,
// Provided by VK_KHR_external_fence_fd
VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000,
// Provided by VK_KHR_external_fence_fd
VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005,
// Provided by VK_KHR_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006,
// Provided by VK_KHR_get_surface_capabilities2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
// Provided by VK_KHR_get_surface_capabilities2
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
// Provided by VK_KHR_get_surface_capabilities2
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
// Provided by VK_KHR_get_display_properties2
VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
// Provided by VK_KHR_get_display_properties2
VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
// Provided by VK_KHR_get_display_properties2
VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
// Provided by VK_KHR_get_display_properties2
VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
// Provided by VK_KHR_get_display_properties2
VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
// Provided by VK_MVK_ios_surface
VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
// Provided by VK_MVK_macos_surface
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
// Provided by VK_EXT_debug_utils
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
// Provided by VK_EXT_debug_utils
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001,
// Provided by VK_EXT_debug_utils
VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002,
// Provided by VK_EXT_debug_utils
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003,
// Provided by VK_EXT_debug_utils
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
// Provided by VK_EXT_inline_uniform_block
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000,
// Provided by VK_EXT_inline_uniform_block
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001,
// Provided by VK_EXT_inline_uniform_block
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002,
// Provided by VK_EXT_inline_uniform_block
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003,
// Provided by VK_EXT_sample_locations
VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000,
// Provided by VK_EXT_sample_locations
VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001,
// Provided by VK_EXT_sample_locations
VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
// Provided by VK_EXT_sample_locations
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
// Provided by VK_EXT_sample_locations
VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
// Provided by VK_EXT_blend_operation_advanced
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
// Provided by VK_EXT_blend_operation_advanced
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
// Provided by VK_EXT_blend_operation_advanced
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
// Provided by VK_NV_fragment_coverage_to_color
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR = 1000165006,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000165007,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR = 1000150001,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR = 1000150008,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_KHR = 1000150009,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR = 1000150013,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_KHR = 1000150014,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017,
// Provided by VK_KHR_ray_tracing
VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018,
// Provided by VK_NV_framebuffer_mixed_samples
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
// Provided by VK_NV_shader_sm_builtins
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000,
// Provided by VK_NV_shader_sm_builtins
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158001,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004,
// Provided by VK_EXT_image_drm_format_modifier
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
// Provided by VK_EXT_validation_cache
VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
// Provided by VK_EXT_validation_cache
VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
// Provided by VK_NV_shading_rate_image
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
// Provided by VK_NV_shading_rate_image
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
// Provided by VK_NV_shading_rate_image
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
// Provided by VK_NV_shading_rate_image
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012,
// Provided by VK_NV_representative_fragment_test
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
// Provided by VK_NV_representative_fragment_test
VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
// Provided by VK_EXT_filter_cubic
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000,
// Provided by VK_EXT_filter_cubic
VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001,
// Provided by VK_EXT_global_priority
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
// Provided by VK_EXT_external_memory_host
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
// Provided by VK_EXT_external_memory_host
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
// Provided by VK_EXT_external_memory_host
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
// Provided by VK_KHR_shader_clock
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000,
// Provided by VK_AMD_pipeline_compiler_control
VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000,
// Provided by VK_EXT_calibrated_timestamps
VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
// Provided by VK_AMD_shader_core_properties
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
// Provided by VK_AMD_memory_overallocation_behavior
VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000,
// Provided by VK_EXT_vertex_attribute_divisor
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
// Provided by VK_EXT_vertex_attribute_divisor
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
// Provided by VK_EXT_vertex_attribute_divisor
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
// Provided by VK_GGP_frame_token
VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000,
// Provided by VK_EXT_pipeline_creation_feedback
VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000,
// Provided by VK_NV_compute_shader_derivatives
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
// Provided by VK_NV_mesh_shader
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
// Provided by VK_NV_mesh_shader
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
// Provided by VK_NV_fragment_shader_barycentric
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000,
// Provided by VK_NV_shader_image_footprint
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
// Provided by VK_NV_scissor_exclusive
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
// Provided by VK_NV_scissor_exclusive
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
// Provided by VK_NV_device_diagnostic_checkpoints
VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
// Provided by VK_NV_device_diagnostic_checkpoints
VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
// Provided by VK_INTEL_shader_integer_functions2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004,
// Provided by VK_INTEL_performance_query
VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005,
// Provided by VK_EXT_pci_bus_info
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
// Provided by VK_AMD_display_native_hdr
VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000,
// Provided by VK_AMD_display_native_hdr
VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001,
// Provided by VK_FUCHSIA_imagepipe_surface
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
// Provided by VK_EXT_metal_surface
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
// Provided by VK_EXT_fragment_density_map
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
// Provided by VK_EXT_fragment_density_map
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
// Provided by VK_EXT_fragment_density_map
VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
// Provided by VK_EXT_subgroup_size_control
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000,
// Provided by VK_EXT_subgroup_size_control
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001,
// Provided by VK_EXT_subgroup_size_control
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002,
// Provided by VK_AMD_shader_core_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000,
// Provided by VK_AMD_device_coherent_memory
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000,
// Provided by VK_EXT_memory_budget
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000,
// Provided by VK_EXT_memory_priority
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000,
// Provided by VK_EXT_memory_priority
VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
// Provided by VK_KHR_surface_protected_capabilities
VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000,
// Provided by VK_NV_dedicated_allocation_image_aliasing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000,
// Provided by VK_EXT_buffer_device_address
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000,
// Provided by VK_EXT_buffer_device_address
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
// Provided by VK_EXT_tooling_info
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
// Provided by VK_EXT_validation_features
VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
// Provided by VK_NV_cooperative_matrix
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
// Provided by VK_NV_cooperative_matrix
VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
// Provided by VK_NV_cooperative_matrix
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002,
// Provided by VK_NV_coverage_reduction_mode
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000,
// Provided by VK_NV_coverage_reduction_mode
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001,
// Provided by VK_NV_coverage_reduction_mode
VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002,
// Provided by VK_EXT_fragment_shader_interlock
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000,
// Provided by VK_EXT_ycbcr_image_arrays
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000,
// Provided by VK_EXT_full_screen_exclusive
VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000,
// Provided by VK_EXT_full_screen_exclusive
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
// Provided by VK_EXT_full_screen_exclusive with VK_KHR_win32_surface
VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001,
// Provided by VK_EXT_headless_surface
VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
// Provided by VK_EXT_line_rasterization
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000,
// Provided by VK_EXT_line_rasterization
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001,
// Provided by VK_EXT_line_rasterization
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002,
// Provided by VK_EXT_shader_atomic_float
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000,
// Provided by VK_EXT_index_type_uint8
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000,
// Provided by VK_EXT_extended_dynamic_state
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000,
// Provided by VK_KHR_deferred_host_operations
VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR = 1000268000,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
// Provided by VK_KHR_pipeline_executable_properties
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
// Provided by VK_EXT_shader_demote_to_helper_invocation
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006,
// Provided by VK_NV_device_generated_commands
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
// Provided by VK_EXT_texel_buffer_alignment
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
// Provided by VK_EXT_texel_buffer_alignment
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001,
// Provided by VK_QCOM_render_pass_transform
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
// Provided by VK_QCOM_render_pass_transform
VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001,
// Provided by VK_EXT_robustness2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000,
// Provided by VK_EXT_robustness2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001,
// Provided by VK_EXT_custom_border_color
VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000,
// Provided by VK_EXT_custom_border_color
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001,
// Provided by VK_EXT_custom_border_color
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002,
// Provided by VK_KHR_pipeline_library
VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
// Provided by VK_EXT_private_data
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000,
// Provided by VK_EXT_private_data
VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001,
// Provided by VK_EXT_private_data
VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002,
// Provided by VK_EXT_pipeline_creation_cache_control
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000,
// Provided by VK_NV_device_diagnostics_config
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000,
// Provided by VK_NV_device_diagnostics_config
VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001,
// Provided by VK_EXT_fragment_density_map2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000,
// Provided by VK_EXT_fragment_density_map2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001,
// Provided by VK_EXT_image_robustness
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000,
// Provided by VK_EXT_directfb_surface
VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
// Provided by VK_KHR_multiview
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
// Provided by VK_KHR_multiview
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
// Provided by VK_KHR_multiview
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2,
// Provided by VK_KHR_get_physical_device_properties2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
// Provided by VK_KHR_device_group
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
// Provided by VK_KHR_device_group
VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
// Provided by VK_KHR_device_group
VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO,
// Provided by VK_KHR_device_group
VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,
// Provided by VK_KHR_device_group
VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO,
// Provided by VK_KHR_device_group with VK_KHR_bind_memory2
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
// Provided by VK_KHR_device_group with VK_KHR_bind_memory2
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
// Provided by VK_KHR_device_group_creation
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
// Provided by VK_KHR_device_group_creation
VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,
// Provided by VK_KHR_external_memory_capabilities
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
// Provided by VK_KHR_external_memory_capabilities
VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
// Provided by VK_KHR_external_memory_capabilities
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
// Provided by VK_KHR_external_memory_capabilities
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
// Provided by VK_KHR_external_memory_capabilities, VK_KHR_external_semaphore_capabilities, VK_KHR_external_fence_capabilities
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
// Provided by VK_KHR_external_memory
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
// Provided by VK_KHR_external_memory
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
// Provided by VK_KHR_external_memory
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
// Provided by VK_KHR_external_semaphore_capabilities
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
// Provided by VK_KHR_external_semaphore_capabilities
VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
// Provided by VK_KHR_external_semaphore
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
// Provided by VK_KHR_shader_float16_int8
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
// Provided by VK_KHR_shader_float16_int8
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
// Provided by VK_KHR_16bit_storage
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
// Provided by VK_KHR_descriptor_update_template
VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
// Provided by VK_KHR_imageless_framebuffer
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
// Provided by VK_KHR_imageless_framebuffer
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
// Provided by VK_KHR_imageless_framebuffer
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
// Provided by VK_KHR_imageless_framebuffer
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
// Provided by VK_KHR_create_renderpass2
VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
// Provided by VK_KHR_external_fence_capabilities
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
// Provided by VK_KHR_external_fence_capabilities
VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
// Provided by VK_KHR_external_fence
VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
// Provided by VK_KHR_maintenance2
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES,
// Provided by VK_KHR_maintenance2
VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
// Provided by VK_KHR_maintenance2
VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
// Provided by VK_KHR_maintenance2
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO,
// Provided by VK_KHR_variable_pointers
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR,
// Provided by VK_KHR_dedicated_allocation
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
// Provided by VK_KHR_dedicated_allocation
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
// Provided by VK_EXT_sampler_filter_minmax
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
// Provided by VK_EXT_sampler_filter_minmax
VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
// Provided by VK_KHR_get_memory_requirements2
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
// Provided by VK_KHR_get_memory_requirements2
VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
// Provided by VK_KHR_get_memory_requirements2
VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
// Provided by VK_KHR_get_memory_requirements2
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
// Provided by VK_KHR_get_memory_requirements2
VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
// Provided by VK_KHR_image_format_list
VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
// Provided by VK_KHR_bind_memory2
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
// Provided by VK_KHR_bind_memory2
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
// Provided by VK_EXT_descriptor_indexing
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
// Provided by VK_EXT_descriptor_indexing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
// Provided by VK_EXT_descriptor_indexing
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
// Provided by VK_EXT_descriptor_indexing
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
// Provided by VK_EXT_descriptor_indexing
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR,
// Provided by VK_NV_ray_tracing
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
// Provided by VK_KHR_maintenance3
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
// Provided by VK_KHR_maintenance3
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
// Provided by VK_KHR_shader_subgroup_extended_types
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
// Provided by VK_KHR_8bit_storage
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
// Provided by VK_KHR_shader_atomic_int64
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
// Provided by VK_KHR_driver_properties
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
// Provided by VK_KHR_shader_float_controls
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
// Provided by VK_KHR_depth_stencil_resolve
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
// Provided by VK_KHR_depth_stencil_resolve
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
// Provided by VK_KHR_timeline_semaphore
VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL,
// Provided by VK_KHR_vulkan_memory_model
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
// Provided by VK_EXT_scalar_block_layout
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
// Provided by VK_KHR_separate_depth_stencil_layouts
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
// Provided by VK_KHR_separate_depth_stencil_layouts
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
// Provided by VK_KHR_separate_depth_stencil_layouts
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
// Provided by VK_EXT_buffer_device_address
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
// Provided by VK_EXT_separate_stencil_usage
VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
// Provided by VK_KHR_uniform_buffer_standard_layout
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
// Provided by VK_KHR_buffer_device_address
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
// Provided by VK_KHR_buffer_device_address
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
// Provided by VK_KHR_buffer_device_address
VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
// Provided by VK_KHR_buffer_device_address
VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
// Provided by VK_KHR_buffer_device_address
VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
// Provided by VK_EXT_host_query_reset
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
} VkStructureType;
Each value corresponds to a particular structure with a sType
member
with a matching name.
As a general rule, the name of each VkStructureType value is obtained
by taking the name of the structure, stripping the leading Vk
,
prefixing each capital letter with _
, converting the entire resulting
string to upper case, and prefixing it with VK_STRUCTURE_TYPE_
.
For example, structures of type VkImageCreateInfo correspond to a
VkStructureType of VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
, and thus
its sType
member must equal that when it is passed to the API.
The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
and
VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
are reserved for internal
use by the loader, and do not have corresponding Vulkan structures in this
Specification.
Valid Usage for Structure Pointer Chains
Any parameter that is a structure containing a void*
pNext
member
must have a value of pNext
that is either NULL
, or is a pointer to
a valid extending structure, containing sType
and pNext
members as described in the Vulkan Documentation and
Extensions document in the section “Extension Interactions”.
The set of structures connected by pNext
pointers is referred to as a
pNext
chain.
Each structure present in the pNext
chain must be defined at runtime
by either:
-
a core version which is supported
-
an extension which is enabled
-
a supported device extension in the case of physical-device-level functionality added by the device extension
Each type of extending structure must not appear more than once in a
pNext
chain, including any
aliases.
This general rule may be explicitly overridden for specific structures.
Any component of the implementation (the loader, any enabled layers, and
drivers) must skip over, without processing (other than reading the
sType
and pNext
members) any extending structures in the chain
not defined by core versions or extensions supported by that component.
As a convenience to implementations and layers needing to iterate through a structure pointer chain, the Vulkan API provides two base structures. These structures allow for some type safety, and can be used by Vulkan API functions that operate on generic inputs and outputs.
The VkBaseInStructure
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkBaseInStructure {
VkStructureType sType;
const struct VkBaseInStructure* pNext;
} VkBaseInStructure;
-
sType
is the structure type of the structure being iterated through. -
pNext
isNULL
or a pointer to the next structure in a structure chain.
VkBaseInStructure
can be used to facilitate iterating through a
read-only structure pointer chain.
The VkBaseOutStructure
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkBaseOutStructure {
VkStructureType sType;
struct VkBaseOutStructure* pNext;
} VkBaseOutStructure;
-
sType
is the structure type of the structure being iterated through. -
pNext
isNULL
or a pointer to the next structure in a structure chain.
VkBaseOutStructure
can be used to facilitate iterating through a
structure pointer chain that returns data back to the application.
Valid Usage for Nested Structures
The above conditions also apply recursively to members of structures provided as input to a command, either as a direct argument to the command, or themselves a member of another structure.
Specifics on valid usage of each command are covered in their individual sections.
Valid Usage for Extensions
Instance-level functionality or behavior added by an instance extension to the API must not be used unless that extension is supported by the instance as determined by vkEnumerateInstanceExtensionProperties, and that extension is enabled in VkInstanceCreateInfo.
Physical-device-level functionality or behavior added by an instance extension to the API must not be used unless that extension is supported by the instance as determined by vkEnumerateInstanceExtensionProperties, and that extension is enabled in VkInstanceCreateInfo.
Physical-device-level functionality or behavior added by a device extension to the API must not be used unless the conditions described in Extending Physical Device Core Functionality are met.
Device functionality or behavior added by a device extension to the API must not be used unless that extension is supported by the device as determined by vkEnumerateDeviceExtensionProperties, and that extension is enabled in VkDeviceCreateInfo.
Valid Usage for Newer Core Versions
Instance-level functionality or behavior added by a new core
version of the API must not be used unless it is supported by the
instance as determined by vkEnumerateInstanceVersion and the specified
version of VkApplicationInfo::apiVersion
.
Physical-device-level functionality or behavior added by a new
core version of the API must not be used unless it is supported by the
physical device as determined by
VkPhysicalDeviceProperties::apiVersion
and the specified version
of VkApplicationInfo::apiVersion
.
Device-level functionality or behavior added by a new core
version of the API must not be used unless it is supported by the device
as determined by VkPhysicalDeviceProperties::apiVersion
and the
specified version of VkApplicationInfo::apiVersion
.
2.7.3. Return Codes
While the core Vulkan API is not designed to capture incorrect usage, some circumstances still require return codes. Commands in Vulkan return their status via return codes that are in one of two categories:
-
Successful completion codes are returned when a command needs to communicate success or status information. All successful completion codes are non-negative values.
-
Run time error codes are returned when a command needs to communicate a failure that could only be detected at runtime. All runtime error codes are negative values.
All return codes in Vulkan are reported via VkResult return values. The possible codes are:
// Provided by VK_VERSION_1_0
typedef enum VkResult {
VK_SUCCESS = 0,
VK_NOT_READY = 1,
VK_TIMEOUT = 2,
VK_EVENT_SET = 3,
VK_EVENT_RESET = 4,
VK_INCOMPLETE = 5,
VK_ERROR_OUT_OF_HOST_MEMORY = -1,
VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
VK_ERROR_INITIALIZATION_FAILED = -3,
VK_ERROR_DEVICE_LOST = -4,
VK_ERROR_MEMORY_MAP_FAILED = -5,
VK_ERROR_LAYER_NOT_PRESENT = -6,
VK_ERROR_EXTENSION_NOT_PRESENT = -7,
VK_ERROR_FEATURE_NOT_PRESENT = -8,
VK_ERROR_INCOMPATIBLE_DRIVER = -9,
VK_ERROR_TOO_MANY_OBJECTS = -10,
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
VK_ERROR_FRAGMENTED_POOL = -12,
VK_ERROR_UNKNOWN = -13,
// Provided by VK_VERSION_1_1
VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000,
// Provided by VK_VERSION_1_1
VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003,
// Provided by VK_VERSION_1_2
VK_ERROR_FRAGMENTATION = -1000161000,
// Provided by VK_VERSION_1_2
VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000,
// Provided by VK_KHR_surface
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
// Provided by VK_KHR_surface
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
// Provided by VK_KHR_swapchain
VK_SUBOPTIMAL_KHR = 1000001003,
// Provided by VK_KHR_swapchain
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
// Provided by VK_KHR_display_swapchain
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
// Provided by VK_EXT_debug_report
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
// Provided by VK_NV_glsl_shader
VK_ERROR_INVALID_SHADER_NV = -1000012000,
// Provided by VK_KHR_ray_tracing
VK_ERROR_INCOMPATIBLE_VERSION_KHR = -1000150000,
// Provided by VK_EXT_image_drm_format_modifier
VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000,
// Provided by VK_EXT_global_priority
VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
// Provided by VK_EXT_full_screen_exclusive
VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000,
// Provided by VK_KHR_deferred_host_operations
VK_THREAD_IDLE_KHR = 1000268000,
// Provided by VK_KHR_deferred_host_operations
VK_THREAD_DONE_KHR = 1000268001,
// Provided by VK_KHR_deferred_host_operations
VK_OPERATION_DEFERRED_KHR = 1000268002,
// Provided by VK_KHR_deferred_host_operations
VK_OPERATION_NOT_DEFERRED_KHR = 1000268003,
// Provided by VK_EXT_pipeline_creation_cache_control
VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000,
// Provided by VK_KHR_maintenance1
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
// Provided by VK_KHR_external_memory
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
// Provided by VK_EXT_descriptor_indexing
VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
// Provided by VK_EXT_buffer_device_address
VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
// Provided by VK_KHR_buffer_device_address
VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT,
} VkResult;
-
VK_SUCCESS
Command successfully completed -
VK_NOT_READY
A fence or query has not yet completed -
VK_TIMEOUT
A wait operation has not completed in the specified time -
VK_EVENT_SET
An event is signaled -
VK_EVENT_RESET
An event is unsignaled -
VK_INCOMPLETE
A return array was too small for the result -
VK_SUBOPTIMAL_KHR
A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully. -
VK_THREAD_IDLE_KHR
A deferred operation is not complete but there is currently no work for this thread to do at the time of this call. -
VK_THREAD_DONE_KHR
A deferred operation is not complete but there is no work remaining to assign to additional threads. -
VK_OPERATION_DEFERRED_KHR
A deferred operation was requested and at least some of the work was deferred. -
VK_OPERATION_NOT_DEFERRED_KHR
A deferred operation was requested and no operations were deferred. -
VK_PIPELINE_COMPILE_REQUIRED_EXT
A requested pipeline creation would have required compilation, but the application requested compilation to not be performed.
-
VK_ERROR_OUT_OF_HOST_MEMORY
A host memory allocation has failed. -
VK_ERROR_OUT_OF_DEVICE_MEMORY
A device memory allocation has failed. -
VK_ERROR_INITIALIZATION_FAILED
Initialization of an object could not be completed for implementation-specific reasons. -
VK_ERROR_DEVICE_LOST
The logical or physical device has been lost. See Lost Device -
VK_ERROR_MEMORY_MAP_FAILED
Mapping of a memory object has failed. -
VK_ERROR_LAYER_NOT_PRESENT
A requested layer is not present or could not be loaded. -
VK_ERROR_EXTENSION_NOT_PRESENT
A requested extension is not supported. -
VK_ERROR_FEATURE_NOT_PRESENT
A requested feature is not supported. -
VK_ERROR_INCOMPATIBLE_DRIVER
The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons. -
VK_ERROR_TOO_MANY_OBJECTS
Too many objects of the type have already been created. -
VK_ERROR_FORMAT_NOT_SUPPORTED
A requested format is not supported on this device. -
VK_ERROR_FRAGMENTED_POOL
A pool allocation has failed due to fragmentation of the pool’s memory. This must only be returned if no attempt to allocate host or device memory was made to accommodate the new allocation. This should be returned in preference toVK_ERROR_OUT_OF_POOL_MEMORY
, but only if the implementation is certain that the pool allocation failure was due to fragmentation. -
VK_ERROR_SURFACE_LOST_KHR
A surface is no longer available. -
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR
The requested window is already in use by Vulkan or another API in a manner which prevents it from being used again. -
VK_ERROR_OUT_OF_DATE_KHR
A surface has changed in such a way that it is no longer compatible with the swapchain, and further presentation requests using the swapchain will fail. Applications must query the new surface properties and recreate their swapchain if they wish to continue presenting to the surface. -
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR
The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image. -
VK_ERROR_INVALID_SHADER_NV
One or more shaders failed to compile or link. More details are reported back to the application viaVK_EXT_debug_report
if enabled. -
VK_ERROR_OUT_OF_POOL_MEMORY
A pool memory allocation has failed. This must only be returned if no attempt to allocate host or device memory was made to accommodate the new allocation. If the failure was definitely due to fragmentation of the pool,VK_ERROR_FRAGMENTED_POOL
should be returned instead. -
VK_ERROR_INVALID_EXTERNAL_HANDLE
An external handle is not a valid handle of the specified type. -
VK_ERROR_FRAGMENTATION
A descriptor pool creation has failed due to fragmentation. -
VK_ERROR_INVALID_DEVICE_ADDRESS_EXT
A buffer creation failed because the requested address is not available. -
VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS
A buffer creation or memory allocation failed because the requested address is not available. A shader group handle assignment failed because the requested shader group handle information is no longer valid. -
VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT
An operation on a swapchain created withVK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT
failed as it did not have exlusive full-screen access. This may occur due to implementation-dependent reasons, outside of the application’s control. -
VK_ERROR_UNKNOWN
An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.
If a command returns a runtime error, unless otherwise specified any output
parameters will have undefined contents, except that if the output
parameter is a structure with sType
and pNext
fields, those
fields will be unmodified.
Any structures chained from pNext
will also have undefined contents,
except that sType
and pNext
will be unmodified.
Out of memory errors do not damage any currently existing Vulkan objects. Objects that have already been successfully created can still be used by the application.
VK_ERROR_UNKNOWN
will be returned by an implementation when an
unexpected error occurs that cannot be attributed to valid behavior of the
application and implementation.
Under these conditions, it may be returned from any command returning a
VkResult.
Note
|
Performance-critical commands generally do not have return codes.
If a runtime error occurs in such commands, the implementation will defer
reporting the error until a specified point.
For commands that record into command buffers (vkCmd*
) runtime errors
are reported by vkEndCommandBuffer
.
2.8. Numeric Representation and Computation
Implementations normally perform computations in floating-point, and must meet the range and precision requirements defined under “Floating-Point Computation” below.
These requirements only apply to computations performed in Vulkan operations outside of shader execution, such as texture image specification and sampling, and per-fragment operations. Range and precision requirements during shader execution differ and are specified by the Precision and Operation of SPIR-V Instructions section.
In some cases, the representation and/or precision of operations is implicitly limited by the specified format of vertex or texel data consumed by Vulkan. Specific floating-point formats are described later in this section.
2.8.1. Floating-Point Computation
Most floating-point computation is performed in SPIR-V shader modules. The properties of computation within shaders are constrained as defined by the Precision and Operation of SPIR-V Instructions section.
Some floating-point computation is performed outside of shaders, such as viewport and depth range calculations. For these computations, we do not specify how floating-point numbers are to be represented, or the details of how operations on them are performed, but only place minimal requirements on representation and precision as described in the remainder of this section.
editing-note
(Jon, Bug 14966) This is a rat’s nest of complexity, both in terms of describing/enumerating places such computation may take place (other than “not shader code”) and in how implementations may do it. We have consciously deferred the resolution of this issue to post-1.0, and in the meantime, the following language inherited from the OpenGL Specification is inserted as a placeholder. Hopefully it can be tightened up considerably. |
We require simply that numbers’ floating-point parts contain enough bits and that their exponent fields are large enough so that individual results of floating-point operations are accurate to about 1 part in 105. The maximum representable magnitude for all floating-point values must be at least 232.
-
x × 0 = 0 × x = 0 for any non-infinite and non-NaN x.
-
1 × x = x × 1 = x.
-
x + 0 = 0 + x = x.
-
00 = 1.
Occasionally, further requirements will be specified. Most single-precision floating-point formats meet these requirements.
The special values Inf and -Inf encode values with magnitudes too large to be represented; the special value NaN encodes “Not A Number” values resulting from undefined arithmetic operations such as 0 / 0. Implementations may support Inf and NaN in their floating-point computations.
2.8.2. Floating-Point Format Conversions
When a value is converted to a defined floating-point representation, finite values falling between two representable finite values are rounded to one or the other. The rounding mode is not defined. Finite values whose magnitude is larger than that of any representable finite value may be rounded either to the closest representable finite value or to the appropriately signed infinity. For unsigned destination formats any negative values are converted to zero. Positive infinity is converted to positive infinity; negative infinity is converted to negative infinity in signed formats and to zero in unsigned formats; and any NaN is converted to a NaN.
2.8.3. 16-Bit Floating-Point Numbers
16-bit floating point numbers are defined in the “16-bit floating point numbers” section of the Khronos Data Format Specification.
2.8.4. Unsigned 11-Bit Floating-Point Numbers
Unsigned 11-bit floating point numbers are defined in the “Unsigned 11-bit floating point numbers” section of the Khronos Data Format Specification.
2.8.5. Unsigned 10-Bit Floating-Point Numbers
Unsigned 10-bit floating point numbers are defined in the “Unsigned 10-bit floating point numbers” section of the Khronos Data Format Specification.
2.8.6. General Requirements
Any representable floating-point value in the appropriate format is legal as input to a Vulkan command that requires floating-point data. The result of providing a value that is not a floating-point number to such a command is unspecified, but must not lead to Vulkan interruption or termination. For example, providing a negative zero (where applicable) or a denormalized number to a Vulkan command must yield deterministic results, while providing a NaN or Inf yields unspecified results.
Some calculations require division. In such cases (including implied divisions performed by vector normalization), division by zero produces an unspecified result but must not lead to Vulkan interruption or termination.
2.9. Fixed-Point Data Conversions
When generic vertex attributes and pixel color or depth components are represented as integers, they are often (but not always) considered to be normalized. Normalized integer values are treated specially when being converted to and from floating-point values, and are usually referred to as normalized fixed-point.
In the remainder of this section, b denotes the bit width of the fixed-point integer representation. When the integer is one of the types defined by the API, b is the bit width of that type. When the integer comes from an image containing color or depth component texels, b is the number of bits allocated to that component in its specified image format.
The signed and unsigned fixed-point representations are assumed to be b-bit binary two’s-complement integers and binary unsigned integers, respectively.
2.9.1. Conversion from Normalized Fixed-Point to Floating-Point
Unsigned normalized fixed-point integers represent numbers in the range [0,1]. The conversion from an unsigned normalized fixed-point value c to the corresponding floating-point value f is defined as
Signed normalized fixed-point integers represent numbers in the range [-1,1]. The conversion from a signed normalized fixed-point value c to the corresponding floating-point value f is performed using
Only the range [-2b-1 + 1, 2b-1 - 1] is used to represent signed fixed-point values in the range [-1,1]. For example, if b = 8, then the integer value -127 corresponds to -1.0 and the value 127 corresponds to 1.0. Note that while zero is exactly expressible in this representation, one value (-128 in the example) is outside the representable range, and must be clamped before use. This equation is used everywhere that signed normalized fixed-point values are converted to floating-point.
2.9.2. Conversion from Floating-Point to Normalized Fixed-Point
The conversion from a floating-point value f to the corresponding unsigned normalized fixed-point value c is defined by first clamping f to the range [0,1], then computing
-
c = convertFloatToUint(f × (2b - 1), b)
where convertFloatToUint}(r,b) returns one of the two unsigned binary integer values with exactly b bits which are closest to the floating-point value r. Implementations should round to nearest. If r is equal to an integer, then that integer value must be returned. In particular, if f is equal to 0.0 or 1.0, then c must be assigned 0 or 2b - 1, respectively.
The conversion from a floating-point value f to the corresponding signed normalized fixed-point value c is performed by clamping f to the range [-1,1], then computing
-
c = convertFloatToInt(f × (2b-1 - 1), b)
where convertFloatToInt(r,b) returns one of the two signed two’s-complement binary integer values with exactly b bits which are closest to the floating-point value r. Implementations should round to nearest. If r is equal to an integer, then that integer value must be returned. In particular, if f is equal to -1.0, 0.0, or 1.0, then c must be assigned -(2b-1 - 1), 0, or 2b-1 - 1, respectively.
This equation is used everywhere that floating-point values are converted to signed normalized fixed-point.
2.10. Common Object Types
Some types of Vulkan objects are used in many different structures and command parameters, and are described here. These types include offsets, extents, and rectangles.
2.10.1. Offsets
Offsets are used to describe a pixel location within an image or framebuffer, as an (x,y) location for two-dimensional images, or an (x,y,z) location for three-dimensional images.
A two-dimensional offsets is defined by the structure:
// Provided by VK_VERSION_1_0
typedef struct VkOffset2D {
int32_t x;
int32_t y;
} VkOffset2D;
-
x
is the x offset. -
y
is the y offset.
A three-dimensional offset is defined by the structure:
// Provided by VK_VERSION_1_0
typedef struct VkOffset3D {
int32_t x;
int32_t y;
int32_t z;
} VkOffset3D;
-
x
is the x offset. -
y
is the y offset. -
z
is the z offset.
2.10.2. Extents
Extents are used to describe the size of a rectangular region of pixels within an image or framebuffer, as (width,height) for two-dimensional images, or as (width,height,depth) for three-dimensional images.
A two-dimensional extent is defined by the structure:
// Provided by VK_VERSION_1_0
typedef struct VkExtent2D {
uint32_t width;
uint32_t height;
} VkExtent2D;
-
width
is the width of the extent. -
height
is the height of the extent.
A three-dimensional extent is defined by the structure:
// Provided by VK_VERSION_1_0
typedef struct VkExtent3D {
uint32_t width;
uint32_t height;
uint32_t depth;
} VkExtent3D;
-
width
is the width of the extent. -
height
is the height of the extent. -
depth
is the depth of the extent.
2.10.3. Rectangles
Rectangles are used to describe a specified rectangular region of pixels within an image or framebuffer. Rectangles include both an offset and an extent of the same dimensionality, as described above. Two-dimensional rectangles are defined by the structure
// Provided by VK_VERSION_1_0
typedef struct VkRect2D {
VkOffset2D offset;
VkExtent2D extent;
} VkRect2D;
-
offset
is a VkOffset2D specifying the rectangle offset. -
extent
is a VkExtent2D specifying the rectangle extent.
3. Initialization
Before using Vulkan, an application must initialize it by loading the
Vulkan commands, and creating a VkInstance
object.
3.1. Command Function Pointers
Vulkan commands are not necessarily exposed by static linking on a platform. Commands to query function pointers for Vulkan commands are described below.
Note
When extensions are promoted or otherwise incorporated into another extension or Vulkan core version, command aliases may be included. Whilst the behavior of each command alias is identical, the behavior of retrieving each alias’s function pointer is not. A function pointer for a given alias can only be retrieved if the extension or version that introduced that alias is supported and enabled, irrespective of whether any other alias is available. |
Function pointers for all Vulkan commands can be obtained with the command:
// Provided by VK_VERSION_1_0
PFN_vkVoidFunction vkGetInstanceProcAddr(
VkInstance instance,
const char* pName);
-
instance
is the instance that the function pointer will be compatible with, orNULL
for commands not dependent on any instance. -
pName
is the name of the command to obtain.
vkGetInstanceProcAddr
itself is obtained in a platform- and loader-
specific manner.
Typically, the loader library will export this command as a function symbol,
so applications can link against the loader library, or load it dynamically
and look up the symbol using platform-specific APIs.
The table below defines the various use cases for
vkGetInstanceProcAddr
and expected return value (“fp” is “function
pointer”) for each case.
The returned function pointer is of type PFN_vkVoidFunction, and must be cast to the type of the command being queried before use.
instance |
pName |
return value |
---|---|---|
*1 |
|
undefined |
invalid non- |
*1 |
undefined |
|
fp4 |
|
|
fp |
|
|
fp |
|
|
fp |
|
|
fp |
|
instance |
core Vulkan command |
fp2 |
instance |
enabled instance extension commands for |
fp2 |
instance |
available device extension3 commands for |
fp2 |
any other case, not covered above |
|
- 1
-
"*" means any representable value for the parameter (including valid values, invalid values, and
NULL
). - 2
-
The returned function pointer must only be called with a dispatchable object (the first parameter) that is
instance
or a child ofinstance
, e.g. VkInstance, VkPhysicalDevice, VkDevice, VkQueue, or VkCommandBuffer. - 3
-
An “available device extension” is a device extension supported by any physical device enumerated by
instance
. - 4
-
Starting with Vulkan 1.2,
vkGetInstanceProcAddr
can resolve itself with aNULL
instance pointer.
In order to support systems with multiple Vulkan implementations, the
function pointers returned by vkGetInstanceProcAddr
may point to
dispatch code that calls a different real implementation for different
VkDevice objects or their child objects.
The overhead of the internal dispatch for VkDevice objects can be
avoided by obtaining device-specific function pointers for any commands that
use a device or device-child object as their dispatchable object.
Such function pointers can be obtained with the command:
// Provided by VK_VERSION_1_0
PFN_vkVoidFunction vkGetDeviceProcAddr(
VkDevice device,
const char* pName);
The table below defines the various use cases for vkGetDeviceProcAddr
and expected return value for each case.
The returned function pointer is of type PFN_vkVoidFunction, and must
be cast to the type of the command being queried before use.
The function pointer must only be called with a dispatchable object (the
first parameter) that is device
or a child of device
.
device |
pName |
return value |
---|---|---|
|
*1 |
undefined |
invalid device |
*1 |
undefined |
device |
|
undefined |
device |
core device-level Vulkan command |
fp2 |
device |
enabled extension device-level commands |
fp2 |
any other case, not covered above |
|
- 1
-
"*" means any representable value for the parameter (including valid values, invalid values, and
NULL
). - 2
-
The returned function pointer must only be called with a dispatchable object (the first parameter) that is
device
or a child ofdevice
e.g. VkDevice, VkQueue, or VkCommandBuffer.
The definition of PFN_vkVoidFunction is:
// Provided by VK_VERSION_1_0
typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);
3.1.1. Extending Physical Device Core Functionality
New core physical-device-level functionality can be used when the physical-device version is greater than or equal to the version of Vulkan that added the new functionality. The Vulkan version supported by a physical device can be obtained by calling vkGetPhysicalDeviceProperties.
3.1.2. Extending Physical Device From Device Extensions
When the VK_KHR_get_physical_device_properties2
extension is enabled,
or when both the instance and the physical-device versions are at least 1.1,
physical-device-level functionality of a device extension can be used with
a physical device if the corresponding extension is enumerated by
vkEnumerateDeviceExtensionProperties for that physical device, even
before a logical device has been created.
To obtain a function pointer for a physical-device-level command from a
device extension, an application can use vkGetInstanceProcAddr.
This function pointer may point to dispatch code, which calls a different
real implementation for different VkPhysicalDevice
objects.
Applications must not use a VkPhysicalDevice in any command added by
an extension or core version that is not supported by that physical device.
Device extensions may define structures that can be added to the
pNext
chain of physical-device-level commands.
3.2. Instances
There is no global state in Vulkan and all per-application state is stored
in a VkInstance
object.
Creating a VkInstance
object initializes the Vulkan library and allows
the application to pass information about itself to the implementation.
Instances are represented by VkInstance
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkInstance)
To query the version of instance-level functionality supported by the implementation, call:
// Provided by VK_VERSION_1_1
VkResult vkEnumerateInstanceVersion(
uint32_t* pApiVersion);
-
pApiVersion
is a pointer to auint32_t
, which is the version of Vulkan supported by instance-level functionality, encoded as described in Version Numbers.
Note
The intended behaviour of vkEnumerateInstanceVersion is that an
implementation should not need to perform memory allocations and should
unconditionally return |
To create an instance object, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance);
-
pCreateInfo
is a pointer to a VkInstanceCreateInfo structure controlling creation of the instance. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pInstance
points a VkInstance handle in which the resulting instance is returned.
vkCreateInstance
verifies that the requested layers exist.
If not, vkCreateInstance
will return VK_ERROR_LAYER_NOT_PRESENT
.
Next vkCreateInstance
verifies that the requested extensions are
supported (e.g. in the implementation or in any enabled instance layer) and
if any requested extension is not supported, vkCreateInstance
must
return VK_ERROR_EXTENSION_NOT_PRESENT
.
After verifying and enabling the instance layers and extensions the
VkInstance
object is created and returned to the application.
If a requested extension is only supported by a layer, both the layer and
the extension need to be specified at vkCreateInstance
time for the
creation to succeed.
The VkInstanceCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkInstanceCreateInfo {
VkStructureType sType;
const void* pNext;
VkInstanceCreateFlags flags;
const VkApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
} VkInstanceCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
pApplicationInfo
isNULL
or a pointer to aVkApplicationInfo
structure. If notNULL
, this information helps implementations recognize behavior inherent to classes of applications. VkApplicationInfo is defined in detail below. -
enabledLayerCount
is the number of global layers to enable. -
ppEnabledLayerNames
is a pointer to an array ofenabledLayerCount
null-terminated UTF-8 strings containing the names of layers to enable for the created instance. The layers are loaded in the order they are listed in this array, with the first array element being the closest to the application, and the last array element being the closest to the driver. See the Layers section for further details. -
enabledExtensionCount
is the number of global extensions to enable. -
ppEnabledExtensionNames
is a pointer to an array ofenabledExtensionCount
null-terminated UTF-8 strings containing the names of extensions to enable.
// Provided by VK_VERSION_1_0
typedef VkFlags VkInstanceCreateFlags;
VkInstanceCreateFlags
is a bitmask type for setting a mask, but is
currently reserved for future use.
When creating a Vulkan instance for which you wish to disable validation
checks, add a VkValidationFlagsEXT structure to the pNext
chain
of the VkInstanceCreateInfo structure, specifying the checks to be
disabled.
// Provided by VK_EXT_validation_flags
typedef struct VkValidationFlagsEXT {
VkStructureType sType;
const void* pNext;
uint32_t disabledValidationCheckCount;
const VkValidationCheckEXT* pDisabledValidationChecks;
} VkValidationFlagsEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
disabledValidationCheckCount
is the number of checks to disable. -
pDisabledValidationChecks
is a pointer to an array of VkValidationCheckEXT values specifying the validation checks to be disabled.
Possible values of elements of the
VkValidationFlagsEXT::pDisabledValidationChecks
array,
specifying validation checks to be disabled, are:
// Provided by VK_EXT_validation_flags
typedef enum VkValidationCheckEXT {
VK_VALIDATION_CHECK_ALL_EXT = 0,
VK_VALIDATION_CHECK_SHADERS_EXT = 1,
} VkValidationCheckEXT;
-
VK_VALIDATION_CHECK_ALL_EXT
specifies that all validation checks are disabled. -
VK_VALIDATION_CHECK_SHADERS_EXT
specifies that shader validation is disabled.
When creating a Vulkan instance for which you wish to enable or disable
specific validation features, add a VkValidationFeaturesEXT structure
to the pNext
chain of the VkInstanceCreateInfo structure,
specifying the features to be enabled or disabled.
// Provided by VK_EXT_validation_features
typedef struct VkValidationFeaturesEXT {
VkStructureType sType;
const void* pNext;
uint32_t enabledValidationFeatureCount;
const VkValidationFeatureEnableEXT* pEnabledValidationFeatures;
uint32_t disabledValidationFeatureCount;
const VkValidationFeatureDisableEXT* pDisabledValidationFeatures;
} VkValidationFeaturesEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
enabledValidationFeatureCount
is the number of features to enable. -
pEnabledValidationFeatures
is a pointer to an array of VkValidationFeatureEnableEXT values specifying the validation features to be enabled. -
disabledValidationFeatureCount
is the number of features to disable. -
pDisabledValidationFeatures
is a pointer to an array of VkValidationFeatureDisableEXT values specifying the validation features to be disabled.
Possible values of elements of the
VkValidationFeaturesEXT::pEnabledValidationFeatures
array,
specifying validation features to be enabled, are:
// Provided by VK_EXT_validation_features
typedef enum VkValidationFeatureEnableEXT {
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0,
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1,
VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2,
VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3,
} VkValidationFeatureEnableEXT;
-
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT
specifies that GPU-assisted validation is enabled. Activating this feature instruments shader programs to generate additional diagnostic data. This feature is disabled by default. -
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT
specifies that the validation layers reserve a descriptor set binding slot for their own use. The layer reports a value for VkPhysicalDeviceLimits::maxBoundDescriptorSets
that is one less than the value reported by the device. If the device supports the binding of only one descriptor set, the validation layer does not perform GPU-assisted validation. This feature is disabled by default. -
VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT
specifies that Vulkan best-practices validation is enabled. Activating this feature enables the output of warnings related to common misuse of the API, but which are not explicitly prohibited by the specification. This feature is disabled by default. -
VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT
specifies that the layers will processdebugPrintfEXT
operations in shaders and send the resulting output to the debug callback. This feature is disabled by default.
Possible values of elements of the
VkValidationFeaturesEXT::pDisabledValidationFeatures
array,
specifying validation features to be disabled, are:
// Provided by VK_EXT_validation_features
typedef enum VkValidationFeatureDisableEXT {
VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0,
VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1,
VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2,
VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3,
VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4,
VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5,
VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6,
} VkValidationFeatureDisableEXT;
-
VK_VALIDATION_FEATURE_DISABLE_ALL_EXT
specifies that all validation checks are disabled. -
VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT
specifies that shader validation is disabled. This feature is enabled by default. -
VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT
specifies that thread safety validation is disabled. This feature is enabled by default. -
VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT
specifies that stateless parameter validation is disabled. This feature is enabled by default. -
VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT
specifies that object lifetime validation is disabled. This feature is enabled by default. -
VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT
specifies that core validation checks are disabled. This feature is enabled by default. If this feature is disabled, the shader validation and GPU-assisted validation features are also disabled. -
VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT
specifies that protection against duplicate non-dispatchable object handles is disabled. This feature is enabled by default.
Note
Disabling checks such as parameter validation and object lifetime validation prevents the reporting of error conditions that can cause other validation checks to behave incorrectly or crash. Some validation checks assume that their inputs are already valid and do not always revalidate them. |
Note
The |
The VkApplicationInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkApplicationInfo {
VkStructureType sType;
const void* pNext;
const char* pApplicationName;
uint32_t applicationVersion;
const char* pEngineName;
uint32_t engineVersion;
uint32_t apiVersion;
} VkApplicationInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pApplicationName
isNULL
or is a pointer to a null-terminated UTF-8 string containing the name of the application. -
applicationVersion
is an unsigned integer variable containing the developer-supplied version number of the application. -
pEngineName
isNULL
or is a pointer to a null-terminated UTF-8 string containing the name of the engine (if any) used to create the application. -
engineVersion
is an unsigned integer variable containing the developer-supplied version number of the engine used to create the application. -
apiVersion
must be the highest version of Vulkan that the application is designed to use, encoded as described in Version Numbers. The patch version number specified inapiVersion
is ignored when creating an instance object. Only the major and minor versions of the instance must match those requested inapiVersion
.
Vulkan 1.0 implementations were required to return
VK_ERROR_INCOMPATIBLE_DRIVER
if apiVersion
was larger than 1.0.
Implementations that support Vulkan 1.1 or later must not return
VK_ERROR_INCOMPATIBLE_DRIVER
for any value of apiVersion
.
Note
Because Vulkan 1.0 implementations may fail with
|
As long as the instance supports at least Vulkan 1.1, an application can use different versions of Vulkan with an instance than it does with a device or physical device.
Note
The Khronos validation layers will treat For example, if the instance supports Vulkan 1.1 and three physical devices
support Vulkan 1.0, Vulkan 1.1, and Vulkan 1.2, respectively, and if the
application sets
If we modify the above example so that the application sets |
Implicit layers must be disabled if they do not support a version at least
as high as apiVersion
.
See the Vulkan Loader Specification and
Architecture Overview document for additional information.
Note
Providing a |
To destroy an instance, call:
// Provided by VK_VERSION_1_0
void vkDestroyInstance(
VkInstance instance,
const VkAllocationCallbacks* pAllocator);
-
instance
is the handle of the instance to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
4. Devices and Queues
Once Vulkan is initialized, devices and queues are the primary objects used to interact with a Vulkan implementation.
Vulkan separates the concept of physical and logical devices. A physical device usually represents a single complete implementation of Vulkan (excluding instance-level functionality) available to the host, of which there are a finite number. A logical device represents an instance of that implementation with its own state and resources independent of other logical devices.
Physical devices are represented by VkPhysicalDevice
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkPhysicalDevice)
4.1. Physical Devices
To retrieve a list of physical device objects representing the physical devices installed in the system, call:
// Provided by VK_VERSION_1_0
VkResult vkEnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices);
-
instance
is a handle to a Vulkan instance previously created with vkCreateInstance. -
pPhysicalDeviceCount
is a pointer to an integer related to the number of physical devices available or queried, as described below. -
pPhysicalDevices
is eitherNULL
or a pointer to an array ofVkPhysicalDevice
handles.
If pPhysicalDevices
is NULL
, then the number of physical devices
available is returned in pPhysicalDeviceCount
.
Otherwise, pPhysicalDeviceCount
must point to a variable set by the
user to the number of elements in the pPhysicalDevices
array, and on
return the variable is overwritten with the number of handles actually
written to pPhysicalDevices
.
If pPhysicalDeviceCount
is less than the number of physical devices
available, at most pPhysicalDeviceCount
structures will be written.
If pPhysicalDeviceCount
is smaller than the number of physical devices
available, VK_INCOMPLETE
will be returned instead of VK_SUCCESS
,
to indicate that not all the available physical devices were returned.
To query general properties of physical devices once enumerated, call:
// Provided by VK_VERSION_1_0
void vkGetPhysicalDeviceProperties(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties* pProperties);
-
physicalDevice
is the handle to the physical device whose properties will be queried. -
pProperties
is a pointer to a VkPhysicalDeviceProperties structure in which properties are returned.
The VkPhysicalDeviceProperties
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPhysicalDeviceProperties {
uint32_t apiVersion;
uint32_t driverVersion;
uint32_t vendorID;
uint32_t deviceID;
VkPhysicalDeviceType deviceType;
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
uint8_t pipelineCacheUUID[VK_UUID_SIZE];
VkPhysicalDeviceLimits limits;
VkPhysicalDeviceSparseProperties sparseProperties;
} VkPhysicalDeviceProperties;
-
apiVersion
is the version of Vulkan supported by the device, encoded as described in Version Numbers. -
driverVersion
is the vendor-specified version of the driver. -
vendorID
is a unique identifier for the vendor (see below) of the physical device. -
deviceID
is a unique identifier for the physical device among devices available from the vendor. -
deviceType
is a VkPhysicalDeviceType specifying the type of device. -
deviceName
is an array ofVK_MAX_PHYSICAL_DEVICE_NAME_SIZE
char
containing a null-terminated UTF-8 string which is the name of the device. -
pipelineCacheUUID
is an array ofVK_UUID_SIZE
uint8_t
values representing a universally unique identifier for the device. -
limits
is the VkPhysicalDeviceLimits structure specifying device-specific limits of the physical device. See Limits for details. -
sparseProperties
is the VkPhysicalDeviceSparseProperties structure specifying various sparse related properties of the physical device. See Sparse Properties for details.
Note
The value of |
The vendorID
and deviceID
fields are provided to allow
applications to adapt to device characteristics that are not adequately
exposed by other Vulkan queries.
Note
These may include performance profiles, hardware errata, or other characteristics. |
The vendor identified by vendorID
is the entity responsible for the
most salient characteristics of the underlying implementation of the
VkPhysicalDevice being queried.
Note
For example, in the case of a discrete GPU implementation, this should be the GPU chipset vendor. In the case of a hardware accelerator integrated into a system-on-chip (SoC), this should be the supplier of the silicon IP used to create the accelerator. |
If the vendor has a PCI
vendor ID, the low 16 bits of vendorID
must contain that PCI vendor
ID, and the remaining bits must be set to zero.
Otherwise, the value returned must be a valid Khronos vendor ID, obtained
as described in the Vulkan Documentation and Extensions:
Procedures and Conventions document in the section “Registering a Vendor
ID with Khronos”.
Khronos vendor IDs are allocated starting at 0x10000, to distinguish them
from the PCI vendor ID namespace.
Khronos vendor IDs are symbolically defined in the VkVendorId type.
The vendor is also responsible for the value returned in deviceID
.
If the implementation is driven primarily by a PCI
device with a PCI device ID, the low 16 bits of
deviceID
must contain that PCI device ID, and the remaining bits
must be set to zero.
Otherwise, the choice of what values to return may be dictated by operating
system or platform policies - but should uniquely identify both the device
version and any major configuration options (for example, core count in the
case of multicore devices).
Note
The same device ID should be used for all physical implementations of that device version and configuration. For example, all uses of a specific silicon IP GPU version and configuration should use the same device ID, even if those uses occur in different SoCs. |
Khronos vendor IDs which may be returned in
VkPhysicalDeviceProperties::vendorID
are:
// Provided by VK_VERSION_1_0
typedef enum VkVendorId {
VK_VENDOR_ID_VIV = 0x10001,
VK_VENDOR_ID_VSI = 0x10002,
VK_VENDOR_ID_KAZAN = 0x10003,
VK_VENDOR_ID_CODEPLAY = 0x10004,
VK_VENDOR_ID_MESA = 0x10005,
} VkVendorId;
Note
Khronos vendor IDs may be allocated by vendors at any time.
Only the latest canonical versions of this Specification, of the
corresponding Only Khronos vendor IDs are given symbolic names at present. PCI vendor IDs returned by the implementation can be looked up in the PCI-SIG database. |
The physical device types which may be returned in
VkPhysicalDeviceProperties::deviceType
are:
// Provided by VK_VERSION_1_0
typedef enum VkPhysicalDeviceType {
VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
} VkPhysicalDeviceType;
-
VK_PHYSICAL_DEVICE_TYPE_OTHER
- the device does not match any other available types. -
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
- the device is typically one embedded in or tightly coupled with the host. -
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
- the device is typically a separate processor connected to the host via an interlink. -
VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU
- the device is typically a virtual node in a virtualization environment. -
VK_PHYSICAL_DEVICE_TYPE_CPU
- the device is typically running on the same processors as the host.
The physical device type is advertised for informational purposes only, and does not directly affect the operation of the system. However, the device type may correlate with other advertised properties or capabilities of the system, such as how many memory heaps there are.
To query general properties of physical devices once enumerated, call:
// Provided by VK_VERSION_1_1
void vkGetPhysicalDeviceProperties2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2* pProperties);
or the equivalent command
// Provided by VK_KHR_get_physical_device_properties2
void vkGetPhysicalDeviceProperties2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2* pProperties);
-
physicalDevice
is the handle to the physical device whose properties will be queried. -
pProperties
is a pointer to a VkPhysicalDeviceProperties2 structure in which properties are returned.
Each structure in pProperties
and its pNext
chain contain
members corresponding to properties or implementation-dependent limits.
vkGetPhysicalDeviceProperties2
writes each member to a value
indicating the value of that property or limit.
The VkPhysicalDeviceProperties2
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkPhysicalDeviceProperties2 {
VkStructureType sType;
void* pNext;
VkPhysicalDeviceProperties properties;
} VkPhysicalDeviceProperties2;
or the equivalent
// Provided by VK_KHR_get_physical_device_properties2
typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
properties
is a VkPhysicalDeviceProperties structure describing properties of the physical device. This structure is written with the same values as if it were written by vkGetPhysicalDeviceProperties.
The pNext
chain of this structure is used to extend the structure with
properties defined by extensions.
To query the properties of the driver corresponding to Vulkan 1.1
functionality, add VkPhysicalDeviceVulkan11Properties to the
pNext
chain of the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceVulkan11Properties
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkPhysicalDeviceVulkan11Properties {
VkStructureType sType;
void* pNext;
uint8_t deviceUUID[VK_UUID_SIZE];
uint8_t driverUUID[VK_UUID_SIZE];
uint8_t deviceLUID[VK_LUID_SIZE];
uint32_t deviceNodeMask;
VkBool32 deviceLUIDValid;
uint32_t subgroupSize;
VkShaderStageFlags subgroupSupportedStages;
VkSubgroupFeatureFlags subgroupSupportedOperations;
VkBool32 subgroupQuadOperationsInAllStages;
VkPointClippingBehavior pointClippingBehavior;
uint32_t maxMultiviewViewCount;
uint32_t maxMultiviewInstanceIndex;
VkBool32 protectedNoFault;
uint32_t maxPerSetDescriptors;
VkDeviceSize maxMemoryAllocationSize;
} VkPhysicalDeviceVulkan11Properties;
-
deviceUUID
is an array ofVK_UUID_SIZE
uint8_t
values representing a universally unique identifier for the device. -
driverUUID
is an array ofVK_UUID_SIZE
uint8_t
values representing a universally unique identifier for the driver build in use by the device. -
deviceLUID
is an array ofVK_LUID_SIZE
uint8_t
values representing a locally unique identifier for the device. -
deviceNodeMask
is auint32_t
bitfield identifying the node within a linked device adapter corresponding to the device. -
deviceLUIDValid
is a boolean value that will beVK_TRUE
ifdeviceLUID
contains a valid LUID anddeviceNodeMask
contains a valid node mask, andVK_FALSE
if they do not. -
subgroupSize
is the default number of invocations in each subgroup.subgroupSize
is at least 1 if any of the physical device’s queues supportVK_QUEUE_GRAPHICS_BIT
orVK_QUEUE_COMPUTE_BIT
.subgroupSize
is a power-of-two. -
subgroupSupportedStages
is a bitfield of VkShaderStageFlagBits describing the shader stages that subgroup operations are supported in.subgroupSupportedStages
will have theVK_SHADER_STAGE_COMPUTE_BIT
bit set if any of the physical device’s queues supportVK_QUEUE_COMPUTE_BIT
. -
subgroupSupportedOperations
is a bitmask of VkSubgroupFeatureFlagBits specifying the sets of subgroup operations supported on this device.subgroupSupportedOperations
will have theVK_SUBGROUP_FEATURE_BASIC_BIT
bit set if any of the physical device’s queues supportVK_QUEUE_GRAPHICS_BIT
orVK_QUEUE_COMPUTE_BIT
. -
subgroupQuadOperationsInAllStages
is a boolean specifying whether quad subgroup operations are available in all stages, or are restricted to fragment and compute stages. -
pointClippingBehavior
is a VkPointClippingBehavior value specifying the point clipping behavior supported by the implementation. -
maxMultiviewViewCount
is one greater than the maximum view index that can be used in a subpass. -
maxMultiviewInstanceIndex
is the maximum valid value of instance index allowed to be generated by a drawing command recorded within a subpass of a multiview render pass instance. -
protectedNoFault
specifies the behavior of the implementation when protected memory access rules are broken. IfprotectedNoFault
isVK_TRUE
, breaking those rules will not result in process termination or device loss. -
maxPerSetDescriptors
is a maximum number of descriptors (summed over all descriptor types) in a single descriptor set that is guaranteed to satisfy any implementation-dependent constraints on the size of a descriptor set itself. Applications can query whether a descriptor set that goes beyond this limit is supported using vkGetDescriptorSetLayoutSupport. -
maxMemoryAllocationSize
is the maximum size of a memory allocation that can be created, even if there is more space available in the heap.
The members of VkPhysicalDeviceVulkan11Properties
must have the same
values as the corresponding members of VkPhysicalDeviceIDProperties,
VkPhysicalDeviceSubgroupProperties,
VkPhysicalDevicePointClippingProperties,
VkPhysicalDeviceMultiviewProperties,
VkPhysicalDeviceProtectedMemoryProperties, and
VkPhysicalDeviceMaintenance3Properties.
To query the properties of the driver corresponding to Vulkan 1.2
functionality, add VkPhysicalDeviceVulkan12Properties to the
pNext
chain of the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceVulkan12Properties
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkPhysicalDeviceVulkan12Properties {
VkStructureType sType;
void* pNext;
VkDriverId driverID;
char driverName[VK_MAX_DRIVER_NAME_SIZE];
char driverInfo[VK_MAX_DRIVER_INFO_SIZE];
VkConformanceVersion conformanceVersion;
VkShaderFloatControlsIndependence denormBehaviorIndependence;
VkShaderFloatControlsIndependence roundingModeIndependence;
VkBool32 shaderSignedZeroInfNanPreserveFloat16;
VkBool32 shaderSignedZeroInfNanPreserveFloat32;
VkBool32 shaderSignedZeroInfNanPreserveFloat64;
VkBool32 shaderDenormPreserveFloat16;
VkBool32 shaderDenormPreserveFloat32;
VkBool32 shaderDenormPreserveFloat64;
VkBool32 shaderDenormFlushToZeroFloat16;
VkBool32 shaderDenormFlushToZeroFloat32;
VkBool32 shaderDenormFlushToZeroFloat64;
VkBool32 shaderRoundingModeRTEFloat16;
VkBool32 shaderRoundingModeRTEFloat32;
VkBool32 shaderRoundingModeRTEFloat64;
VkBool32 shaderRoundingModeRTZFloat16;
VkBool32 shaderRoundingModeRTZFloat32;
VkBool32 shaderRoundingModeRTZFloat64;
uint32_t maxUpdateAfterBindDescriptorsInAllPools;
VkBool32 shaderUniformBufferArrayNonUniformIndexingNative;
VkBool32 shaderSampledImageArrayNonUniformIndexingNative;
VkBool32 shaderStorageBufferArrayNonUniformIndexingNative;
VkBool32 shaderStorageImageArrayNonUniformIndexingNative;
VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative;
VkBool32 robustBufferAccessUpdateAfterBind;
VkBool32 quadDivergentImplicitLod;
uint32_t maxPerStageDescriptorUpdateAfterBindSamplers;
uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers;
uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers;
uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages;
uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages;
uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments;
uint32_t maxPerStageUpdateAfterBindResources;
uint32_t maxDescriptorSetUpdateAfterBindSamplers;
uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers;
uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers;
uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
uint32_t maxDescriptorSetUpdateAfterBindSampledImages;
uint32_t maxDescriptorSetUpdateAfterBindStorageImages;
uint32_t maxDescriptorSetUpdateAfterBindInputAttachments;
VkResolveModeFlags supportedDepthResolveModes;
VkResolveModeFlags supportedStencilResolveModes;
VkBool32 independentResolveNone;
VkBool32 independentResolve;
VkBool32 filterMinmaxSingleComponentFormats;
VkBool32 filterMinmaxImageComponentMapping;
uint64_t maxTimelineSemaphoreValueDifference;
VkSampleCountFlags framebufferIntegerColorSampleCounts;
} VkPhysicalDeviceVulkan12Properties;
-
driverID
is a unique identifier for the driver of the physical device. -
driverName
is an array ofVK_MAX_DRIVER_NAME_SIZE
char
containing a null-terminated UTF-8 string which is the name of the driver. -
driverInfo
is an array ofVK_MAX_DRIVER_INFO_SIZE
char
containing a null-terminated UTF-8 string with additional information about the driver. -
conformanceVersion
is the version of the Vulkan conformance test this driver is conformant against (see VkConformanceVersion). -
denormBehaviorIndependence
is a VkShaderFloatControlsIndependence value indicating whether, and how, denorm behavior can be set independently for different bit widths. -
roundingModeIndependence
is a VkShaderFloatControlsIndependence value indicating whether, and how, rounding modes can be set independently for different bit widths. -
shaderSignedZeroInfNanPreserveFloat16
is a boolean value indicating whether sign of a zero, Nans and can be preserved in 16-bit floating-point computations. It also indicates whether theSignedZeroInfNanPreserve
execution mode can be used for 16-bit floating-point types. -
shaderSignedZeroInfNanPreserveFloat32
is a boolean value indicating whether sign of a zero, Nans and can be preserved in 32-bit floating-point computations. It also indicates whether theSignedZeroInfNanPreserve
execution mode can be used for 32-bit floating-point types. -
shaderSignedZeroInfNanPreserveFloat64
is a boolean value indicating whether sign of a zero, Nans and can be preserved in 64-bit floating-point computations. It also indicates whether theSignedZeroInfNanPreserve
execution mode can be used for 64-bit floating-point types. -
shaderDenormPreserveFloat16
is a boolean value indicating whether denormals can be preserved in 16-bit floating-point computations. It also indicates whether theDenormPreserve
execution mode can be used for 16-bit floating-point types. -
shaderDenormPreserveFloat32
is a boolean value indicating whether denormals can be preserved in 32-bit floating-point computations. It also indicates whether theDenormPreserve
execution mode can be used for 32-bit floating-point types. -
shaderDenormPreserveFloat64
is a boolean value indicating whether denormals can be preserved in 64-bit floating-point computations. It also indicates whether theDenormPreserve
execution mode can be used for 64-bit floating-point types. -
shaderDenormFlushToZeroFloat16
is a boolean value indicating whether denormals can be flushed to zero in 16-bit floating-point computations. It also indicates whether theDenormFlushToZero
execution mode can be used for 16-bit floating-point types. -
shaderDenormFlushToZeroFloat32
is a boolean value indicating whether denormals can be flushed to zero in 32-bit floating-point computations. It also indicates whether theDenormFlushToZero
execution mode can be used for 32-bit floating-point types. -
shaderDenormFlushToZeroFloat64
is a boolean value indicating whether denormals can be flushed to zero in 64-bit floating-point computations. It also indicates whether theDenormFlushToZero
execution mode can be used for 64-bit floating-point types. -
shaderRoundingModeRTEFloat16
is a boolean value indicating whether an implementation supports the round-to-nearest-even rounding mode for 16-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTE
execution mode can be used for 16-bit floating-point types. -
shaderRoundingModeRTEFloat32
is a boolean value indicating whether an implementation supports the round-to-nearest-even rounding mode for 32-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTE
execution mode can be used for 32-bit floating-point types. -
shaderRoundingModeRTEFloat64
is a boolean value indicating whether an implementation supports the round-to-nearest-even rounding mode for 64-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTE
execution mode can be used for 64-bit floating-point types. -
shaderRoundingModeRTZFloat16
is a boolean value indicating whether an implementation supports the round-towards-zero rounding mode for 16-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTZ
execution mode can be used for 16-bit floating-point types. -
shaderRoundingModeRTZFloat32
is a boolean value indicating whether an implementation supports the round-towards-zero rounding mode for 32-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTZ
execution mode can be used for 32-bit floating-point types. -
shaderRoundingModeRTZFloat64
is a boolean value indicating whether an implementation supports the round-towards-zero rounding mode for 64-bit floating-point arithmetic and conversion instructions. It also indicates whether theRoundingModeRTZ
execution mode can be used for 64-bit floating-point types. -
maxUpdateAfterBindDescriptorsInAllPools
is the maximum number of descriptors (summed over all descriptor types) that can be created across all pools that are created with theVK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT
bit set. Pool creation may fail when this limit is exceeded, or when the space this limit represents is unable to satisfy a pool creation due to fragmentation. -
shaderUniformBufferArrayNonUniformIndexingNative
is a boolean value indicating whether uniform buffer descriptors natively support nonuniform indexing. If this isVK_FALSE
, then a single dynamic instance of an instruction that nonuniformly indexes an array of uniform buffers may execute multiple times in order to access all the descriptors. -
shaderSampledImageArrayNonUniformIndexingNative
is a boolean value indicating whether sampler and image descriptors natively support nonuniform indexing. If this isVK_FALSE
, then a single dynamic instance of an instruction that nonuniformly indexes an array of samplers or images may execute multiple times in order to access all the descriptors. -
shaderStorageBufferArrayNonUniformIndexingNative
is a boolean value indicating whether storage buffer descriptors natively support nonuniform indexing. If this isVK_FALSE
, then a single dynamic instance of an instruction that nonuniformly indexes an array of storage buffers may execute multiple times in order to access all the descriptors. -
shaderStorageImageArrayNonUniformIndexingNative
is a boolean value indicating whether storage image descriptors natively support nonuniform indexing. If this isVK_FALSE
, then a single dynamic instance of an instruction that nonuniformly indexes an array of storage images may execute multiple times in order to access all the descriptors. -
shaderInputAttachmentArrayNonUniformIndexingNative
is a boolean value indicating whether input attachment descriptors natively support nonuniform indexing. If this isVK_FALSE
, then a single dynamic instance of an instruction that nonuniformly indexes an array of input attachments may execute multiple times in order to access all the descriptors. -
robustBufferAccessUpdateAfterBind
is a boolean value indicating whetherrobustBufferAccess
can be enabled in a device simultaneously withdescriptorBindingUniformBufferUpdateAfterBind
,descriptorBindingStorageBufferUpdateAfterBind
,descriptorBindingUniformTexelBufferUpdateAfterBind
, and/ordescriptorBindingStorageTexelBufferUpdateAfterBind
. If this isVK_FALSE
, then eitherrobustBufferAccess
must be disabled or all of these update-after-bind features must be disabled. -
quadDivergentImplicitLod
is a boolean value indicating whether implicit level of detail calculations for image operations have well-defined results when the image and/or sampler objects used for the instruction are not uniform within a quad. See Derivative Image Operations. -
maxPerStageDescriptorUpdateAfterBindSamplers
is similar tomaxPerStageDescriptorSamplers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageDescriptorUpdateAfterBindUniformBuffers
is similar tomaxPerStageDescriptorUniformBuffers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageDescriptorUpdateAfterBindStorageBuffers
is similar tomaxPerStageDescriptorStorageBuffers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageDescriptorUpdateAfterBindSampledImages
is similar tomaxPerStageDescriptorSampledImages
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageDescriptorUpdateAfterBindStorageImages
is similar tomaxPerStageDescriptorStorageImages
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageDescriptorUpdateAfterBindInputAttachments
is similar tomaxPerStageDescriptorInputAttachments
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxPerStageUpdateAfterBindResources
is similar tomaxPerStageResources
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindSamplers
is similar tomaxDescriptorSetSamplers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindUniformBuffers
is similar tomaxDescriptorSetUniformBuffers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindUniformBuffersDynamic
is similar tomaxDescriptorSetUniformBuffersDynamic
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindStorageBuffers
is similar tomaxDescriptorSetStorageBuffers
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindStorageBuffersDynamic
is similar tomaxDescriptorSetStorageBuffersDynamic
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindSampledImages
is similar tomaxDescriptorSetSampledImages
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindStorageImages
is similar tomaxDescriptorSetStorageImages
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
maxDescriptorSetUpdateAfterBindInputAttachments
is similar tomaxDescriptorSetInputAttachments
but counts descriptors from descriptor sets created with or without theVK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
bit set. -
supportedDepthResolveModes
is a bitmask of VkResolveModeFlagBits indicating the set of supported depth resolve modes.VK_RESOLVE_MODE_SAMPLE_ZERO_BIT
must be included in the set but implementations may support additional modes. -
supportedStencilResolveModes
is a bitmask of VkResolveModeFlagBits indicating the set of supported stencil resolve modes.VK_RESOLVE_MODE_SAMPLE_ZERO_BIT
must be included in the set but implementations may support additional modes.VK_RESOLVE_MODE_AVERAGE_BIT
must not be included in the set. -
independentResolveNone
isVK_TRUE
if the implementation supports setting the depth and stencil resolve modes to different values when one of those modes isVK_RESOLVE_MODE_NONE
. Otherwise the implementation only supports setting both modes to the same value. -
independentResolve
isVK_TRUE
if the implementation supports all combinations of the supported depth and stencil resolve modes, including setting either depth or stencil resolve mode toVK_RESOLVE_MODE_NONE
. An implementation that supportsindependentResolve
must also supportindependentResolveNone
. -
filterMinmaxSingleComponentFormats
is a boolean value indicating whether a minimum set of required formats support min/max filtering. -
filterMinmaxImageComponentMapping
is a boolean value indicating whether the implementation supports non-identity component mapping of the image when doing min/max filtering. -
maxTimelineSemaphoreValueDifference
indicates the maximum difference allowed by the implementation between the current value of a timeline semaphore and any pending signal or wait operations. -
framebufferIntegerColorSampleCounts
is a bitmask of VkSampleCountFlagBits indicating the color sample counts that are supported for all framebuffer color attachments with integer formats.
The members of VkPhysicalDeviceVulkan12Properties
must have the same
values as the corresponding members of
VkPhysicalDeviceDriverProperties,
VkPhysicalDeviceFloatControlsProperties,
VkPhysicalDeviceDescriptorIndexingProperties,
VkPhysicalDeviceDepthStencilResolveProperties,
VkPhysicalDeviceSamplerFilterMinmaxProperties, and
VkPhysicalDeviceTimelineSemaphoreProperties.
To query the UUID and LUID of a device, add a
VkPhysicalDeviceIDProperties structure to the pNext
chain of the
VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceIDProperties
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkPhysicalDeviceIDProperties {
VkStructureType sType;
void* pNext;
uint8_t deviceUUID[VK_UUID_SIZE];
uint8_t driverUUID[VK_UUID_SIZE];
uint8_t deviceLUID[VK_LUID_SIZE];
uint32_t deviceNodeMask;
VkBool32 deviceLUIDValid;
} VkPhysicalDeviceIDProperties;
or the equivalent
// Provided by VK_KHR_external_memory_capabilities, VK_KHR_external_semaphore_capabilities, VK_KHR_external_fence_capabilities
typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure.
-
deviceUUID
is an array ofVK_UUID_SIZE
uint8_t
values representing a universally unique identifier for the device. -
driverUUID
is an array ofVK_UUID_SIZE
uint8_t
values representing a universally unique identifier for the driver build in use by the device. -
deviceLUID
is an array ofVK_LUID_SIZE
uint8_t
values representing a locally unique identifier for the device. -
deviceNodeMask
is auint32_t
bitfield identifying the node within a linked device adapter corresponding to the device. -
deviceLUIDValid
is a boolean value that will beVK_TRUE
ifdeviceLUID
contains a valid LUID anddeviceNodeMask
contains a valid node mask, andVK_FALSE
if they do not.
deviceUUID
must be immutable for a given device across instances,
processes, driver APIs, driver versions, and system reboots.
Applications can compare the driverUUID
value across instance and
process boundaries, and can make similar queries in external APIs to
determine whether they are capable of sharing memory objects and resources
using them with the device.
deviceUUID
and/or driverUUID
must be used to determine whether
a particular external object can be shared between driver components, where
such a restriction exists as defined in the compatibility table for the
particular object type:
If deviceLUIDValid
is VK_FALSE
, the values of deviceLUID
and deviceNodeMask
are undefined.
If deviceLUIDValid
is VK_TRUE
and Vulkan is running on the
Windows operating system, the contents of deviceLUID
can be cast to
an LUID
object and must be equal to the locally unique identifier of a
IDXGIAdapter1
object that corresponds to physicalDevice
.
If deviceLUIDValid
is VK_TRUE
, deviceNodeMask
must
contain exactly one bit.
If Vulkan is running on an operating system that supports the Direct3D 12
API and physicalDevice
corresponds to an individual device in a linked
device adapter, deviceNodeMask
identifies the Direct3D 12 node
corresponding to physicalDevice
.
Otherwise, deviceNodeMask
must be 1
.
Note
Although they have identical descriptions,
VkPhysicalDeviceIDProperties:: Implementations should return Khronos' conformance testing can not guarantee that A combination of values unique to the vendor, the driver, and the hardware
environment can be used to provide a
|
Note
While VkPhysicalDeviceIDProperties:: |
To query the properties of the driver corresponding to a physical device,
add a VkPhysicalDeviceDriverProperties structure to the pNext
chain of the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceDriverProperties
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkPhysicalDeviceDriverProperties {
VkStructureType sType;
void* pNext;
VkDriverId driverID;
char driverName[VK_MAX_DRIVER_NAME_SIZE];
char driverInfo[VK_MAX_DRIVER_INFO_SIZE];
VkConformanceVersion conformanceVersion;
} VkPhysicalDeviceDriverProperties;
or the equivalent
// Provided by VK_KHR_driver_properties
typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure.
-
driverID
is a unique identifier for the driver of the physical device. -
driverName
is an array ofVK_MAX_DRIVER_NAME_SIZE
char
containing a null-terminated UTF-8 string which is the name of the driver. -
driverInfo
is an array ofVK_MAX_DRIVER_INFO_SIZE
char
containing a null-terminated UTF-8 string with additional information about the driver. -
conformanceVersion
is the version of the Vulkan conformance test this driver is conformant against (see VkConformanceVersion).
driverID
must be immutable for a given driver across instances,
processes, driver versions, and system reboots.
Khronos driver IDs which may be returned in
VkPhysicalDeviceDriverProperties::driverID
are:
// Provided by VK_VERSION_1_2
typedef enum VkDriverId {
VK_DRIVER_ID_AMD_PROPRIETARY = 1,
VK_DRIVER_ID_AMD_OPEN_SOURCE = 2,
VK_DRIVER_ID_MESA_RADV = 3,
VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4,
VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5,
VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6,
VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7,
VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8,
VK_DRIVER_ID_ARM_PROPRIETARY = 9,
VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10,
VK_DRIVER_ID_GGP_PROPRIETARY = 11,
VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12,
VK_DRIVER_ID_MESA_LLVMPIPE = 13,
VK_DRIVER_ID_MOLTENVK = 14,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY,
// Provided by VK_KHR_driver_properties
VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
} VkDriverId;
or the equivalent
// Provided by VK_KHR_driver_properties
typedef VkDriverId VkDriverIdKHR;
Note
Khronos driver IDs may be allocated by vendors at any time.
There may be multiple driver IDs for the same vendor, representing different
drivers (for e.g. different platforms, proprietary or open source, etc.).
Only the latest canonical versions of this Specification, of the
corresponding Only driver IDs registered with Khronos are given symbolic names. There may be unregistered driver IDs returned. |
The conformance test suite version an implementation is compliant with is
described with the VkConformanceVersion
structure:
// Provided by VK_VERSION_1_2
typedef struct VkConformanceVersion {
uint8_t major;
uint8_t minor;
uint8_t subminor;
uint8_t patch;
} VkConformanceVersion;
or the equivalent
// Provided by VK_KHR_driver_properties
typedef VkConformanceVersion VkConformanceVersionKHR;
-
major
is the major version number of the conformance test suite. -
minor
is the minor version number of the conformance test suite. -
subminor
is the subminor version number of the conformance test suite. -
patch
is the patch version number of the conformance test suite.
To query the PCI bus information of a physical device, add a
VkPhysicalDevicePCIBusInfoPropertiesEXT structure to the pNext
chain of the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDevicePCIBusInfoPropertiesEXT
structure is defined as:
// Provided by VK_EXT_pci_bus_info
typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT {
VkStructureType sType;
void* pNext;
uint32_t pciDomain;
uint32_t pciBus;
uint32_t pciDevice;
uint32_t pciFunction;
} VkPhysicalDevicePCIBusInfoPropertiesEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pciDomain
is the PCI bus domain. -
pciBus
is the PCI bus identifier. -
pciDevice
is the PCI device identifier. -
pciFunction
is the PCI device function identifier.
To query properties of queues available on a physical device, call:
// Provided by VK_VERSION_1_0
void vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties);
-
physicalDevice
is the handle to the physical device whose properties will be queried. -
pQueueFamilyPropertyCount
is a pointer to an integer related to the number of queue families available or queried, as described below. -
pQueueFamilyProperties
is eitherNULL
or a pointer to an array of VkQueueFamilyProperties structures.
If pQueueFamilyProperties
is NULL
, then the number of queue families
available is returned in pQueueFamilyPropertyCount
.
Implementations must support at least one queue family.
Otherwise, pQueueFamilyPropertyCount
must point to a variable set by
the user to the number of elements in the pQueueFamilyProperties
array, and on return the variable is overwritten with the number of
structures actually written to pQueueFamilyProperties
.
If pQueueFamilyPropertyCount
is less than the number of queue families
available, at most pQueueFamilyPropertyCount
structures will be
written.
The VkQueueFamilyProperties
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkQueueFamilyProperties {
VkQueueFlags queueFlags;
uint32_t queueCount;
uint32_t timestampValidBits;
VkExtent3D minImageTransferGranularity;
} VkQueueFamilyProperties;
-
queueFlags
is a bitmask of VkQueueFlagBits indicating capabilities of the queues in this queue family. -
queueCount
is the unsigned integer count of queues in this queue family. Each queue family must support at least one queue. -
timestampValidBits
is the unsigned integer count of meaningful bits in the timestamps written viavkCmdWriteTimestamp
. The valid range for the count is 36..64 bits, or a value of 0, indicating no support for timestamps. Bits outside the valid range are guaranteed to be zeros. -
minImageTransferGranularity
is the minimum granularity supported for image transfer operations on the queues in this queue family.
The value returned in minImageTransferGranularity
has a unit of
compressed texel blocks for images having a block-compressed format, and a
unit of texels otherwise.
Possible values of minImageTransferGranularity
are:
-
(0,0,0) which indicates that only whole mip levels must be transferred using the image transfer operations on the corresponding queues. In this case, the following restrictions apply to all offset and extent parameters of image transfer operations:
-
The
x
,y
, andz
members of a VkOffset3D parameter must always be zero. -
The
width
,height
, anddepth
members of a VkExtent3D parameter must always match the width, height, and depth of the image subresource corresponding to the parameter, respectively.
-
-
(Ax, Ay, Az) where Ax, Ay, and Az are all integer powers of two. In this case the following restrictions apply to all image transfer operations:
-
x
,y
, andz
of a VkOffset3D parameter must be integer multiples of Ax, Ay, and Az, respectively. -
width
of a VkExtent3D parameter must be an integer multiple of Ax, or elsex
+width
must equal the width of the image subresource corresponding to the parameter. -
height
of a VkExtent3D parameter must be an integer multiple of Ay, or elsey
+height
must equal the height of the image subresource corresponding to the parameter. -
depth
of a VkExtent3D parameter must be an integer multiple of Az, or elsez
+depth
must equal the depth of the image subresource corresponding to the parameter. -
If the format of the image corresponding to the parameters is one of the block-compressed formats then for the purposes of the above calculations the granularity must be scaled up by the compressed texel block dimensions.
-
Queues supporting graphics and/or compute operations must report
(1,1,1) in minImageTransferGranularity
, meaning that there are
no additional restrictions on the granularity of image transfer operations
for these queues.
Other queues supporting image transfer operations are only required to
support whole mip level transfers, thus minImageTransferGranularity
for queues belonging to such queue families may be (0,0,0).
The Device Memory section describes memory properties queried from the physical device.
For physical device feature queries see the Features chapter.
Bits which may be set in VkQueueFamilyProperties::queueFlags
indicating capabilities of queues in a queue family are:
// Provided by VK_VERSION_1_0
typedef enum VkQueueFlagBits {
VK_QUEUE_GRAPHICS_BIT = 0x00000001,
VK_QUEUE_COMPUTE_BIT = 0x00000002,
VK_QUEUE_TRANSFER_BIT = 0x00000004,
VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
// Provided by VK_VERSION_1_1
VK_QUEUE_PROTECTED_BIT = 0x00000010,
} VkQueueFlagBits;
-
VK_QUEUE_GRAPHICS_BIT
specifies that queues in this queue family support graphics operations. -
VK_QUEUE_COMPUTE_BIT
specifies that queues in this queue family support compute operations. -
VK_QUEUE_TRANSFER_BIT
specifies that queues in this queue family support transfer operations. -
VK_QUEUE_SPARSE_BINDING_BIT
specifies that queues in this queue family support sparse memory management operations (see Sparse Resources). If any of the sparse resource features are enabled, then at least one queue family must support this bit. -
if
VK_QUEUE_PROTECTED_BIT
is set, then the queues in this queue family support theVK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
bit. (see Protected Memory). If the protected memory physical device feature is supported, then at least one queue family of at least one physical device exposed by the implementation must support this bit.
If an implementation exposes any queue family that supports graphics operations, at least one queue family of at least one physical device exposed by the implementation must support both graphics and compute operations.
Furthermore, if the protected memory physical device feature is supported, then at least one queue family of at least one physical device exposed by the implementation must support graphics operations, compute operations, and protected memory operations.
Note
All commands that are allowed on a queue that supports transfer operations
are also allowed on a queue that supports either graphics or compute
operations.
Thus, if the capabilities of a queue family include
|
For further details see Queues.
// Provided by VK_VERSION_1_0
typedef VkFlags VkQueueFlags;
VkQueueFlags
is a bitmask type for setting a mask of zero or more
VkQueueFlagBits.
To query properties of queues available on a physical device, call:
// Provided by VK_VERSION_1_1
void vkGetPhysicalDeviceQueueFamilyProperties2(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2* pQueueFamilyProperties);
or the equivalent command
// Provided by VK_KHR_get_physical_device_properties2
void vkGetPhysicalDeviceQueueFamilyProperties2KHR(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2* pQueueFamilyProperties);
-
physicalDevice
is the handle to the physical device whose properties will be queried. -
pQueueFamilyPropertyCount
is a pointer to an integer related to the number of queue families available or queried, as described in vkGetPhysicalDeviceQueueFamilyProperties. -
pQueueFamilyProperties
is eitherNULL
or a pointer to an array of VkQueueFamilyProperties2 structures.
vkGetPhysicalDeviceQueueFamilyProperties2
behaves similarly to
vkGetPhysicalDeviceQueueFamilyProperties, with the ability to return
extended information in a pNext
chain of output structures.
The VkQueueFamilyProperties2
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkQueueFamilyProperties2 {
VkStructureType sType;
void* pNext;
VkQueueFamilyProperties queueFamilyProperties;
} VkQueueFamilyProperties2;
or the equivalent
// Provided by VK_KHR_get_physical_device_properties2
typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
queueFamilyProperties
is a VkQueueFamilyProperties structure which is populated with the same values as in vkGetPhysicalDeviceQueueFamilyProperties.
Additional queue family information can be queried by setting
VkQueueFamilyProperties2::pNext
to point to a
VkQueueFamilyCheckpointPropertiesNV structure.
The VkQueueFamilyCheckpointPropertiesNV structure is defined as:
// Provided by VK_NV_device_diagnostic_checkpoints
typedef struct VkQueueFamilyCheckpointPropertiesNV {
VkStructureType sType;
void* pNext;
VkPipelineStageFlags checkpointExecutionStageMask;
} VkQueueFamilyCheckpointPropertiesNV;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
checkpointExecutionStageMask
is a mask indicating which pipeline stages the implementation can execute checkpoint markers in.
To enumerate the performance query counters available on a queue family of a physical device, call:
// Provided by VK_KHR_performance_query
VkResult vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
uint32_t* pCounterCount,
VkPerformanceCounterKHR* pCounters,
VkPerformanceCounterDescriptionKHR* pCounterDescriptions);
-
physicalDevice
is the handle to the physical device whose queue family performance query counter properties will be queried. -
queueFamilyIndex
is the index into the queue family of the physical device we want to get properties for. -
pCounterCount
is a pointer to an integer related to the number of counters available or queried, as described below. -
pCounters
is eitherNULL
or a pointer to an array of VkPerformanceCounterKHR structures. -
pCounterDescriptions
is eitherNULL
or a pointer to an array of VkPerformanceCounterDescriptionKHR structures.
If pCounters
is NULL
and pCounterDescriptions
is NULL
, then
the number of counters available is returned in pCounterCount
.
Otherwise, pCounterCount
must point to a variable set by the user to
the number of elements in the pCounters
, pCounterDescriptions
,
or both arrays and on return the variable is overwritten with the number of
structures actually written out.
If pCounterCount
is less than the number of counters available, at
most pCounterCount
structures will be written and VK_INCOMPLETE
will be returned instead of VK_SUCCESS
.
The VkPerformanceCounterKHR
structure is defined as:
// Provided by VK_KHR_performance_query
typedef struct VkPerformanceCounterKHR {
VkStructureType sType;
const void* pNext;
VkPerformanceCounterUnitKHR unit;
VkPerformanceCounterScopeKHR scope;
VkPerformanceCounterStorageKHR storage;
uint8_t uuid[VK_UUID_SIZE];
} VkPerformanceCounterKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
unit
is a VkPerformanceCounterUnitKHR specifying the unit that the counter data will record. -
scope
is a VkPerformanceCounterScopeKHR specifying the scope that the counter belongs to. -
storage
is a VkPerformanceCounterStorageKHR specifying the storage type that the counter’s data uses. -
uuid
is an array of sizeVK_UUID_SIZE
, containing 8-bit values that represent a universally unique identifier for the counter of the physical device.
Performance counters have an associated unit. This unit describes how to interpret the performance counter result.
The performance counter unit types which may be returned in
VkPerformanceCounterKHR::unit
are:
// Provided by VK_KHR_performance_query
typedef enum VkPerformanceCounterUnitKHR {
VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0,
VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1,
VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2,
VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3,
VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4,
VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5,
VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6,
VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7,
VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8,
VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9,
VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10,
} VkPerformanceCounterUnitKHR;
-
VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR
- the performance counter unit is a generic data point. -
VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR
- the performance counter unit is a percentage (%). -
VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR
- the performance counter unit is a value of nanoseconds (ns). -
VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR
- the performance counter unit is a value of bytes. -
VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR
- the performance counter unit is a value of bytes/s. -
VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR
- the performance counter unit is a temperature reported in Kelvin. -
VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR
- the performance counter unit is a value of watts (W). -
VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR
- the performance counter unit is a value of volts (V). -
VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR
- the performance counter unit is a value of amps (A). -
VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR
- the performance counter unit is a value of hertz (Hz). -
VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR
- the performance counter unit is a value of cycles.
Performance counters have an associated scope. This scope describes the granularity of a performance counter.
The performance counter scope types which may be returned in
VkPerformanceCounterKHR::scope
are:
// Provided by VK_KHR_performance_query
typedef enum VkPerformanceCounterScopeKHR {
VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0,
VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1,
VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2,
VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR,
VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
} VkPerformanceCounterScopeKHR;
-
VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR
- the performance counter scope is a single complete command buffer. -
VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR
- the performance counter scope is zero or more complete render passes. The performance query containing the performance counter must begin and end outside a render pass instance. -
VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR
- the performance counter scope is zero or more commands.
Performance counters have an associated storage. This storage describes the payload of a counter result.
The performance counter storage types which may be returned in
VkPerformanceCounterKHR::storage
are:
// Provided by VK_KHR_performance_query
typedef enum VkPerformanceCounterStorageKHR {
VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0,
VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1,
VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2,
VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3,
VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4,
VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5,
} VkPerformanceCounterStorageKHR;
-
VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR
- the performance counter storage is a 32-bit signed integer. -
VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR
- the performance counter storage is a 64-bit signed integer. -
VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR
- the performance counter storage is a 32-bit unsigned integer. -
VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR
- the performance counter storage is a 64-bit unsigned integer. -
VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR
- the performance counter storage is a 32-bit floating-point. -
VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR
- the performance counter storage is a 64-bit floating-point.
The VkPerformanceCounterDescriptionKHR
structure is defined as:
// Provided by VK_KHR_performance_query
typedef struct VkPerformanceCounterDescriptionKHR {
VkStructureType sType;
const void* pNext;
VkPerformanceCounterDescriptionFlagsKHR flags;
char name[VK_MAX_DESCRIPTION_SIZE];
char category[VK_MAX_DESCRIPTION_SIZE];
char description[VK_MAX_DESCRIPTION_SIZE];
} VkPerformanceCounterDescriptionKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPerformanceCounterDescriptionFlagBitsKHR indicating the usage behavior for the counter. -
name
is an array of sizeVK_MAX_DESCRIPTION_SIZE
, containing a null-terminated UTF-8 string specifying the name of the counter. -
category
is an array of sizeVK_MAX_DESCRIPTION_SIZE
, containing a null-terminated UTF-8 string specifying the category of the counter. -
description
is an array of sizeVK_MAX_DESCRIPTION_SIZE
, containing a null-terminated UTF-8 string specifying the description of the counter.
Bits which can be set in
VkPerformanceCounterDescriptionKHR::flags
to specify usage
behavior for a command pool are:
// Provided by VK_KHR_performance_query
typedef enum VkPerformanceCounterDescriptionFlagBitsKHR {
VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = 0x00000001,
VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = 0x00000002,
} VkPerformanceCounterDescriptionFlagBitsKHR;
-
VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR
specifies that recording the counter may have a noticeable performance impact. -
VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR
specifies that concurrently recording the counter while other submitted command buffers are running may impact the accuracy of the recording.
// Provided by VK_KHR_performance_query
typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR;
VkPerformanceCounterDescriptionFlagsKHR is a bitmask type for setting a mask of zero or more VkPerformanceCounterDescriptionFlagBitsKHR.
4.2. Devices
Device objects represent logical connections to physical devices. Each device exposes a number of queue families each having one or more queues. All queues in a queue family support the same operations.
As described in Physical Devices, a Vulkan application will first query for all physical devices in a system. Each physical device can then be queried for its capabilities, including its queue and queue family properties. Once an acceptable physical device is identified, an application will create a corresponding logical device. An application must create a separate logical device for each physical device it will use. The created logical device is then the primary interface to the physical device.
How to enumerate the physical devices in a system and query those physical devices for their queue family properties is described in the Physical Device Enumeration section above.
A single logical device can also be created from multiple physical devices, if those physical devices belong to the same device group. A device group is a set of physical devices that support accessing each other’s memory and recording a single command buffer that can be executed on all the physical devices. Device groups are enumerated by calling vkEnumeratePhysicalDeviceGroups, and a logical device is created from a subset of the physical devices in a device group by passing the physical devices through VkDeviceGroupDeviceCreateInfo. For two physical devices to be in the same device group, they must support identical extensions, features, and properties.
Note
Physical devices in the same device group must be so similar because there
are no rules for how different features/properties would interact.
They must return the same values for nearly every invariant
|
To retrieve a list of the device groups present in the system, call:
// Provided by VK_VERSION_1_1
VkResult vkEnumeratePhysicalDeviceGroups(
VkInstance instance,
uint32_t* pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
or the equivalent command
// Provided by VK_KHR_device_group_creation
VkResult vkEnumeratePhysicalDeviceGroupsKHR(
VkInstance instance,
uint32_t* pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
-
instance
is a handle to a Vulkan instance previously created with vkCreateInstance. -
pPhysicalDeviceGroupCount
is a pointer to an integer related to the number of device groups available or queried, as described below. -
pPhysicalDeviceGroupProperties
is eitherNULL
or a pointer to an array of VkPhysicalDeviceGroupProperties structures.
If pPhysicalDeviceGroupProperties
is NULL
, then the number of device
groups available is returned in pPhysicalDeviceGroupCount
.
Otherwise, pPhysicalDeviceGroupCount
must point to a variable set by
the user to the number of elements in the
pPhysicalDeviceGroupProperties
array, and on return the variable is
overwritten with the number of structures actually written to
pPhysicalDeviceGroupProperties
.
If pPhysicalDeviceGroupCount
is less than the number of device groups
available, at most pPhysicalDeviceGroupCount
structures will be
written.
If pPhysicalDeviceGroupCount
is smaller than the number of device
groups available, VK_INCOMPLETE
will be returned instead of
VK_SUCCESS
, to indicate that not all the available device groups were
returned.
Every physical device must be in exactly one device group.
The VkPhysicalDeviceGroupProperties
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkPhysicalDeviceGroupProperties {
VkStructureType sType;
void* pNext;
uint32_t physicalDeviceCount;
VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE];
VkBool32 subsetAllocation;
} VkPhysicalDeviceGroupProperties;
or the equivalent
// Provided by VK_KHR_device_group_creation
typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
physicalDeviceCount
is the number of physical devices in the group. -
physicalDevices
is an array ofVK_MAX_DEVICE_GROUP_SIZE
VkPhysicalDevice handles representing all physical devices in the group. The firstphysicalDeviceCount
elements of the array will be valid. -
subsetAllocation
specifies whether logical devices created from the group support allocating device memory on a subset of devices, via thedeviceMask
member of the VkMemoryAllocateFlagsInfo. If this isVK_FALSE
, then all device memory allocations are made across all physical devices in the group. IfphysicalDeviceCount
is1
, thensubsetAllocation
must beVK_FALSE
.
4.2.1. Device Creation
Logical devices are represented by VkDevice
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkDevice)
A logical device is created as a connection to a physical device. To create a logical device, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
-
physicalDevice
must be one of the device handles returned from a call tovkEnumeratePhysicalDevices
(see Physical Device Enumeration). -
pCreateInfo
is a pointer to a VkDeviceCreateInfo structure containing information about how to create the device. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pDevice
is a pointer to a handle in which the created VkDevice is returned.
vkCreateDevice
verifies that extensions and features requested in the
ppEnabledExtensionNames
and pEnabledFeatures
members of
pCreateInfo
, respectively, are supported by the implementation.
If any requested extension is not supported, vkCreateDevice
must
return VK_ERROR_EXTENSION_NOT_PRESENT
.
If any requested feature is not supported, vkCreateDevice
must return
VK_ERROR_FEATURE_NOT_PRESENT
.
Support for extensions can be checked before creating a device by querying
vkEnumerateDeviceExtensionProperties.
Support for features can similarly be checked by querying
vkGetPhysicalDeviceFeatures.
After verifying and enabling the extensions the VkDevice
object is
created and returned to the application.
If a requested extension is only supported by a layer, both the layer and
the extension need to be specified at vkCreateInstance
time for the
creation to succeed.
Multiple logical devices can be created from the same physical device.
Logical device creation may fail due to lack of device-specific resources
(in addition to the other errors).
If that occurs, vkCreateDevice
will return
VK_ERROR_TOO_MANY_OBJECTS
.
The VkDeviceCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkDeviceCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceCreateFlags flags;
uint32_t queueCreateInfoCount;
const VkDeviceQueueCreateInfo* pQueueCreateInfos;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
const VkPhysicalDeviceFeatures* pEnabledFeatures;
} VkDeviceCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
queueCreateInfoCount
is the unsigned integer size of thepQueueCreateInfos
array. Refer to the Queue Creation section below for further details. -
pQueueCreateInfos
is a pointer to an array of VkDeviceQueueCreateInfo structures describing the queues that are requested to be created along with the logical device. Refer to the Queue Creation section below for further details. -
enabledLayerCount
is deprecated and ignored. -
ppEnabledLayerNames
is deprecated and ignored. See Device Layer Deprecation. -
enabledExtensionCount
is the number of device extensions to enable. -
ppEnabledExtensionNames
is a pointer to an array ofenabledExtensionCount
null-terminated UTF-8 strings containing the names of extensions to enable for the created device. See the Extensions section for further details. -
pEnabledFeatures
isNULL
or a pointer to a VkPhysicalDeviceFeatures structure containing boolean indicators of all the features to be enabled. Refer to the Features section for further details.
// Provided by VK_VERSION_1_0
typedef VkFlags VkDeviceCreateFlags;
VkDeviceCreateFlags
is a bitmask type for setting a mask, but is
currently reserved for future use.
A logical device can be created that connects to one or more physical
devices by adding a VkDeviceGroupDeviceCreateInfo
structure to the
pNext
chain of VkDeviceCreateInfo.
The VkDeviceGroupDeviceCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkDeviceGroupDeviceCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t physicalDeviceCount;
const VkPhysicalDevice* pPhysicalDevices;
} VkDeviceGroupDeviceCreateInfo;
or the equivalent
// Provided by VK_KHR_device_group_creation
typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
physicalDeviceCount
is the number of elements in thepPhysicalDevices
array. -
pPhysicalDevices
is a pointer to an array of physical device handles belonging to the same device group.
The elements of the pPhysicalDevices
array are an ordered list of the
physical devices that the logical device represents.
These must be a subset of a single device group, and need not be in the
same order as they were enumerated.
The order of the physical devices in the pPhysicalDevices
array
determines the device index of each physical device, with element i
being assigned a device index of i.
Certain commands and structures refer to one or more physical devices by
using device indices or device masks formed using device indices.
A logical device created without using VkDeviceGroupDeviceCreateInfo
,
or with physicalDeviceCount
equal to zero, is equivalent to a
physicalDeviceCount
of one and pPhysicalDevices
pointing to the
physicalDevice
parameter to vkCreateDevice.
In particular, the device index of that physical device is zero.
To specify whether device memory allocation is allowed beyond the size
reported by VkPhysicalDeviceMemoryProperties, add a
VkDeviceMemoryOverallocationCreateInfoAMD structure to the pNext
chain of the VkDeviceCreateInfo structure.
If this structure is not specified, it is as if the
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD
value is used.
// Provided by VK_AMD_memory_overallocation_behavior
typedef struct VkDeviceMemoryOverallocationCreateInfoAMD {
VkStructureType sType;
const void* pNext;
VkMemoryOverallocationBehaviorAMD overallocationBehavior;
} VkDeviceMemoryOverallocationCreateInfoAMD;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
overallocationBehavior
is the desired overallocation behavior.
Possible values for VkDeviceMemoryOverallocationCreateInfoAMD::overallocationBehavior include:
// Provided by VK_AMD_memory_overallocation_behavior
typedef enum VkMemoryOverallocationBehaviorAMD {
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0,
VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1,
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2,
} VkMemoryOverallocationBehaviorAMD;
-
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD
lets the implementation decide if overallocation is allowed. -
VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD
specifies overallocation is allowed if platform permits. -
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD
specifies the application is not allowed to allocate device memory beyond the heap sizes reported by VkPhysicalDeviceMemoryProperties. Allocations that are not explicitly made by the application within the scope of the Vulkan instance are not accounted for.
When using the Nsight™ Aftermath SDK, to configure how device crash
dumps are created, add a VkDeviceDiagnosticsConfigCreateInfoNV
structure to the pNext
chain of the VkDeviceCreateInfo
structure.
// Provided by VK_NV_device_diagnostics_config
typedef struct VkDeviceDiagnosticsConfigCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkDeviceDiagnosticsConfigFlagsNV flags;
} VkDeviceDiagnosticsConfigCreateInfoNV;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkDeviceDiagnosticsConfigFlagBitsNV specifying addtional parameters for configuring diagnostic tools.
Bits which can be set in VkDeviceDiagnosticsConfigCreateInfoNV::flags include:
// Provided by VK_NV_device_diagnostics_config
typedef enum VkDeviceDiagnosticsConfigFlagBitsNV {
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001,
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002,
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004,
} VkDeviceDiagnosticsConfigFlagBitsNV;
-
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV
enables the generation of debug information for shaders. -
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV
enables driver side tracking of resources (images, buffers, etc.) used to augment the device fault information. -
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV
enables automatic insertion of diagnostic checkpoints for draw calls, dispatches, trace rays, and copies. The CPU call stack at the time of the command will be associated as the marker data for the automatically inserted checkpoints.
// Provided by VK_NV_device_diagnostics_config
typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV;
VkDeviceDiagnosticsConfigFlagsNV
is a bitmask type for setting a mask
of zero or more VkDeviceDiagnosticsConfigFlagBitsNV.
To reserve private data storage slots, add a
VkDevicePrivateDataCreateInfoEXT structure to the pNext
chain of
the VkDeviceCreateInfo structure.
Reserving slots in this manner is not strictly necessary, but doing so may
improve performance.
// Provided by VK_EXT_private_data
typedef struct VkDevicePrivateDataCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t privateDataSlotRequestCount;
} VkDevicePrivateDataCreateInfoEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
privateDataSlotRequestCount
is the amount of slots to reserve.
4.2.2. Device Use
The following is a high-level list of VkDevice
uses along with
references on where to find more information:
-
Creation of queues. See the Queues section below for further details.
-
Creation and tracking of various synchronization constructs. See Synchronization and Cache Control for further details.
-
Allocating, freeing, and managing memory. See Memory Allocation and Resource Creation for further details.
-
Creation and destruction of command buffers and command buffer pools. See Command Buffers for further details.
-
Creation, destruction, and management of graphics state. See Pipelines and Resource Descriptors, among others, for further details.
4.2.3. Lost Device
A logical device may become lost for a number of implementation-specific reasons, indicating that pending and future command execution may fail and cause resources and backing memory to become undefined.
Note
Typical reasons for device loss will include things like execution timing out (to prevent denial of service), power management events, platform resource management, implementation errors. Applications not adhering to valid usage may also result in device loss being reported, however this is not guaranteed. Even if device loss is reported, the system may be in an unrecoverable state, and further usage of the API is still considered invalid. |
When this happens, certain commands will return VK_ERROR_DEVICE_LOST
.
After any such event, the logical device is considered lost.
It is not possible to reset the logical device to a non-lost state, however
the lost state is specific to a logical device (VkDevice
), and the
corresponding physical device (VkPhysicalDevice
) may be otherwise
unaffected.
In some cases, the physical device may also be lost, and attempting to
create a new logical device will fail, returning VK_ERROR_DEVICE_LOST
.
This is usually indicative of a problem with the underlying implementation,
or its connection to the host.
If the physical device has not been lost, and a new logical device is
successfully created from that physical device, it must be in the non-lost
state.
Note
Whilst logical device loss may be recoverable, in the case of physical device loss, it is unlikely that an application will be able to recover unless additional, unaffected physical devices exist on the system. The error is largely informational and intended only to inform the user that a platform issue has occurred, and should be investigated further. For example, underlying hardware may have developed a fault or become physically disconnected from the rest of the system. In many cases, physical device loss may cause other more serious issues such as the operating system crashing; in which case it may not be reported via the Vulkan API. |
When a device is lost, its child objects are not implicitly destroyed and their handles are still valid. Those objects must still be destroyed before their parents or the device can be destroyed (see the Object Lifetime section). The host address space corresponding to device memory mapped using vkMapMemory is still valid, and host memory accesses to these mapped regions are still valid, but the contents are undefined. It is still legal to call any API command on the device and child objects.
Once a device is lost, command execution may fail, and commands that return
a VkResult may return VK_ERROR_DEVICE_LOST
.
Commands that do not allow runtime errors must still operate correctly for
valid usage and, if applicable, return valid data.
Commands that wait indefinitely for device execution (namely
vkDeviceWaitIdle, vkQueueWaitIdle, vkWaitForFences
or vkAcquireNextImageKHR
with a maximum timeout
, and vkGetQueryPoolResults with the
VK_QUERY_RESULT_WAIT_BIT
bit set in flags
) must return in
finite time even in the case of a lost device, and return either
VK_SUCCESS
or VK_ERROR_DEVICE_LOST
.
For any command that may return VK_ERROR_DEVICE_LOST
, for the purpose
of determining whether a command buffer is in the
pending state, or whether resources are
considered in-use by the device, a return value of
VK_ERROR_DEVICE_LOST
is equivalent to VK_SUCCESS
.
The content of any external memory objects that have been exported from or
imported to a lost device become undefined.
Objects on other logical devices or in other APIs which are associated with
the same underlying memory resource as the external memory objects on the
lost device are unaffected other than their content becoming undefined.
The layout of subresources of images on other logical devices that are bound
to VkDeviceMemory
objects associated with the same underlying memory
resources as external memory objects on the lost device becomes
VK_IMAGE_LAYOUT_UNDEFINED
.
The state of VkSemaphore
objects on other logical devices created by
importing a semaphore payload with
temporary permanence which was exported from the lost device is undefined.
The state of VkSemaphore
objects on other logical devices that
permanently share a semaphore payload with a VkSemaphore
object on the
lost device is undefined, and remains undefined following any subsequent
signal operations.
Implementations must ensure pending and subsequently submitted wait
operations on such semaphores behave as defined in
Semaphore State Requirements For
Wait Operations for external semaphores not in a valid state for a wait
operation.
editing-note
TODO (piman) - I do not think we are very clear about what “in-use by the device” means. |
4.2.4. Device Destruction
To destroy a device, call:
// Provided by VK_VERSION_1_0
void vkDestroyDevice(
VkDevice device,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
To ensure that no work is active on the device, vkDeviceWaitIdle can
be used to gate the destruction of the device.
Prior to destroying a device, an application is responsible for
destroying/freeing any Vulkan objects that were created using that device as
the first parameter of the corresponding vkCreate*
or
vkAllocate*
command.
Note
The lifetime of each of these objects is bound by the lifetime of the
|
4.3. Queues
4.3.1. Queue Family Properties
As discussed in the Physical Device Enumeration section above, the vkGetPhysicalDeviceQueueFamilyProperties command is used to retrieve details about the queue families and queues supported by a device.
Each index in the pQueueFamilyProperties
array returned by
vkGetPhysicalDeviceQueueFamilyProperties describes a unique queue
family on that physical device.
These indices are used when creating queues, and they correspond directly
with the queueFamilyIndex
that is passed to the vkCreateDevice
command via the VkDeviceQueueCreateInfo structure as described in the
Queue Creation section below.
Grouping of queue families within a physical device is implementation-dependent.
Note
The general expectation is that a physical device groups all queues of matching capabilities into a single family. However, while implementations should do this, it is possible that a physical device may return two separate queue families with the same capabilities. |
Once an application has identified a physical device with the queue(s) that it desires to use, it will create those queues in conjunction with a logical device. This is described in the following section.
4.3.2. Queue Creation
Creating a logical device also creates the queues associated with that
device.
The queues to create are described by a set of VkDeviceQueueCreateInfo
structures that are passed to vkCreateDevice in
pQueueCreateInfos
.
Queues are represented by VkQueue
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkQueue)
The VkDeviceQueueCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkDeviceQueueCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueCount;
const float* pQueuePriorities;
} VkDeviceQueueCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask indicating behavior of the queue. -
queueFamilyIndex
is an unsigned integer indicating the index of the queue family to create on this device. This index corresponds to the index of an element of thepQueueFamilyProperties
array that was returned byvkGetPhysicalDeviceQueueFamilyProperties
. -
queueCount
is an unsigned integer specifying the number of queues to create in the queue family indicated byqueueFamilyIndex
. -
pQueuePriorities
is a pointer to an array ofqueueCount
normalized floating point values, specifying priorities of work that will be submitted to each created queue. See Queue Priority for more information.
Bits which can be set in VkDeviceQueueCreateInfo::flags
to
specify usage behavior of the queue are:
// Provided by VK_VERSION_1_0
typedef enum VkDeviceQueueCreateFlagBits {
// Provided by VK_VERSION_1_1
VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001,
} VkDeviceQueueCreateFlagBits;
-
VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
specifies that the device queue is a protected-capable queue.
// Provided by VK_VERSION_1_0
typedef VkFlags VkDeviceQueueCreateFlags;
VkDeviceQueueCreateFlags
is a bitmask type for setting a mask of zero
or more VkDeviceQueueCreateFlagBits.
A queue can be created with a system-wide priority by adding a
VkDeviceQueueGlobalPriorityCreateInfoEXT
structure to the pNext
chain of VkDeviceQueueCreateInfo.
The VkDeviceQueueGlobalPriorityCreateInfoEXT
structure is defined as:
// Provided by VK_EXT_global_priority
typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkQueueGlobalPriorityEXT globalPriority;
} VkDeviceQueueGlobalPriorityCreateInfoEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
globalPriority
is the system-wide priority associated to this queue as specified by VkQueueGlobalPriorityEXT
A queue created without specifying
VkDeviceQueueGlobalPriorityCreateInfoEXT
will default to
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT
.
Possible values of
VkDeviceQueueGlobalPriorityCreateInfoEXT::globalPriority
,
specifying a system-wide priority level are:
// Provided by VK_EXT_global_priority
typedef enum VkQueueGlobalPriorityEXT {
VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128,
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256,
VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512,
VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024,
} VkQueueGlobalPriorityEXT;
Priority values are sorted in ascending order. A comparison operation on the enum values can be used to determine the priority order.
-
VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT
is below the system default. Useful for non-interactive tasks. -
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT
is the system default priority. -
VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT
is above the system default. -
VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT
is the highest priority. Useful for critical tasks.
Queues with higher system priority may be allotted more processing time than queues with lower priority. An implementation may allow a higher-priority queue to starve a lower-priority queue until the higher-priority queue has no further commands to execute.
Priorities imply no ordering or scheduling constraints.
No specific guarantees are made about higher priority queues receiving more processing time or better quality of service than lower priority queues.
The global priority level of a queue takes precedence over the per-process
queue priority (VkDeviceQueueCreateInfo::pQueuePriorities
).
Abuse of this feature may result in starving the rest of the system of
implementation resources.
Therefore, the driver implementation may deny requests to acquire a
priority above the default priority
(VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT
) if the caller does not have
sufficient privileges.
In this scenario VK_ERROR_NOT_PERMITTED_EXT
is returned.
The driver implementation may fail the queue allocation request if
resources required to complete the operation have been exhausted (either by
the same process or a different process).
In this scenario VK_ERROR_INITIALIZATION_FAILED
is returned.
To retrieve a handle to a VkQueue object, call:
// Provided by VK_VERSION_1_0
void vkGetDeviceQueue(
VkDevice device,
uint32_t queueFamilyIndex,
uint32_t queueIndex,
VkQueue* pQueue);
-
device
is the logical device that owns the queue. -
queueFamilyIndex
is the index of the queue family to which the queue belongs. -
queueIndex
is the index within this queue family of the queue to retrieve. -
pQueue
is a pointer to a VkQueue object that will be filled with the handle for the requested queue.
vkGetDeviceQueue
must only be used to get queues that were created
with the flags
parameter of VkDeviceQueueCreateInfo set to zero.
To get queues that were created with a non-zero flags
parameter use
vkGetDeviceQueue2.
To retrieve a handle to a VkQueue object with specific VkDeviceQueueCreateFlags creation flags, call:
// Provided by VK_VERSION_1_1
void vkGetDeviceQueue2(
VkDevice device,
const VkDeviceQueueInfo2* pQueueInfo,
VkQueue* pQueue);
-
device
is the logical device that owns the queue. -
pQueueInfo
is a pointer to a VkDeviceQueueInfo2 structure, describing the parameters used to create the device queue. -
pQueue
is a pointer to a VkQueue object that will be filled with the handle for the requested queue.
The VkDeviceQueueInfo2
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkDeviceQueueInfo2 {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueIndex;
} VkDeviceQueueInfo2;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. ThepNext
chain ofVkDeviceQueueInfo2
is used to provide additional image parameters tovkGetDeviceQueue2
. -
flags
is a VkDeviceQueueCreateFlags value indicating the flags used to create the device queue. -
queueFamilyIndex
is the index of the queue family to which the queue belongs. -
queueIndex
is the index within this queue family of the queue to retrieve.
The queue returned by vkGetDeviceQueue2
must have the same
flags
value from this structure as that used at device creation time
in a VkDeviceQueueCreateInfo instance.
If no matching flags
were specified at device creation time then
pQueue
will return VK_NULL_HANDLE.
4.3.3. Queue Family Index
The queue family index is used in multiple places in Vulkan in order to tie operations to a specific family of queues.
When retrieving a handle to the queue via vkGetDeviceQueue
, the queue
family index is used to select which queue family to retrieve the
VkQueue
handle from as described in the previous section.
When creating a VkCommandPool
object (see
Command Pools), a queue family index is specified
in the VkCommandPoolCreateInfo structure.
Command buffers from this pool can only be submitted on queues
corresponding to this queue family.
When creating VkImage
(see Images) and
VkBuffer
(see Buffers) resources, a set of queue
families is included in the VkImageCreateInfo and
VkBufferCreateInfo structures to specify the queue families that can
access the resource.
When inserting a VkBufferMemoryBarrier or VkImageMemoryBarrier (see Pipeline Barriers), a source and destination queue family index is specified to allow the ownership of a buffer or image to be transferred from one queue family to another. See the Resource Sharing section for details.
4.3.4. Queue Priority
Each queue is assigned a priority, as set in the VkDeviceQueueCreateInfo structures when creating the device. The priority of each queue is a normalized floating point value between 0.0 and 1.0, which is then translated to a discrete priority level by the implementation. Higher values indicate a higher priority, with 0.0 being the lowest priority and 1.0 being the highest.
Within the same device, queues with higher priority may be allotted more processing time than queues with lower priority. The implementation makes no guarantees with regards to ordering or scheduling among queues with the same priority, other than the constraints defined by any explicit synchronization primitives. The implementation make no guarantees with regards to queues across different devices.
An implementation may allow a higher-priority queue to starve a
lower-priority queue on the same VkDevice
until the higher-priority
queue has no further commands to execute.
The relationship of queue priorities must not cause queues on one
VkDevice
to starve queues on another VkDevice
.
No specific guarantees are made about higher priority queues receiving more processing time or better quality of service than lower priority queues.
4.3.5. Queue Submission
Work is submitted to a queue via queue submission commands such as vkQueueSubmit. Queue submission commands define a set of queue operations to be executed by the underlying physical device, including synchronization with semaphores and fences.
Submission commands take as parameters a target queue, zero or more batches of work, and an optional fence to signal upon completion. Each batch consists of three distinct parts:
-
Zero or more semaphores to wait on before execution of the rest of the batch.
-
If present, these describe a semaphore wait operation.
-
-
Zero or more work items to execute.
-
If present, these describe a queue operation matching the work described.
-
-
Zero or more semaphores to signal upon completion of the work items.
-
If present, these describe a semaphore signal operation.
-
If a fence is present in a queue submission, it describes a fence signal operation.
All work described by a queue submission command must be submitted to the queue before the command returns.
Sparse Memory Binding
In Vulkan it is possible to sparsely bind memory to buffers and images as
described in the Sparse Resource chapter.
Sparse memory binding is a queue operation.
A queue whose flags include the VK_QUEUE_SPARSE_BINDING_BIT
must be
able to support the mapping of a virtual address to a physical address on
the device.
This causes an update to the page table mappings on the device.
This update must be synchronized on a queue to avoid corrupting page table
mappings during execution of graphics commands.
By binding the sparse memory resources on queues, all commands that are
dependent on the updated bindings are synchronized to only execute after the
binding is updated.
See the Synchronization and Cache Control chapter for
how this synchronization is accomplished.
5. Command Buffers
Command buffers are objects used to record commands which can be subsequently submitted to a device queue for execution. There are two levels of command buffers - primary command buffers, which can execute secondary command buffers, and which are submitted to queues, and secondary command buffers, which can be executed by primary command buffers, and which are not directly submitted to queues.
Command buffers are represented by VkCommandBuffer
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkCommandBuffer)
Recorded commands include commands to bind pipelines and descriptor sets to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering), commands to dispatch (for compute), commands to execute secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands.
Each command buffer manages state independently of other command buffers. There is no inheritance of state across primary and secondary command buffers, or between secondary command buffers. When a command buffer begins recording, all state in that command buffer is undefined. When secondary command buffer(s) are recorded to execute on a primary command buffer, the secondary command buffer inherits no state from the primary command buffer, and all state of the primary command buffer is undefined after an execute secondary command buffer command is recorded. There is one exception to this rule - if the primary command buffer is inside a render pass instance, then the render pass and subpass state is not disturbed by executing secondary command buffers. For state dependent commands (such as draws and dispatches), any state consumed by those commands must not be undefined.
Unless otherwise specified, and without explicit synchronization, the various commands submitted to a queue via command buffers may execute in arbitrary order relative to each other, and/or concurrently. Also, the memory side-effects of those commands may not be directly visible to other commands without explicit memory dependencies. This is true within a command buffer, and across command buffers submitted to a given queue. See the synchronization chapter for information on implicit and explicit synchronization between commands.
5.1. Command Buffer Lifecycle
Each command buffer is always in one of the following states:
- Initial
-
When a command buffer is allocated, it is in the initial state. Some commands are able to reset a command buffer (or a set of command buffers) back to this state from any of the executable, recording or invalid state. Command buffers in the initial state can only be moved to the recording state, or freed.
- Recording
-
vkBeginCommandBuffer changes the state of a command buffer from the initial state to the recording state. Once a command buffer is in the recording state,
vkCmd*
commands can be used to record to the command buffer. - Executable
-
vkEndCommandBuffer ends the recording of a command buffer, and moves it from the recording state to the executable state. Executable command buffers can be submitted, reset, or recorded to another command buffer.
- Pending
-
Queue submission of a command buffer changes the state of a command buffer from the executable state to the pending state. Whilst in the pending state, applications must not attempt to modify the command buffer in any way - as the device may be processing the commands recorded to it. Once execution of a command buffer completes, the command buffer either reverts back to the executable state, or if it was recorded with
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
, it moves to the invalid state. A synchronization command should be used to detect when this occurs. - Invalid
-
Some operations, such as modifying or deleting a resource that was used in a command recorded to a command buffer, will transition the state of that command buffer into the invalid state. Command buffers in the invalid state can only be reset or freed.
Any given command that operates on a command buffer has its own requirements on what state a command buffer must be in, which are detailed in the valid usage constraints for that command.
Resetting a command buffer is an operation that discards any previously recorded commands and puts a command buffer in the initial state. Resetting occurs as a result of vkResetCommandBuffer or vkResetCommandPool, or as part of vkBeginCommandBuffer (which additionally puts the command buffer in the recording state).
Secondary command buffers can be recorded to a primary command buffer via vkCmdExecuteCommands. This partially ties the lifecycle of the two command buffers together - if the primary is submitted to a queue, both the primary and any secondaries recorded to it move to the pending state. Once execution of the primary completes, so it does for any secondary recorded within it. After all executions of each command buffer complete, they each move to their appropriate completion state (either to the execution state or the invalid state, as specified above).
If a secondary moves to the invalid state or the initial state, then all primary buffers it is recorded in move to the invalid state. A primary moving to any other state does not affect the state of a secondary recorded in it.
Note
Resetting or freeing a primary command buffer removes the lifecycle linkage to all secondary command buffers that were recorded into it. |
5.2. Command Pools
Command pools are opaque objects that command buffer memory is allocated from, and which allow the implementation to amortize the cost of resource creation across multiple command buffers. Command pools are externally synchronized, meaning that a command pool must not be used concurrently in multiple threads. That includes use via recording commands on any command buffers allocated from the pool, as well as operations that allocate, free, and reset command buffers or the pool itself.
Command pools are represented by VkCommandPool
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
To create a command pool, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateCommandPool(
VkDevice device,
const VkCommandPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkCommandPool* pCommandPool);
-
device
is the logical device that creates the command pool. -
pCreateInfo
is a pointer to a VkCommandPoolCreateInfo structure specifying the state of the command pool object. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pCommandPool
is a pointer to a VkCommandPool handle in which the created pool is returned.
The VkCommandPoolCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkCommandPoolCreateInfo {
VkStructureType sType;
const void* pNext;
VkCommandPoolCreateFlags flags;
uint32_t queueFamilyIndex;
} VkCommandPoolCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkCommandPoolCreateFlagBits indicating usage behavior for the pool and command buffers allocated from it. -
queueFamilyIndex
designates a queue family as described in section Queue Family Properties. All command buffers allocated from this command pool must be submitted on queues from the same queue family.
Bits which can be set in VkCommandPoolCreateInfo::flags
to
specify usage behavior for a command pool are:
// Provided by VK_VERSION_1_0
typedef enum VkCommandPoolCreateFlagBits {
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
// Provided by VK_VERSION_1_1
VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004,
} VkCommandPoolCreateFlagBits;
-
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT
specifies that command buffers allocated from the pool will be short-lived, meaning that they will be reset or freed in a relatively short timeframe. This flag may be used by the implementation to control memory allocation behavior within the pool. -
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
allows any command buffer allocated from a pool to be individually reset to the initial state; either by calling vkResetCommandBuffer, or via the implicit reset when calling vkBeginCommandBuffer. If this flag is not set on a pool, thenvkResetCommandBuffer
must not be called for any command buffer allocated from that pool. -
VK_COMMAND_POOL_CREATE_PROTECTED_BIT
specifies that command buffers allocated from the pool are protected command buffers.
// Provided by VK_VERSION_1_0
typedef VkFlags VkCommandPoolCreateFlags;
VkCommandPoolCreateFlags
is a bitmask type for setting a mask of zero
or more VkCommandPoolCreateFlagBits.
To trim a command pool, call:
// Provided by VK_VERSION_1_1
void vkTrimCommandPool(
VkDevice device,
VkCommandPool commandPool,
VkCommandPoolTrimFlags flags);
or the equivalent command
// Provided by VK_KHR_maintenance1
void vkTrimCommandPoolKHR(
VkDevice device,
VkCommandPool commandPool,
VkCommandPoolTrimFlags flags);
-
device
is the logical device that owns the command pool. -
commandPool
is the command pool to trim. -
flags
is reserved for future use.
Trimming a command pool recycles unused memory from the command pool back to the system. Command buffers allocated from the pool are not affected by the command.
Note
This command provides applications with some control over the internal memory allocations used by command pools. Unused memory normally arises from command buffers that have been recorded and later reset, such that they are no longer using the memory. On reset, a command buffer can return memory to its command pool, but the only way to release memory from a command pool to the system requires calling vkResetCommandPool, which cannot be executed while any command buffers from that pool are still in use. Subsequent recording operations into command buffers will re-use this memory but since total memory requirements fluctuate over time, unused memory can accumulate. In this situation, trimming a command pool may be useful to return unused memory back to the system, returning the total outstanding memory allocated by the pool back to a more “average” value. Implementations utilize many internal allocation strategies that make it impossible to guarantee that all unused memory is released back to the system. For instance, an implementation of a command pool may involve allocating memory in bulk from the system and sub-allocating from that memory. In such an implementation any live command buffer that holds a reference to a bulk allocation would prevent that allocation from being freed, even if only a small proportion of the bulk allocation is in use. In most cases trimming will result in a reduction in allocated but unused memory, but it does not guarantee the “ideal” behavior. Trimming may be an expensive operation, and should not be called frequently. Trimming should be treated as a way to relieve memory pressure after application-known points when there exists enough unused memory that the cost of trimming is “worth” it. |
// Provided by VK_VERSION_1_1
typedef VkFlags VkCommandPoolTrimFlags;
or the equivalent
// Provided by VK_KHR_maintenance1
typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;
VkCommandPoolTrimFlags
is a bitmask type for setting a mask, but is
currently reserved for future use.
To reset a command pool, call:
// Provided by VK_VERSION_1_0
VkResult vkResetCommandPool(
VkDevice device,
VkCommandPool commandPool,
VkCommandPoolResetFlags flags);
-
device
is the logical device that owns the command pool. -
commandPool
is the command pool to reset. -
flags
is a bitmask of VkCommandPoolResetFlagBits controlling the reset operation.
Resetting a command pool recycles all of the resources from all of the command buffers allocated from the command pool back to the command pool. All command buffers that have been allocated from the command pool are put in the initial state.
Any primary command buffer allocated from another VkCommandPool that
is in the recording or executable state and
has a secondary command buffer allocated from commandPool
recorded
into it, becomes invalid.
Bits which can be set in vkResetCommandPool::flags
to control
the reset operation are:
// Provided by VK_VERSION_1_0
typedef enum VkCommandPoolResetFlagBits {
VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
} VkCommandPoolResetFlagBits;
-
VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT
specifies that resetting a command pool recycles all of the resources from the command pool back to the system.
// Provided by VK_VERSION_1_0
typedef VkFlags VkCommandPoolResetFlags;
VkCommandPoolResetFlags
is a bitmask type for setting a mask of zero
or more VkCommandPoolResetFlagBits.
To destroy a command pool, call:
// Provided by VK_VERSION_1_0
void vkDestroyCommandPool(
VkDevice device,
VkCommandPool commandPool,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that destroys the command pool. -
commandPool
is the handle of the command pool to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
When a pool is destroyed, all command buffers allocated from the pool are freed.
Any primary command buffer allocated from another VkCommandPool that
is in the recording or executable state and
has a secondary command buffer allocated from commandPool
recorded
into it, becomes invalid.
5.3. Command Buffer Allocation and Management
To allocate command buffers, call:
// Provided by VK_VERSION_1_0
VkResult vkAllocateCommandBuffers(
VkDevice device,
const VkCommandBufferAllocateInfo* pAllocateInfo,
VkCommandBuffer* pCommandBuffers);
-
device
is the logical device that owns the command pool. -
pAllocateInfo
is a pointer to aVkCommandBufferAllocateInfo
structure describing parameters of the allocation. -
pCommandBuffers
is a pointer to an array of VkCommandBuffer handles in which the resulting command buffer objects are returned. The array must be at least the length specified by thecommandBufferCount
member ofpAllocateInfo
. Each allocated command buffer begins in the initial state.
vkAllocateCommandBuffers
can be used to create multiple command
buffers.
If the creation of any of those command buffers fails, the implementation
must destroy all successfully created command buffer objects from this
command, set all entries of the pCommandBuffers
array to NULL
and
return the error.
When command buffers are first allocated, they are in the initial state.
The VkCommandBufferAllocateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkCommandBufferAllocateInfo {
VkStructureType sType;
const void* pNext;
VkCommandPool commandPool;
VkCommandBufferLevel level;
uint32_t commandBufferCount;
} VkCommandBufferAllocateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
commandPool
is the command pool from which the command buffers are allocated. -
level
is a VkCommandBufferLevel value specifying the command buffer level. -
commandBufferCount
is the number of command buffers to allocate from the pool.
Possible values of VkCommandBufferAllocateInfo::level
,
specifying the command buffer level, are:
// Provided by VK_VERSION_1_0
typedef enum VkCommandBufferLevel {
VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1,
} VkCommandBufferLevel;
-
VK_COMMAND_BUFFER_LEVEL_PRIMARY
specifies a primary command buffer. -
VK_COMMAND_BUFFER_LEVEL_SECONDARY
specifies a secondary command buffer.
To reset command buffers, call:
// Provided by VK_VERSION_1_0
VkResult vkResetCommandBuffer(
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
-
commandBuffer
is the command buffer to reset. The command buffer can be in any state other than pending, and is moved into the initial state. -
flags
is a bitmask of VkCommandBufferResetFlagBits controlling the reset operation.
Any primary command buffer that is in the recording or executable state and has commandBuffer
recorded into
it, becomes invalid.
Bits which can be set in vkResetCommandBuffer::flags
to control
the reset operation are:
// Provided by VK_VERSION_1_0
typedef enum VkCommandBufferResetFlagBits {
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
} VkCommandBufferResetFlagBits;
-
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT
specifies that most or all memory resources currently owned by the command buffer should be returned to the parent command pool. If this flag is not set, then the command buffer may hold onto memory resources and reuse them when recording commands.commandBuffer
is moved to the initial state.
// Provided by VK_VERSION_1_0
typedef VkFlags VkCommandBufferResetFlags;
VkCommandBufferResetFlags
is a bitmask type for setting a mask of zero
or more VkCommandBufferResetFlagBits.
To free command buffers, call:
// Provided by VK_VERSION_1_0
void vkFreeCommandBuffers(
VkDevice device,
VkCommandPool commandPool,
uint32_t commandBufferCount,
const VkCommandBuffer* pCommandBuffers);
-
device
is the logical device that owns the command pool. -
commandPool
is the command pool from which the command buffers were allocated. -
commandBufferCount
is the length of thepCommandBuffers
array. -
pCommandBuffers
is a pointer to an array of handles of command buffers to free.
Any primary command buffer that is in the recording or executable state and has any element of pCommandBuffers
recorded into it, becomes invalid.
5.4. Command Buffer Recording
To begin recording a command buffer, call:
// Provided by VK_VERSION_1_0
VkResult vkBeginCommandBuffer(
VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo* pBeginInfo);
-
commandBuffer
is the handle of the command buffer which is to be put in the recording state. -
pBeginInfo
points to a VkCommandBufferBeginInfo structure defining additional information about how the command buffer begins recording.
The VkCommandBufferBeginInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkCommandBufferBeginInfo {
VkStructureType sType;
const void* pNext;
VkCommandBufferUsageFlags flags;
const VkCommandBufferInheritanceInfo* pInheritanceInfo;
} VkCommandBufferBeginInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkCommandBufferUsageFlagBits specifying usage behavior for the command buffer. -
pInheritanceInfo
is a pointer to aVkCommandBufferInheritanceInfo
structure, used ifcommandBuffer
is a secondary command buffer. If this is a primary command buffer, then this value is ignored.
Bits which can be set in VkCommandBufferBeginInfo::flags
to
specify usage behavior for a command buffer are:
// Provided by VK_VERSION_1_0
typedef enum VkCommandBufferUsageFlagBits {
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001,
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002,
VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004,
} VkCommandBufferUsageFlagBits;
-
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
specifies that each recording of the command buffer will only be submitted once, and the command buffer will be reset and recorded again between each submission. -
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
specifies that a secondary command buffer is considered to be entirely inside a render pass. If this is a primary command buffer, then this bit is ignored. -
VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
specifies that a command buffer can be resubmitted to a queue while it is in the pending state, and recorded into multiple primary command buffers.
// Provided by VK_VERSION_1_0
typedef VkFlags VkCommandBufferUsageFlags;
VkCommandBufferUsageFlags
is a bitmask type for setting a mask of zero
or more VkCommandBufferUsageFlagBits.
If the command buffer is a secondary command buffer, then the
VkCommandBufferInheritanceInfo
structure defines any state that will
be inherited from the primary command buffer:
// Provided by VK_VERSION_1_0
typedef struct VkCommandBufferInheritanceInfo {
VkStructureType sType;
const void* pNext;
VkRenderPass renderPass;
uint32_t subpass;
VkFramebuffer framebuffer;
VkBool32 occlusionQueryEnable;
VkQueryControlFlags queryFlags;
VkQueryPipelineStatisticFlags pipelineStatistics;
} VkCommandBufferInheritanceInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
renderPass
is a VkRenderPass object defining which render passes theVkCommandBuffer
will be compatible with and can be executed within. If theVkCommandBuffer
will not be executed within a render pass instance,renderPass
is ignored. -
subpass
is the index of the subpass within the render pass instance that theVkCommandBuffer
will be executed within. If theVkCommandBuffer
will not be executed within a render pass instance,subpass
is ignored. -
framebuffer
optionally refers to the VkFramebuffer object that theVkCommandBuffer
will be rendering to if it is executed within a render pass instance. It can be VK_NULL_HANDLE if the framebuffer is not known, or if theVkCommandBuffer
will not be executed within a render pass instance.NoteSpecifying the exact framebuffer that the secondary command buffer will be executed with may result in better performance at command buffer execution time.
-
occlusionQueryEnable
specifies whether the command buffer can be executed while an occlusion query is active in the primary command buffer. If this isVK_TRUE
, then this command buffer can be executed whether the primary command buffer has an occlusion query active or not. If this isVK_FALSE
, then the primary command buffer must not have an occlusion query active. -
queryFlags
specifies the query flags that can be used by an active occlusion query in the primary command buffer when this secondary command buffer is executed. If this value includes theVK_QUERY_CONTROL_PRECISE_BIT
bit, then the active query can return boolean results or actual sample counts. If this bit is not set, then the active query must not use theVK_QUERY_CONTROL_PRECISE_BIT
bit. -
pipelineStatistics
is a bitmask of VkQueryPipelineStatisticFlagBits specifying the set of pipeline statistics that can be counted by an active query in the primary command buffer when this secondary command buffer is executed. If this value includes a given bit, then this command buffer can be executed whether the primary command buffer has a pipeline statistics query active that includes this bit or not. If this value excludes a given bit, then the active pipeline statistics query must not be from a query pool that counts that statistic.
Note
On some implementations, not using the
|
If a command buffer is in the invalid, or
executable state, and the command buffer was allocated from a command pool
with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
flag set,
then vkBeginCommandBuffer
implicitly resets the command buffer,
behaving as if vkResetCommandBuffer
had been called with
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT
not set.
After the implicit reset, commandBuffer
is moved to the
recording state.
If the pNext
chain of VkCommandBufferInheritanceInfo includes a
VkCommandBufferInheritanceConditionalRenderingInfoEXT
structure, then
that structure controls whether a command buffer can be executed while
conditional rendering is active in the
primary command buffer.
The VkCommandBufferInheritanceConditionalRenderingInfoEXT
structure is
defined as:
// Provided by VK_EXT_conditional_rendering
typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 conditionalRenderingEnable;
} VkCommandBufferInheritanceConditionalRenderingInfoEXT;
-
sType
is the type of this structure -
pNext
isNULL
or a pointer to a structure extending this structure -
conditionalRenderingEnable
specifies whether the command buffer can be executed while conditional rendering is active in the primary command buffer. If this isVK_TRUE
, then this command buffer can be executed whether the primary command buffer has active conditional rendering or not. If this isVK_FALSE
, then the primary command buffer must not have conditional rendering active.
If this structure is not present, the behavior is as if
conditionalRenderingEnable
is VK_FALSE
.
To begin recording a secondary command buffer compatible with execution
inside a render pass using render
pass transform, add the
VkCommandBufferInheritanceRenderPassTransformInfoQCOM to the
pNext
chain of VkCommandBufferInheritanceInfo structure passed
to the vkBeginCommandBuffer command specifying the parameters for
transformed rasterization.
The VkCommandBufferInheritanceRenderPassTransformInfoQCOM
structure is
defined as:
// Provided by VK_QCOM_render_pass_transform
typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM {
VkStructureType sType;
void* pNext;
VkSurfaceTransformFlagBitsKHR transform;
VkRect2D renderArea;
} VkCommandBufferInheritanceRenderPassTransformInfoQCOM;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
transform
is a VkSurfaceTransformFlagBitsKHR value describing the transform to be applied to the render pass. -
renderArea
is the render area that is affected by the command buffer.
When the secondary is recorded to execute within a render pass instance
using vkCmdExecuteCommands, the render pass transform parameters of
the secondary command buffer must be consistent with the render pass
transform parameters specified for the render pass instance.
In particular, the transform
and renderArea
for command buffer
must be identical to the transform
and renderArea
of the render
pass instance.
Once recording starts, an application records a sequence of commands
(vkCmd*
) to set state in the command buffer, draw, dispatch, and other
commands.
Several commands can also be recorded indirectly from VkBuffer
content, see Device-Generated Commands.
To complete recording of a command buffer, call:
// Provided by VK_VERSION_1_0
VkResult vkEndCommandBuffer(
VkCommandBuffer commandBuffer);
-
commandBuffer
is the command buffer to complete recording.
If there was an error during recording, the application will be notified by
an unsuccessful return code returned by vkEndCommandBuffer
.
If the application wishes to further use the command buffer, the command
buffer must be reset.
The command buffer must have been in the recording state, and is moved to the executable state.
When a command buffer is in the executable state, it can be submitted to a queue for execution.
5.5. Command Buffer Submission
Note
Submission can be a high overhead operation, and applications should
attempt to batch work together into as few calls to |
To submit command buffers to a queue, call:
// Provided by VK_VERSION_1_0
VkResult vkQueueSubmit(
VkQueue queue,
uint32_t submitCount,
const VkSubmitInfo* pSubmits,
VkFence fence);
-
queue
is the queue that the command buffers will be submitted to. -
submitCount
is the number of elements in thepSubmits
array. -
pSubmits
is a pointer to an array of VkSubmitInfo structures, each specifying a command buffer submission batch. -
fence
is an optional handle to a fence to be signaled once all submitted command buffers have completed execution. Iffence
is not VK_NULL_HANDLE, it defines a fence signal operation.
vkQueueSubmit
is a queue submission
command, with each batch defined by an element of pSubmits
.
Batches begin execution in the order they appear in pSubmits
, but may
complete out of order.
Fence and semaphore operations submitted with vkQueueSubmit have additional ordering constraints compared to other submission commands, with dependencies involving previous and subsequent queue operations. Information about these additional constraints can be found in the semaphore and fence sections of the synchronization chapter.
Details on the interaction of pWaitDstStageMask
with synchronization
are described in the semaphore wait
operation section of the synchronization chapter.
The order that batches appear in pSubmits
is used to determine
submission order, and thus all the
implicit ordering guarantees that respect it.
Other than these implicit ordering guarantees and any explicit synchronization primitives, these batches may overlap or
otherwise execute out of order.
If any command buffer submitted to this queue is in the
executable state, it is moved to the
pending state.
Once execution of all submissions of a command buffer complete, it moves
from the pending state, back to the
executable state.
If a command buffer was recorded with the
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
flag, it instead moves to
the invalid state.
If vkQueueSubmit
fails, it may return
VK_ERROR_OUT_OF_HOST_MEMORY
or VK_ERROR_OUT_OF_DEVICE_MEMORY
.
If it does, the implementation must ensure that the state and contents of
any resources or synchronization primitives referenced by the submitted
command buffers and any semaphores referenced by pSubmits
is
unaffected by the call or its failure.
If vkQueueSubmit
fails in such a way that the implementation is unable
to make that guarantee, the implementation must return
VK_ERROR_DEVICE_LOST
.
See Lost Device.
The VkSubmitInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkSubmitInfo {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreCount;
const VkSemaphore* pWaitSemaphores;
const VkPipelineStageFlags* pWaitDstStageMask;
uint32_t commandBufferCount;
const VkCommandBuffer* pCommandBuffers;
uint32_t signalSemaphoreCount;
const VkSemaphore* pSignalSemaphores;
} VkSubmitInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
waitSemaphoreCount
is the number of semaphores upon which to wait before executing the command buffers for the batch. -
pWaitSemaphores
is a pointer to an array of VkSemaphore handles upon which to wait before the command buffers for this batch begin execution. If semaphores to wait on are provided, they define a semaphore wait operation. -
pWaitDstStageMask
is a pointer to an array of pipeline stages at which each corresponding semaphore wait will occur. -
commandBufferCount
is the number of command buffers to execute in the batch. -
pCommandBuffers
is a pointer to an array of VkCommandBuffer handles to execute in the batch. -
signalSemaphoreCount
is the number of semaphores to be signaled once the commands specified inpCommandBuffers
have completed execution. -
pSignalSemaphores
is a pointer to an array of VkSemaphore handles which will be signaled when the command buffers for this batch have completed execution. If semaphores to be signaled are provided, they define a semaphore signal operation.
The order that command buffers appear in pCommandBuffers
is used to
determine submission order, and thus
all the implicit ordering guarantees that
respect it.
Other than these implicit ordering guarantees and any explicit synchronization primitives, these command buffers may overlap or
otherwise execute out of order.
To specify the values to use when waiting for and signaling semaphores
created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_TIMELINE
,
add a VkTimelineSemaphoreSubmitInfo structure to the pNext
chain
of the VkSubmitInfo structure when using vkQueueSubmit or the
VkBindSparseInfo structure when using vkQueueBindSparse.
The VkTimelineSemaphoreSubmitInfo
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkTimelineSemaphoreSubmitInfo {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreValueCount;
const uint64_t* pWaitSemaphoreValues;
uint32_t signalSemaphoreValueCount;
const uint64_t* pSignalSemaphoreValues;
} VkTimelineSemaphoreSubmitInfo;
or the equivalent
// Provided by VK_KHR_timeline_semaphore
typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
waitSemaphoreValueCount
is the number of semaphore wait values specified inpWaitSemaphoreValues
. -
pWaitSemaphoreValues
is an array of lengthwaitSemaphoreValueCount
containing values for the corresponding semaphores in VkSubmitInfo::pWaitSemaphores
to wait for. -
signalSemaphoreValueCount
is the number of semaphore signal values specified inpSignalSemaphoreValues
. -
pSignalSemaphoreValues
is an array of lengthsignalSemaphoreValueCount
containing values for the corresponding semaphores in VkSubmitInfo::pSignalSemaphores
to set when signaled.
If the semaphore in VkSubmitInfo::pWaitSemaphores
or
VkSubmitInfo::pSignalSemaphores
corresponding to an entry in
pWaitSemaphoreValues
or pSignalSemaphoreValues
respectively was
not created with a VkSemaphoreType of
VK_SEMAPHORE_TYPE_TIMELINE
, the implementation must ignore the value
in the pWaitSemaphoreValues
or pSignalSemaphoreValues
entry.
To specify the values to use when waiting for and signaling semaphores whose
current payload refers to a
Direct3D 12 fence, add a VkD3D12FenceSubmitInfoKHR structure to the
pNext
chain of the VkSubmitInfo structure.
The VkD3D12FenceSubmitInfoKHR
structure is defined as:
// Provided by VK_KHR_external_semaphore_win32
typedef struct VkD3D12FenceSubmitInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreValuesCount;
const uint64_t* pWaitSemaphoreValues;
uint32_t signalSemaphoreValuesCount;
const uint64_t* pSignalSemaphoreValues;
} VkD3D12FenceSubmitInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
waitSemaphoreValuesCount
is the number of semaphore wait values specified inpWaitSemaphoreValues
. -
pWaitSemaphoreValues
is a pointer to an array ofwaitSemaphoreValuesCount
values for the corresponding semaphores in VkSubmitInfo::pWaitSemaphores
to wait for. -
signalSemaphoreValuesCount
is the number of semaphore signal values specified inpSignalSemaphoreValues
. -
pSignalSemaphoreValues
is a pointer to an array ofsignalSemaphoreValuesCount
values for the corresponding semaphores in VkSubmitInfo::pSignalSemaphores
to set when signaled.
If the semaphore in VkSubmitInfo::pWaitSemaphores
or
VkSubmitInfo::pSignalSemaphores
corresponding to an entry in
pWaitSemaphoreValues
or pSignalSemaphoreValues
respectively does
not currently have a payload
referring to a Direct3D 12 fence, the implementation must ignore the value
in the pWaitSemaphoreValues
or pSignalSemaphoreValues
entry.
Note
As the introduction of the external semaphore handle type
|
When submitting work that operates on memory imported from a Direct3D 11
resource to a queue, the keyed mutex mechanism may be used in addition to
Vulkan semaphores to synchronize the work.
Keyed mutexes are a property of a properly created shareable Direct3D 11
resource.
They can only be used if the imported resource was created with the
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
flag.
To acquire keyed mutexes before submitted work and/or release them after,
add a VkWin32KeyedMutexAcquireReleaseInfoKHR structure to the
pNext
chain of the VkSubmitInfo structure.
The VkWin32KeyedMutexAcquireReleaseInfoKHR
structure is defined as:
// Provided by VK_KHR_win32_keyed_mutex
typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeouts;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoKHR;
-
acquireCount
is the number of entries in thepAcquireSyncs
,pAcquireKeys
, andpAcquireTimeoutMilliseconds
arrays. -
pAcquireSyncs
is a pointer to an array of VkDeviceMemory objects which were imported from Direct3D 11 resources. -
pAcquireKeys
is a pointer to an array of mutex key values to wait for prior to beginning the submitted work. Entries refer to the keyed mutex associated with the corresponding entries inpAcquireSyncs
. -
pAcquireTimeoutMilliseconds
is a pointer to an array of timeout values, in millisecond units, for each acquire specified inpAcquireKeys
. -
releaseCount
is the number of entries in thepReleaseSyncs
andpReleaseKeys
arrays. -
pReleaseSyncs
is a pointer to an array of VkDeviceMemory objects which were imported from Direct3D 11 resources. -
pReleaseKeys
is a pointer to an array of mutex key values to set when the submitted work has completed. Entries refer to the keyed mutex associated with the corresponding entries inpReleaseSyncs
.
When submitting work that operates on memory imported from a Direct3D 11
resource to a queue, the keyed mutex mechanism may be used in addition to
Vulkan semaphores to synchronize the work.
Keyed mutexes are a property of a properly created shareable Direct3D 11
resource.
They can only be used if the imported resource was created with the
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
flag.
To acquire keyed mutexes before submitted work and/or release them after,
add a VkWin32KeyedMutexAcquireReleaseInfoNV structure to the
pNext
chain of the VkSubmitInfo structure.
The VkWin32KeyedMutexAcquireReleaseInfoNV
structure is defined as:
// Provided by VK_NV_win32_keyed_mutex
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeoutMilliseconds;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoNV;
-
acquireCount
is the number of entries in thepAcquireSyncs
,pAcquireKeys
, andpAcquireTimeoutMilliseconds
arrays. -
pAcquireSyncs
is a pointer to an array of VkDeviceMemory objects which were imported from Direct3D 11 resources. -
pAcquireKeys
is a pointer to an array of mutex key values to wait for prior to beginning the submitted work. Entries refer to the keyed mutex associated with the corresponding entries inpAcquireSyncs
. -
pAcquireTimeoutMilliseconds
is a pointer to an array of timeout values, in millisecond units, for each acquire specified inpAcquireKeys
. -
releaseCount
is the number of entries in thepReleaseSyncs
andpReleaseKeys
arrays. -
pReleaseSyncs
is a pointer to an array of VkDeviceMemory objects which were imported from Direct3D 11 resources. -
pReleaseKeys
is a pointer to an array of mutex key values to set when the submitted work has completed. Entries refer to the keyed mutex associated with the corresponding entries inpReleaseSyncs
.
If the pNext
chain of VkSubmitInfo includes a
VkProtectedSubmitInfo
structure, then the structure indicates whether
the batch is protected.
The VkProtectedSubmitInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkProtectedSubmitInfo {
VkStructureType sType;
const void* pNext;
VkBool32 protectedSubmit;
} VkProtectedSubmitInfo;
-
protectedSubmit
specifies whether the batch is protected. IfprotectedSubmit
isVK_TRUE
, the batch is protected. IfprotectedSubmit
isVK_FALSE
, the batch is unprotected. If theVkSubmitInfo
::pNext
chain does not include this structure, the batch is unprotected.
If the pNext
chain of VkSubmitInfo includes a
VkDeviceGroupSubmitInfo
structure, then that structure includes device
indices and masks specifying which physical devices execute semaphore
operations and command buffers.
The VkDeviceGroupSubmitInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkDeviceGroupSubmitInfo {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreCount;
const uint32_t* pWaitSemaphoreDeviceIndices;
uint32_t commandBufferCount;
const uint32_t* pCommandBufferDeviceMasks;
uint32_t signalSemaphoreCount;
const uint32_t* pSignalSemaphoreDeviceIndices;
} VkDeviceGroupSubmitInfo;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
waitSemaphoreCount
is the number of elements in thepWaitSemaphoreDeviceIndices
array. -
pWaitSemaphoreDeviceIndices
is a pointer to an array ofwaitSemaphoreCount
device indices indicating which physical device executes the semaphore wait operation in the corresponding element of VkSubmitInfo::pWaitSemaphores
. -
commandBufferCount
is the number of elements in thepCommandBufferDeviceMasks
array. -
pCommandBufferDeviceMasks
is a pointer to an array ofcommandBufferCount
device masks indicating which physical devices execute the command buffer in the corresponding element of VkSubmitInfo::pCommandBuffers
. A physical device executes the command buffer if the corresponding bit is set in the mask. -
signalSemaphoreCount
is the number of elements in thepSignalSemaphoreDeviceIndices
array. -
pSignalSemaphoreDeviceIndices
is a pointer to an array ofsignalSemaphoreCount
device indices indicating which physical device executes the semaphore signal operation in the corresponding element of VkSubmitInfo::pSignalSemaphores
.
If this structure is not present, semaphore operations and command buffers execute on device index zero.
If the pNext
chain of VkSubmitInfo includes a
VkPerformanceQuerySubmitInfoKHR structure, then the structure
indicates which counter pass is active for the batch in that submit.
The VkPerformanceQuerySubmitInfoKHR
structure is defined as:
// Provided by VK_KHR_performance_query
typedef struct VkPerformanceQuerySubmitInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t counterPassIndex;
} VkPerformanceQuerySubmitInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
counterPassIndex
specifies which counter pass index is active.
If the VkSubmitInfo
::pNext
chain does not include this
structure, the batch defaults to use counter pass index 0.
5.6. Queue Forward Progress
When using binary semaphores, the application must ensure that command
buffer submissions will be able to complete without any subsequent
operations by the application on any queue.
After any call to vkQueueSubmit
(or other queue operation), for every
queued wait on a semaphore
created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_BINARY
there must be a prior signal of that semaphore that will not be consumed by
a different wait on the semaphore.
When using timeline semaphores, wait-before-signal behavior is well-defined
and applications can submit work via vkQueueSubmit
which defines a
timeline semaphore wait operation
before submitting a corresponding semaphore signal operation.
For each timeline semaphore wait
operation defined by a call to vkQueueSubmit
, the application must
ensure that a corresponding semaphore signal operation is executed before forward progress can be
made.
Command buffers in the submission can include vkCmdWaitEvents
commands that wait on events that will not be signaled by earlier commands
in the queue.
Such events must be signaled by the application using vkSetEvent, and
the vkCmdWaitEvents
commands that wait upon them must not be inside a
render pass instance.
The event must be set before the vkCmdWaitEvents command is executed.
Note
Implementations may have some tolerance for waiting on events to be set, but this is defined outside of the scope of Vulkan. |
5.7. Secondary Command Buffer Execution
A secondary command buffer must not be directly submitted to a queue. Instead, secondary command buffers are recorded to execute as part of a primary command buffer with the command:
// Provided by VK_VERSION_1_0
void vkCmdExecuteCommands(
VkCommandBuffer commandBuffer,
uint32_t commandBufferCount,
const VkCommandBuffer* pCommandBuffers);
-
commandBuffer
is a handle to a primary command buffer that the secondary command buffers are executed in. -
commandBufferCount
is the length of thepCommandBuffers
array. -
pCommandBuffers
is a pointer to an array ofcommandBufferCount
secondary command buffer handles, which are recorded to execute in the primary command buffer in the order they are listed in the array.
If any element of pCommandBuffers
was not recorded with the
VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
flag, and it was recorded
into any other primary command buffer which is currently in the
executable or recording state, that primary
command buffer becomes invalid.
5.8. Command Buffer Device Mask
Each command buffer has a piece of state storing the current device mask of the command buffer. This mask controls which physical devices within the logical device all subsequent commands will execute on, including state-setting commands, action commands, and synchronization commands.
Scissor, exclusive scissor, and viewport state (excluding the count of each) can be set to different values on each physical device (only when set as dynamic state), and each physical device will render using its local copy of the state. Other state is shared between physical devices, such that all physical devices use the most recently set values for the state. However, when recording an action command that uses a piece of state, the most recent command that set that state must have included all physical devices that execute the action command in its current device mask.
The command buffer’s device mask is orthogonal to the
pCommandBufferDeviceMasks
member of VkDeviceGroupSubmitInfo.
Commands only execute on a physical device if the device index is set in
both device masks.
If the pNext
chain of VkCommandBufferBeginInfo includes a
VkDeviceGroupCommandBufferBeginInfo
structure, then that structure
includes an initial device mask for the command buffer.
The VkDeviceGroupCommandBufferBeginInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkDeviceGroupCommandBufferBeginInfo {
VkStructureType sType;
const void* pNext;
uint32_t deviceMask;
} VkDeviceGroupCommandBufferBeginInfo;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupCommandBufferBeginInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
deviceMask
is the initial value of the command buffer’s device mask.
The initial device mask also acts as an upper bound on the set of devices that can ever be in the device mask in the command buffer.
If this structure is not present, the initial value of a command buffer’s device mask is set to include all physical devices in the logical device when the command buffer begins recording.
To update the current device mask of a command buffer, call:
// Provided by VK_VERSION_1_1
void vkCmdSetDeviceMask(
VkCommandBuffer commandBuffer,
uint32_t deviceMask);
or the equivalent command
// Provided by VK_KHR_device_group
void vkCmdSetDeviceMaskKHR(
VkCommandBuffer commandBuffer,
uint32_t deviceMask);
-
commandBuffer
is command buffer whose current device mask is modified. -
deviceMask
is the new value of the current device mask.
deviceMask
is used to filter out subsequent commands from executing on
all physical devices whose bit indices are not set in the mask, except
commands beginning a render pass instance, commands transitioning to the
next subpass in the render pass instance, and commands ending a render pass
instance, which always execute on the set of physical devices whose bit
indices are included in the deviceMask
member of the
VkDeviceGroupRenderPassBeginInfo structure passed to the command
beginning the corresponding render pass instance.
6. Synchronization and Cache Control
Synchronization of access to resources is primarily the responsibility of the application in Vulkan. The order of execution of commands with respect to the host and other commands on the device has few implicit guarantees, and needs to be explicitly specified. Memory caches and other optimizations are also explicitly managed, requiring that the flow of data through the system is largely under application control.
Whilst some implicit guarantees exist between commands, five explicit synchronization mechanisms are exposed by Vulkan:
- Fences
-
Fences can be used to communicate to the host that execution of some task on the device has completed.
- Semaphores
-
Semaphores can be used to control resource access across multiple queues.
- Events
-
Events provide a fine-grained synchronization primitive which can be signaled either within a command buffer or by the host, and can be waited upon within a command buffer or queried on the host.
- Pipeline Barriers
-
Pipeline barriers also provide synchronization control within a command buffer, but at a single point, rather than with separate signal and wait operations.
- Render Passes
-
Render passes provide a useful synchronization framework for most rendering tasks, built upon the concepts in this chapter. Many cases that would otherwise need an application to use other synchronization primitives can be expressed more efficiently as part of a render pass.
6.1. Execution and Memory Dependencies
An operation is an arbitrary amount of work to be executed on the host, a device, or an external entity such as a presentation engine. Synchronization commands introduce explicit execution dependencies, and memory dependencies between two sets of operations defined by the command’s two synchronization scopes.
The synchronization scopes define which other operations a synchronization command is able to create execution dependencies with. Any type of operation that is not in a synchronization command’s synchronization scopes will not be included in the resulting dependency. For example, for many synchronization commands, the synchronization scopes can be limited to just operations executing in specific pipeline stages, which allows other pipeline stages to be excluded from a dependency. Other scoping options are possible, depending on the particular command.
An execution dependency is a guarantee that for two sets of operations, the first set must happen-before the second set. If an operation happens-before another operation, then the first operation must complete before the second operation is initiated. More precisely:
-
Let A and B be separate sets of operations.
-
Let S be a synchronization command.
-
Let AS and BS be the synchronization scopes of S.
-
Let A' be the intersection of sets A and AS.
-
Let B' be the intersection of sets B and BS.
-
Submitting A, S and B for execution, in that order, will result in execution dependency E between A' and B'.
-
Execution dependency E guarantees that A' happens-before B'.
An execution dependency chain is a sequence of execution dependencies that form a happens-before relation between the first dependency’s A' and the final dependency’s B'. For each consecutive pair of execution dependencies, a chain exists if the intersection of BS in the first dependency and AS in the second dependency is not an empty set. The formation of a single execution dependency from an execution dependency chain can be described by substituting the following in the description of execution dependencies:
-
Let S be a set of synchronization commands that generate an execution dependency chain.
-
Let AS be the first synchronization scope of the first command in S.
-
Let BS be the second synchronization scope of the last command in S.
Execution dependencies alone are not sufficient to guarantee that values resulting from writes in one set of operations can be read from another set of operations.
Three additional types of operation are used to control memory access. Availability operations cause the values generated by specified memory write accesses to become available to a memory domain for future access. Any available value remains available until a subsequent write to the same memory location occurs (whether it is made available or not) or the memory is freed. Memory domain operations cause writes that are available to a source memory domain to become available to a destination memory domain (an example of this is making writes available to the host domain available to the device domain). Visibility operations cause values available to a memory domain to become visible to specified memory accesses.
Availability, visibility, memory domains, and memory domain operations are formally defined in the Availability and Visibility section of the Memory Model chapter. Which API operations perform each of these operations is defined in Availability, Visibility, and Domain Operations.
A memory dependency is an execution dependency which includes availability and visibility operations such that:
-
The first set of operations happens-before the availability operation.
-
The availability operation happens-before the visibility operation.
-
The visibility operation happens-before the second set of operations.
Once written values are made visible to a particular type of memory access, they can be read or written by that type of memory access. Most synchronization commands in Vulkan define a memory dependency.
The specific memory accesses that are made available and visible are defined by the access scopes of a memory dependency. Any type of access that is in a memory dependency’s first access scope and occurs in A' is made available. Any type of access that is in a memory dependency’s second access scope and occurs in B' has any available writes made visible to it. Any type of operation that is not in a synchronization command’s access scopes will not be included in the resulting dependency.
A memory dependency enforces availability and visibility of memory accesses and execution order between two sets of operations. Adding to the description of execution dependency chains:
-
Let a be the set of memory accesses performed by A'.
-
Let b be the set of memory accesses performed by B'.
-
Let aS be the first access scope of the first command in S.
-
Let bS be the second access scope of the last command in S.
-
Let a' be the intersection of sets a and aS.
-
Let b' be the intersection of sets b and bS.
-
Submitting A, S and B for execution, in that order, will result in a memory dependency m between A' and B'.
-
Memory dependency m guarantees that:
-
Memory writes in a' are made available.
-
Available memory writes, including those from a', are made visible to b'.
-
Note
Execution and memory dependencies are used to solve data hazards, i.e. to ensure that read and write operations occur in a well-defined order. Write-after-read hazards can be solved with just an execution dependency, but read-after-write and write-after-write hazards need appropriate memory dependencies to be included between them. If an application does not include dependencies to solve these hazards, the results and execution orders of memory accesses are undefined. |
6.1.1. Image Layout Transitions
Image subresources can be transitioned from one layout to another as part of a memory dependency (e.g. by using an image memory barrier). When a layout transition is specified in a memory dependency, it happens-after the availability operations in the memory dependency, and happens-before the visibility operations. Image layout transitions may perform read and write accesses on all memory bound to the image subresource range, so applications must ensure that all memory writes have been made available before a layout transition is executed. Available memory is automatically made visible to a layout transition, and writes performed by a layout transition are automatically made available.
Layout transitions always apply to a particular image subresource range, and
specify both an old layout and new layout.
The old layout must either be VK_IMAGE_LAYOUT_UNDEFINED
, or match the
current layout of the image subresource range.
If the old layout matches the current layout of the image subresource range,
the transition preserves the contents of that range.
If the old layout is VK_IMAGE_LAYOUT_UNDEFINED
, the contents of that
range may be discarded.
As image layout transitions may perform read and write accesses on the
memory bound to the image, if the image subresource affected by the layout
transition is bound to peer memory for any device in the current device mask
then the memory heap the bound memory comes from must support the
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT
and
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT
capabilities as returned by
vkGetDeviceGroupPeerMemoryFeatures.
Note
Applications must ensure that layout transitions happen-after all operations accessing the image with the old layout, and happen-before any operations that will access the image with the new layout. Layout transitions are potentially read/write operations, so not defining appropriate memory dependencies to guarantee this will result in a data race. |
Image layout transitions interact with memory aliasing.
Layout transitions that are performed via image memory barriers execute in their entirety in submission order, relative to other image layout transitions submitted to the same queue, including those performed by render passes. In effect there is an implicit execution dependency from each such layout transition to all layout transitions previously submitted to the same queue.
The image layout of each image subresource of a depth/stencil image created
with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
is
dependent on the last sample locations used to render to the image
subresource as a depth/stencil attachment, thus when the image
member
of an image memory barrier is an
image created with this flag the application can chain a
VkSampleLocationsInfoEXT structure to the pNext
chain of
VkImageMemoryBarrier to specify the sample locations to use during any
image layout transition.
If the VkSampleLocationsInfoEXT
structure does not match the sample
location state last used to render to the image subresource range specified
by subresourceRange
, or if no VkSampleLocationsInfoEXT
structure
is present, then the contents of the given image subresource range becomes
undefined as if oldLayout
would equal
VK_IMAGE_LAYOUT_UNDEFINED
.
6.1.2. Pipeline Stages
The work performed by an action or synchronization command consists of multiple operations, which are performed as a sequence of logically independent steps known as pipeline stages. The exact pipeline stages executed depend on the particular command that is used, and current command buffer state when the command was recorded. Drawing commands, dispatching commands, copy commands, clear commands, and synchronization commands all execute in different sets of pipeline stages. Synchronization commands do not execute in a defined pipeline.
Note
Operations performed by synchronization commands (e.g. availability and visibility operations) are not executed by a defined pipeline stage. However other commands can still synchronize with them by using the synchronization scopes to create a dependency chain. |
Execution of operations across pipeline stages must adhere to implicit ordering guarantees, particularly including pipeline stage order. Otherwise, execution across pipeline stages may overlap or execute out of order with regards to other stages, unless otherwise enforced by an execution dependency.
Several of the synchronization commands include pipeline stage parameters, restricting the synchronization scopes for that command to just those stages. This allows fine grained control over the exact execution dependencies and accesses performed by action commands. Implementations should use these pipeline stages to avoid unnecessary stalls or cache flushing.
The VkPipelineStageFlagBits
enum is defined as:
// Provided by VK_VERSION_1_0
typedef enum VkPipelineStageFlagBits {
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004,
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008,
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010,
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020,
VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100,
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800,
VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000,
VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
// Provided by VK_EXT_transform_feedback
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000,
// Provided by VK_EXT_conditional_rendering
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
// Provided by VK_KHR_ray_tracing
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000,
// Provided by VK_KHR_ray_tracing
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000,
// Provided by VK_NV_shading_rate_image
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000,
// Provided by VK_NV_mesh_shader
VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000,
// Provided by VK_NV_mesh_shader
VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000,
// Provided by VK_EXT_fragment_density_map
VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000,
// Provided by VK_NV_device_generated_commands
VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000,
// Provided by VK_NV_ray_tracing
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
// Provided by VK_NV_ray_tracing
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
} VkPipelineStageFlagBits;
-
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
is equivalent toVK_PIPELINE_STAGE_ALL_COMMANDS_BIT
with VkAccessFlags set to0
when specified in the second synchronization scope, but specifies no stages in the first scope. -
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
specifies the stage of the pipeline where Draw/DispatchIndirect data structures are consumed. This stage also includes reading commands written by vkCmdExecuteGeneratedCommandsNV. -
VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV
specifies the task shader stage. -
VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV
specifies the mesh shader stage. -
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
specifies the stage of the pipeline where vertex and index buffers are consumed. -
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
specifies the vertex shader stage. -
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
specifies the tessellation control shader stage. -
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
specifies the tessellation evaluation shader stage. -
VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
specifies the geometry shader stage. -
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
specifies the fragment shader stage. -
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
specifies the stage of the pipeline where early fragment tests (depth and stencil tests before fragment shading) are performed. This stage also includes subpass load operations for framebuffer attachments with a depth/stencil format. -
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
specifies the stage of the pipeline where late fragment tests (depth and stencil tests after fragment shading) are performed. This stage also includes subpass store operations for framebuffer attachments with a depth/stencil format. -
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
specifies the stage of the pipeline after blending where the final color values are output from the pipeline. This stage also includes subpass load and store operations and multisample resolve operations for framebuffer attachments with a color or depth/stencil format. -
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
specifies the execution of a compute shader. -
VK_PIPELINE_STAGE_TRANSFER_BIT
specifies the following commands:-
All copy commands, including vkCmdCopyQueryPoolResults
-
All clear commands, with the exception of vkCmdClearAttachments
-
-
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
is equivalent toVK_PIPELINE_STAGE_ALL_COMMANDS_BIT
with VkAccessFlags set to0
when specified in the first synchronization scope, but specifies no stages in the second scope. -
VK_PIPELINE_STAGE_HOST_BIT
specifies a pseudo-stage indicating execution on the host of reads/writes of device memory. This stage is not invoked by any commands recorded in a command buffer. -
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR
specifies the execution of the ray tracing shader stages. -
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
specifies the execution of acceleration structure commands. -
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT
specifies the execution of all graphics pipeline stages, and is equivalent to the logical OR of:-
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
-
VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV
-
VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV
-
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
-
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
-
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
-
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
-
VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
-
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
-
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
-
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
-
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
-
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV
-
VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
-
-
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
specifies all commands supported on the queue it is used with. -
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
specifies the stage of the pipeline where the predicate of conditional rendering is consumed. -
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
specifies the stage of the pipeline where vertex attribute output values are written to the transform feedback buffers. -
VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV
specifies the stage of the pipeline where device-side preprocessing for generated commands via vkCmdPreprocessGeneratedCommandsNV is handled. -
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV
specifies the stage of the pipeline where the shading rate image is read to determine the shading rate for portions of a rasterized primitive. -
VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
specifies the stage of the pipeline where the fragment density map is read to generate the fragment areas.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineStageFlags;
VkPipelineStageFlags
is a bitmask type for setting a mask of zero or
more VkPipelineStageFlagBits.
If a synchronization command includes a source stage mask, its first synchronization scope only includes execution of the pipeline stages specified in that mask, and its first access scope only includes memory access performed by pipeline stages specified in that mask. If a synchronization command includes a destination stage mask, its second synchronization scope only includes execution of the pipeline stages specified in that mask, and its second access scope only includes memory access performed by pipeline stages specified in that mask.
Note
Including a particular pipeline stage in the first synchronization scope of a command implicitly includes logically earlier pipeline stages in the synchronization scope. Similarly, the second synchronization scope includes logically later pipeline stages. However, note that access scopes are not affected in this way - only the precise stages specified are considered part of each access scope. |
Certain pipeline stages are only available on queues that support a particular set of operations. The following table lists, for each pipeline stage flag, which queue capability flag must be supported by the queue. When multiple flags are enumerated in the second column of the table, it means that the pipeline stage is supported on the queue if it supports any of the listed capability flags. For further details on queue capabilities see Physical Device Enumeration and Queues.
Pipeline stage flag | Required queue capability flag |
---|---|
|
None required |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
None required |
|
None required |
|
|
|
None required |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pipeline stages that execute as a result of a command logically complete execution in a specific order, such that completion of a logically later pipeline stage must not happen-before completion of a logically earlier stage. This means that including any stage in the source stage mask for a particular synchronization command also implies that any logically earlier stages are included in AS for that command.
Similarly, initiation of a logically earlier pipeline stage must not happen-after initiation of a logically later pipeline stage. Including any given stage in the destination stage mask for a particular synchronization command also implies that any logically later stages are included in BS for that command.
Note
Implementations may not support synchronization at every pipeline stage for every synchronization operation. If a pipeline stage that an implementation does not support synchronization for appears in a source stage mask, it may substitute any logically later stage in its place for the first synchronization scope. If a pipeline stage that an implementation does not support synchronization for appears in a destination stage mask, it may substitute any logically earlier stage in its place for the second synchronization scope. For example, if an implementation is unable to signal an event immediately after vertex shader execution is complete, it may instead signal the event after color attachment output has completed. If an implementation makes such a substitution, it must not affect the semantics of execution or memory dependencies or image and buffer memory barriers. |
Graphics pipelines are executable on queues
supporting VK_QUEUE_GRAPHICS_BIT
.
Stages executed by graphics pipelines can only be specified in commands
recorded for queues supporting VK_QUEUE_GRAPHICS_BIT
.
The graphics primitive pipeline executes the following stages, with the logical ordering of the stages matching the order specified here:
-
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
-
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
-
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
-
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
-
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
-
VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
-
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
-
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV
-
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
-
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
The graphics mesh pipeline executes the following stages, with the logical ordering of the stages matching the order specified here:
-
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
-
VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV
-
VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV
-
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV
-
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
-
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
For the compute pipeline, the following stages occur in this order:
-
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
-
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
For graphics pipeline commands executing in a render pass with a fragment
density map attachment, the following pipeline stage where the fragment
density map read happens has no particular order relative to the other
stages, except that it is logically earlier than
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
:
-
VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
-
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
The conditional rendering stage is formally part of both the graphics, and the compute pipeline. The pipeline stage where the predicate read happens has unspecified order relative to other stages of these pipelines:
-
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
For the transfer pipeline, the following stages occur in this order:
-
VK_PIPELINE_STAGE_TRANSFER_BIT
For host operations, only one pipeline stage occurs, so no order is guaranteed:
-
VK_PIPELINE_STAGE_HOST_BIT
For the command preprocessing pipeline, the following stages occur in this order:
-
VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV
For the ray tracing shader pipeline, only one pipeline stage occurs, so no order is guaranteed:
-
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR
For ray tracing acceleration structure operations, only one pipeline stage occurs, so no order is guaranteed:
-
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
6.1.3. Access Types
Memory in Vulkan can be accessed from within shader invocations and via some fixed-function stages of the pipeline. The access type is a function of the descriptor type used, or how a fixed-function stage accesses memory.
Some synchronization commands take sets of access types as parameters to define the access scopes of a memory dependency. If a synchronization command includes a source access mask, its first access scope only includes accesses via the access types specified in that mask. Similarly, if a synchronization command includes a destination access mask, its second access scope only includes accesses via the access types specified in that mask.
The VkAccessFlagBits
enums is defined as:
// Provided by VK_VERSION_1_0
typedef enum VkAccessFlagBits {
VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001,
VK_ACCESS_INDEX_READ_BIT = 0x00000002,
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004,
VK_ACCESS_UNIFORM_READ_BIT = 0x00000008,
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010,
VK_ACCESS_SHADER_READ_BIT = 0x00000020,
VK_ACCESS_SHADER_WRITE_BIT = 0x00000040,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400,
VK_ACCESS_TRANSFER_READ_BIT = 0x00000800,
VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000,
VK_ACCESS_HOST_READ_BIT = 0x00002000,
VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
// Provided by VK_EXT_transform_feedback
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000,
// Provided by VK_EXT_transform_feedback
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000,
// Provided by VK_EXT_transform_feedback
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000,
// Provided by VK_EXT_conditional_rendering
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000,
// Provided by VK_EXT_blend_operation_advanced
VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
// Provided by VK_KHR_ray_tracing
VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000,
// Provided by VK_KHR_ray_tracing
VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000,
// Provided by VK_NV_shading_rate_image
VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000,
// Provided by VK_EXT_fragment_density_map
VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000,
// Provided by VK_NV_device_generated_commands
VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000,
// Provided by VK_NV_device_generated_commands
VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000,
// Provided by VK_NV_ray_tracing
VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
// Provided by VK_NV_ray_tracing
VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
} VkAccessFlagBits;
-
VK_ACCESS_INDIRECT_COMMAND_READ_BIT
specifies read access to indirect command data read as part of an indirect drawing or dispatch command. -
VK_ACCESS_INDEX_READ_BIT
specifies read access to an index buffer as part of an indexed drawing command, bound by vkCmdBindIndexBuffer. -
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
specifies read access to a vertex buffer as part of a drawing command, bound by vkCmdBindVertexBuffers. -
VK_ACCESS_UNIFORM_READ_BIT
specifies read access to a uniform buffer. -
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
specifies read access to an input attachment within a render pass during fragment shading. -
VK_ACCESS_SHADER_READ_BIT
specifies read access to a storage buffer, physical storage buffer, shader binding table, uniform texel buffer, storage texel buffer, sampled image, or storage image. -
VK_ACCESS_SHADER_WRITE_BIT
specifies write access to a storage buffer, physical storage buffer, storage texel buffer, or storage image. -
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
specifies read access to a color attachment, such as via blending, logic operations, or via certain subpass load operations. It does not include advanced blend operations. -
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
specifies write access to a color, resolve, or depth/stencil resolve attachment during a render pass or via certain subpass load and store operations. -
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
specifies read access to a depth/stencil attachment, via depth or stencil operations or via certain subpass load operations. -
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
specifies write access to a depth/stencil attachment, via depth or stencil operations or via certain subpass load and store operations. -
VK_ACCESS_TRANSFER_READ_BIT
specifies read access to an image or buffer in a copy operation. -
VK_ACCESS_TRANSFER_WRITE_BIT
specifies write access to an image or buffer in a clear or copy operation. -
VK_ACCESS_HOST_READ_BIT
specifies read access by a host operation. Accesses of this type are not performed through a resource, but directly on memory. -
VK_ACCESS_HOST_WRITE_BIT
specifies write access by a host operation. Accesses of this type are not performed through a resource, but directly on memory. -
VK_ACCESS_MEMORY_READ_BIT
specifies all read accesses. It is always valid in any access mask, and is treated as equivalent to setting allREAD
access flags that are valid where it is used. -
VK_ACCESS_MEMORY_WRITE_BIT
specifies all write accesses. It is always valid in any access mask, and is treated as equivalent to setting allWRITE
access flags that are valid where it is used. -
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT
specifies read access to a predicate as part of conditional rendering. -
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT
specifies write access to a transform feedback buffer made when transform feedback is active. -
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
specifies read access to a transform feedback counter buffer which is read whenvkCmdBeginTransformFeedbackEXT
executes. -
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
specifies write access to a transform feedback counter buffer which is written whenvkCmdEndTransformFeedbackEXT
executes. -
VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV
specifies reads fromVkBuffer
inputs to vkCmdPreprocessGeneratedCommandsNV. -
VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV
specifies writes to theVkBuffer
preprocess outputs in vkCmdPreprocessGeneratedCommandsNV. -
VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT
is similar toVK_ACCESS_COLOR_ATTACHMENT_READ_BIT
, but also includes advanced blend operations. -
VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV
specifies read access to a shading rate image as part of a drawing command, as bound by vkCmdBindShadingRateImageNV. -
VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR
specifies read access to an acceleration structure as part of a trace or build command, or to an acceleration structure scratch buffer as part of a build command. -
VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR
specifies write access to an acceleration structure or acceleration structure scratch buffer as part of a build command. -
VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT
specifies read access to a fragment density map attachment during dynamic fragment density map operations
Certain access types are only performed by a subset of pipeline stages. Any synchronization command that takes both stage masks and access masks uses both to define the access scopes - only the specified access types performed by the specified stages are included in the access scope. An application must not specify an access flag in a synchronization command if it does not include a pipeline stage in the corresponding stage mask that is able to perform accesses of that type. The following table lists, for each access flag, which pipeline stages can perform that type of access.
Access flag | Supported pipeline stages |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Any |
|
Any |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Provided by VK_VERSION_1_0
typedef VkFlags VkAccessFlags;
VkAccessFlags
is a bitmask type for setting a mask of zero or more
VkAccessFlagBits.
If a memory object does not have the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
property, then
vkFlushMappedMemoryRanges must be called in order to guarantee that
writes to the memory object from the host are made available to the host
domain, where they can be further made available to the device domain via a
domain operation.
Similarly, vkInvalidateMappedMemoryRanges must be called to guarantee
that writes which are available to the host domain are made visible to host
operations.
If the memory object does have the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
property flag, writes to the
memory object from the host are automatically made available to the host
domain.
Similarly, writes made available to the host domain are automatically made
visible to the host.
Note
Queue submission commands automatically perform a domain operation from host to device for all writes performed before the command executes, so in most cases an explicit memory barrier is not needed for this case. In the few circumstances where a submit does not occur between the host write and the device read access, writes can be made available by using an explicit memory barrier. |
6.1.4. Framebuffer Region Dependencies
Pipeline stages that operate on, or with respect to, the framebuffer are collectively the framebuffer-space pipeline stages. These stages are:
-
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
-
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
-
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
For these pipeline stages, an execution or memory dependency from the first set of operations to the second set can either be a single framebuffer-global dependency, or split into multiple framebuffer-local dependencies. A dependency with non-framebuffer-space pipeline stages is neither framebuffer-global nor framebuffer-local.
A framebuffer region is a subset of the entire framebuffer, and can either be:
-
A sample region, which is set of sample (x, y, layer, sample) coordinates that is a subset of the entire framebuffer, or
-
A fragment region, which is a set of fragment (x, y, layer) coordinates that is a subset of the entire framebuffer.
Both synchronization scopes of a framebuffer-local dependency include only the operations performed within corresponding framebuffer regions (as defined below). No ordering guarantees are made between different framebuffer regions for a framebuffer-local dependency.
Both synchronization scopes of a framebuffer-global dependency include operations on all framebuffer-regions.
If the first synchronization scope includes operations on pixels/fragments
with N samples and the second synchronization scope includes operations on
pixels/fragments with M samples, where N does not equal M, then a
framebuffer region containing all samples at a given (x, y, layer)
coordinate in the first synchronization scope corresponds to a region
containing all samples at the same coordinate in the second synchronization
scope.
In other words, the framebuffer region is a fragment region and it is a
pixel granularity dependency.
If N equals M,
and if the VkSubpassDescription
::flags
does not specify the
VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM
flag,
then a framebuffer region containing a single (x, y, layer, sample)
coordinate in the first synchronization scope corresponds to a region
containing the same sample at the same coordinate in the second
synchronization scope.
In other words, the framebuffer region is a sample region and it is a sample
granularity dependency.
Note
Since fragment invocations are not specified to run in any particular groupings, the size of a framebuffer region is implementation-dependent, not known to the application, and must be assumed to be no larger than specified above. |
Note
Practically, the pixel vs sample granularity dependency means that if an
input attachment has a different number of samples than the pipeline’s
|
If a synchronization command includes a dependencyFlags
parameter, and
specifies the VK_DEPENDENCY_BY_REGION_BIT
flag, then it defines
framebuffer-local dependencies for the framebuffer-space pipeline stages in
that synchronization command, for all framebuffer regions.
If no dependencyFlags
parameter is included, or the
VK_DEPENDENCY_BY_REGION_BIT
flag is not specified, then a
framebuffer-global dependency is specified for those stages.
The VK_DEPENDENCY_BY_REGION_BIT
flag does not affect the dependencies
between non-framebuffer-space pipeline stages, nor does it affect the
dependencies between framebuffer-space and non-framebuffer-space pipeline
stages.
Note
Framebuffer-local dependencies are more optimal for most architectures; particularly tile-based architectures - which can keep framebuffer-regions entirely in on-chip registers and thus avoid external bandwidth across such a dependency. Including a framebuffer-global dependency in your rendering will usually force all implementations to flush data to memory, or to a higher level cache, breaking any potential locality optimizations. |
6.1.5. View-Local Dependencies
In a render pass instance that has multiview enabled, dependencies can be either view-local or view-global.
A view-local dependency only includes operations from a single source view from the source subpass in the first synchronization scope, and only includes operations from a single destination view from the destination subpass in the second synchronization scope. A view-global dependency includes all views in the view mask of the source and destination subpasses in the corresponding synchronization scopes.
If a synchronization command includes a dependencyFlags
parameter and
specifies the VK_DEPENDENCY_VIEW_LOCAL_BIT
flag, then it defines
view-local dependencies for that synchronization command, for all views.
If no dependencyFlags
parameter is included or the
VK_DEPENDENCY_VIEW_LOCAL_BIT
flag is not specified, then a view-global
dependency is specified.
6.1.6. Device-Local Dependencies
Dependencies can be either device-local or non-device-local.
A device-local dependency acts as multiple separate dependencies, one for
each physical device that executes the synchronization command, where each
dependency only includes operations from that physical device in both
synchronization scopes.
A non-device-local dependency is a single dependency where both
synchronization scopes include operations from all physical devices that
participate in the synchronization command.
For subpass dependencies, all physical devices in the
VkDeviceGroupRenderPassBeginInfo::deviceMask
participate in the
dependency, and for pipeline barriers all physical devices that are set in
the command buffer’s current device mask participate in the dependency.
If a synchronization command includes a dependencyFlags
parameter and
specifies the VK_DEPENDENCY_DEVICE_GROUP_BIT
flag, then it defines a
non-device-local dependency for that synchronization command.
If no dependencyFlags
parameter is included or the
VK_DEPENDENCY_DEVICE_GROUP_BIT
flag is not specified, then it defines
device-local dependencies for that synchronization command, for all
participating physical devices.
Semaphore and event dependencies are device-local and only execute on the one physical device that performs the dependency.
6.2. Implicit Synchronization Guarantees
A small number of implicit ordering guarantees are provided by Vulkan, ensuring that the order in which commands are submitted is meaningful, and avoiding unnecessary complexity in common operations.
Submission order is a fundamental ordering in Vulkan, giving meaning to the order in which action and synchronization commands are recorded and submitted to a single queue. Explicit and implicit ordering guarantees between commands in Vulkan all work on the premise that this ordering is meaningful. This order does not itself define any execution or memory dependencies; synchronization commands and other orderings within the API use this ordering to define their scopes.
Submission order for any given set of commands is based on the order in which they were recorded to command buffers and then submitted. This order is determined as follows:
-
The initial order is determined by the order in which vkQueueSubmit commands are executed on the host, for a single queue, from first to last.
-
The order in which VkSubmitInfo structures are specified in the
pSubmits
parameter of vkQueueSubmit, from lowest index to highest. -
The order in which command buffers are specified in the
pCommandBuffers
member of VkSubmitInfo, from lowest index to highest. -
The order in which commands were recorded to a command buffer on the host, from first to last:
-
For commands recorded outside a render pass, this includes all other commands recorded outside a render pass, including vkCmdBeginRenderPass and vkCmdEndRenderPass commands; it does not directly include commands inside a render pass.
-
For commands recorded inside a render pass, this includes all other commands recorded inside the same subpass, including the vkCmdBeginRenderPass and vkCmdEndRenderPass commands that delimit the same render pass instance; it does not include commands recorded to other subpasses.
-
State commands do not execute any operations on the device, instead they set the state of the command buffer when they execute on the host, in the order that they are recorded. Action commands consume the current state of the command buffer when they are recorded, and will execute state changes on the device as required to match the recorded state.
Query commands, the order of primitives passing through the graphics pipeline and image layout transitions as part of an image memory barrier provide additional guarantees based on submission order.
Execution of pipeline stages within a given command also has a loose ordering, dependent only on a single command.
Signal operation order is a fundamental ordering in Vulkan, giving meaning to the order in which semaphore and fence signal operations occur when submitted to a single queue. The signal operation order for queue operations is determined as follows:
-
The initial order is determined by the order in which vkQueueSubmit commands are executed on the host, for a single queue, from first to last.
-
The order in which VkSubmitInfo structures are specified in the
pSubmits
parameter of vkQueueSubmit, from lowest index to highest. -
The fence signal operation defined by the
fence
parameter of a vkQueueSubmit or vkQueueBindSparse command is ordered after all semaphore signal operations defined by that command.
Semaphore signal operations defined by a single VkSubmitInfo or VkBindSparseInfo structure are unordered with respect to other semaphore signal operations defined within the same VkSubmitInfo or VkBindSparseInfo structure.
The vkSignalSemaphore command does not execute on a queue but instead performs the signal operation from the host. The semaphore signal operation defined by executing a vkSignalSemaphore command happens-after the vkSignalSemaphore command is invoked and happens-before the command returns.
Note
When signaling timeline semaphores, it is the responsibility of the application to ensure that they are ordered such that the semaphore value is strictly increasing. Because the first synchronization scope for a semaphore signal operation contains all semaphore signal operations which occur earlier in submission order, all semaphore signal operations contained in any given batch are guaranteed to happen-after all semaphore signal operations contained in any previous batches. However, no ordering guarantee is provided between the semaphore signal operations defined within a single batch. This, combined with the requirement that timeline semaphore values strictly increase, means that it is invalid to signal the same timeline semaphore twice within a single batch. If an application wishes to ensure that some semaphore signal operation happens-after some other semaphore signal operation, it can submit a separate batch containing only semaphore signal operations, which will happen-after the semaphore signal operations in any earlier batches. When signaling a semaphore from the host, the only ordering guarantee is
that the signal operation happens-after when vkSignalSemaphore is
called and happens-before it returns.
Therefore, it is invalid to call |
6.3. Fences
Fences are a synchronization primitive that can be used to insert a dependency from a queue to the host. Fences have two states - signaled and unsignaled. A fence can be signaled as part of the execution of a queue submission command. Fences can be unsignaled on the host with vkResetFences. Fences can be waited on by the host with the vkWaitForFences command, and the current state can be queried with vkGetFenceStatus.
As with most objects in Vulkan, fences are an interface to internal data which is typically opaque to applications. This internal data is referred to as a fence’s payload.
However, in order to enable communication with agents outside of the current device, it is necessary to be able to export that payload to a commonly understood format, and subsequently import from that format as well.
The internal data of a fence may include a reference to any resources and pending work associated with signal or unsignal operations performed on that fence object. Mechanisms to import and export that internal data to and from fences are provided below. These mechanisms indirectly enable applications to share fence state between two or more fences and other synchronization primitives across process and API boundaries.
Fences are represented by VkFence
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
To create a fence, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateFence(
VkDevice device,
const VkFenceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkFence* pFence);
-
device
is the logical device that creates the fence. -
pCreateInfo
is a pointer to a VkFenceCreateInfo structure containing information about how the fence is to be created. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pFence
is a pointer to a handle in which the resulting fence object is returned.
The VkFenceCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkFenceCreateInfo {
VkStructureType sType;
const void* pNext;
VkFenceCreateFlags flags;
} VkFenceCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkFenceCreateFlagBits specifying the initial state and behavior of the fence.
// Provided by VK_VERSION_1_0
typedef enum VkFenceCreateFlagBits {
VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
} VkFenceCreateFlagBits;
-
VK_FENCE_CREATE_SIGNALED_BIT
specifies that the fence object is created in the signaled state. Otherwise, it is created in the unsignaled state.
// Provided by VK_VERSION_1_0
typedef VkFlags VkFenceCreateFlags;
VkFenceCreateFlags
is a bitmask type for setting a mask of zero or
more VkFenceCreateFlagBits.
To create a fence whose payload can be exported to external handles, add a
VkExportFenceCreateInfo structure to the pNext
chain of the
VkFenceCreateInfo structure.
The VkExportFenceCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkExportFenceCreateInfo {
VkStructureType sType;
const void* pNext;
VkExternalFenceHandleTypeFlags handleTypes;
} VkExportFenceCreateInfo;
or the equivalent
// Provided by VK_KHR_external_fence
typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleTypes
is a bitmask of VkExternalFenceHandleTypeFlagBits specifying one or more fence handle types the application can export from the resulting fence. The application can request multiple handle types for the same fence.
To specify additional attributes of NT handles exported from a fence, add a
VkExportFenceWin32HandleInfoKHR structure to the pNext
chain of
the VkFenceCreateInfo structure.
The VkExportFenceWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_fence_win32
typedef struct VkExportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportFenceWin32HandleInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pAttributes
is a pointer to a WindowsSECURITY_ATTRIBUTES
structure specifying security attributes of the handle. -
dwAccess
is aDWORD
specifying access rights of the handle. -
name
is a null-terminated UTF-16 string to associate with the underlying synchronization primitive referenced by NT handles exported from the created fence.
If VkExportFenceCreateInfo is not present in the same pNext
chain, this structure is ignored.
If VkExportFenceCreateInfo is present in the pNext
chain of
VkFenceCreateInfo with a Windows handleType
, but either
VkExportFenceWin32HandleInfoKHR
is not present in the pNext
chain, or if it is but pAttributes
is set to NULL
, default security
descriptor values will be used, and child processes created by the
application will not inherit the handle, as described in the MSDN
documentation for “Synchronization Object Security and Access Rights”1.
Further, if the structure is not present, the access rights will be
DXGI_SHARED_RESOURCE_READ
| DXGI_SHARED_RESOURCE_WRITE
for handles of the following types:
VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
To export a Windows handle representing the state of a fence, call:
// Provided by VK_KHR_external_fence_win32
VkResult vkGetFenceWin32HandleKHR(
VkDevice device,
const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
-
device
is the logical device that created the fence being exported. -
pGetWin32HandleInfo
is a pointer to a VkFenceGetWin32HandleInfoKHR structure containing parameters of the export operation. -
pHandle
will return the Windows handle representing the fence state.
For handle types defined as NT handles, the handles returned by
vkGetFenceWin32HandleKHR
are owned by the application.
To avoid leaking resources, the application must release ownership of them
using the CloseHandle
system call when they are no longer needed.
Exporting a Windows handle from a fence may have side effects depending on the transference of the specified handle type, as described in Importing Fence Payloads.
The VkFenceGetWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_fence_win32
typedef struct VkFenceGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkExternalFenceHandleTypeFlagBits handleType;
} VkFenceGetWin32HandleInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
fence
is the fence from which state will be exported. -
handleType
is the type of handle requested.
The properties of the handle returned depend on the value of
handleType
.
See VkExternalFenceHandleTypeFlagBits for a description of the
properties of the defined external fence handle types.
To export a POSIX file descriptor representing the payload of a fence, call:
// Provided by VK_KHR_external_fence_fd
VkResult vkGetFenceFdKHR(
VkDevice device,
const VkFenceGetFdInfoKHR* pGetFdInfo,
int* pFd);
-
device
is the logical device that created the fence being exported. -
pGetFdInfo
is a pointer to a VkFenceGetFdInfoKHR structure containing parameters of the export operation. -
pFd
will return the file descriptor representing the fence payload.
Each call to vkGetFenceFdKHR
must create a new file descriptor and
transfer ownership of it to the application.
To avoid leaking resources, the application must release ownership of the
file descriptor when it is no longer needed.
Note
Ownership can be released in many ways.
For example, the application can call |
If pGetFdInfo->handleType
is
VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
and the fence is signaled at
the time vkGetFenceFdKHR
is called, pFd
may return the value
-1
instead of a valid file descriptor.
Where supported by the operating system, the implementation must set the
file descriptor to be closed automatically when an execve
system call
is made.
Exporting a file descriptor from a fence may have side effects depending on the transference of the specified handle type, as described in Importing Fence State.
The VkFenceGetFdInfoKHR
structure is defined as:
// Provided by VK_KHR_external_fence_fd
typedef struct VkFenceGetFdInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkExternalFenceHandleTypeFlagBits handleType;
} VkFenceGetFdInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
fence
is the fence from which state will be exported. -
handleType
is the type of handle requested.
The properties of the file descriptor returned depend on the value of
handleType
.
See VkExternalFenceHandleTypeFlagBits for a description of the
properties of the defined external fence handle types.
To destroy a fence, call:
// Provided by VK_VERSION_1_0
void vkDestroyFence(
VkDevice device,
VkFence fence,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that destroys the fence. -
fence
is the handle of the fence to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
To query the status of a fence from the host, call:
// Provided by VK_VERSION_1_0
VkResult vkGetFenceStatus(
VkDevice device,
VkFence fence);
-
device
is the logical device that owns the fence. -
fence
is the handle of the fence to query.
Upon success, vkGetFenceStatus
returns the status of the fence object,
with the following return codes:
Status | Meaning |
---|---|
|
The fence specified by |
|
The fence specified by |
|
The device has been lost. See Lost Device. |
If a queue submission command is pending execution, then the value returned by this command may immediately be out of date.
If the device has been lost (see Lost Device),
vkGetFenceStatus
may return any of the above status codes.
If the device has been lost and vkGetFenceStatus
is called repeatedly,
it will eventually return either VK_SUCCESS
or
VK_ERROR_DEVICE_LOST
.
To set the state of fences to unsignaled from the host, call:
// Provided by VK_VERSION_1_0
VkResult vkResetFences(
VkDevice device,
uint32_t fenceCount,
const VkFence* pFences);
-
device
is the logical device that owns the fences. -
fenceCount
is the number of fences to reset. -
pFences
is a pointer to an array of fence handles to reset.
If any member of pFences
currently has its
payload imported with temporary
permanence, that fence’s prior permanent payload is first restored.
The remaining operations described therefore operate on the restored
payload.
When vkResetFences is executed on the host, it defines a fence unsignal operation for each fence, which resets the fence to the unsignaled state.
If any member of pFences
is already in the unsignaled state when
vkResetFences is executed, then vkResetFences has no effect on
that fence.
When a fence is submitted to a queue as part of a queue submission command, it defines a memory dependency on the batches that were submitted as part of that command, and defines a fence signal operation which sets the fence to the signaled state.
The first synchronization scope includes every batch submitted in the same queue submission command. Fence signal operations that are defined by vkQueueSubmit additionally include in the first synchronization scope all commands that occur earlier in submission order. Fence signal operations that are defined by vkQueueSubmit or vkQueueBindSparse additionally include in the first synchronization scope any semaphore and fence signal operations that occur earlier in signal operation order.
The second synchronization scope only includes the fence signal operation.
The first access scope includes all memory access performed by the device.
The second access scope is empty.
To wait for one or more fences to enter the signaled state on the host, call:
// Provided by VK_VERSION_1_0
VkResult vkWaitForFences(
VkDevice device,
uint32_t fenceCount,
const VkFence* pFences,
VkBool32 waitAll,
uint64_t timeout);
-
device
is the logical device that owns the fences. -
fenceCount
is the number of fences to wait on. -
pFences
is a pointer to an array offenceCount
fence handles. -
waitAll
is the condition that must be satisfied to successfully unblock the wait. IfwaitAll
isVK_TRUE
, then the condition is that all fences inpFences
are signaled. Otherwise, the condition is that at least one fence inpFences
is signaled. -
timeout
is the timeout period in units of nanoseconds.timeout
is adjusted to the closest value allowed by the implementation-dependent timeout accuracy, which may be substantially longer than one nanosecond, and may be longer than the requested period.
If the condition is satisfied when vkWaitForFences
is called, then
vkWaitForFences
returns immediately.
If the condition is not satisfied at the time vkWaitForFences
is
called, then vkWaitForFences
will block and wait until the condition
is satisfied or the timeout
has expired, whichever is sooner.
If timeout
is zero, then vkWaitForFences
does not wait, but
simply returns the current state of the fences.
VK_TIMEOUT
will be returned in this case if the condition is not
satisfied, even though no actual wait was performed.
If the condition is satisfied before the timeout
has expired,
vkWaitForFences
returns VK_SUCCESS
.
Otherwise, vkWaitForFences
returns VK_TIMEOUT
after the
timeout
has expired.
If device loss occurs (see Lost Device) before
the timeout has expired, vkWaitForFences
must return in finite time
with either VK_SUCCESS
or VK_ERROR_DEVICE_LOST
.
Note
While we guarantee that |
An execution dependency is defined by waiting for a fence to become signaled, either via vkWaitForFences or by polling on vkGetFenceStatus.
The first synchronization scope includes only the fence signal operation.
The second synchronization scope includes the host operations of vkWaitForFences or vkGetFenceStatus indicating that the fence has become signaled.
Note
Signaling a fence and waiting on the host does not guarantee that the results of memory accesses will be visible to the host, as the access scope of a memory dependency defined by a fence only includes device access. A memory barrier or other memory dependency must be used to guarantee this. See the description of host access types for more information. |
6.3.1. Alternate Methods to Signal Fences
Besides submitting a fence to a queue as part of a queue submission command, a fence may also be signaled when a particular event occurs on a device or display.
To create a fence that will be signaled when an event occurs on a device, call:
// Provided by VK_EXT_display_control
VkResult vkRegisterDeviceEventEXT(
VkDevice device,
const VkDeviceEventInfoEXT* pDeviceEventInfo,
const VkAllocationCallbacks* pAllocator,
VkFence* pFence);
-
device
is a logical device on which the event may occur. -
pDeviceEventInfo
is a pointer to a VkDeviceEventInfoEXT structure describing the event of interest to the application. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pFence
is a pointer to a handle in which the resulting fence object is returned.
The VkDeviceEventInfoEXT
structure is defined as:
// Provided by VK_EXT_display_control
typedef struct VkDeviceEventInfoEXT {
VkStructureType sType;
const void* pNext;
VkDeviceEventTypeEXT deviceEvent;
} VkDeviceEventInfoEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
device
is a VkDeviceEventTypeEXT value specifying when the fence will be signaled.
Possible values of VkDeviceEventInfoEXT::device
, specifying when
a fence will be signaled, are:
// Provided by VK_EXT_display_control
typedef enum VkDeviceEventTypeEXT {
VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0,
} VkDeviceEventTypeEXT;
-
VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT
specifies that the fence is signaled when a display is plugged into or unplugged from the specified device. Applications can use this notification to determine when they need to re-enumerate the available displays on a device.
To create a fence that will be signaled when an event occurs on a VkDisplayKHR object, call:
// Provided by VK_EXT_display_control
VkResult vkRegisterDisplayEventEXT(
VkDevice device,
VkDisplayKHR display,
const VkDisplayEventInfoEXT* pDisplayEventInfo,
const VkAllocationCallbacks* pAllocator,
VkFence* pFence);
-
device
is a logical device associated withdisplay
-
display
is the display on which the event may occur. -
pDisplayEventInfo
is a pointer to a VkDisplayEventInfoEXT structure describing the event of interest to the application. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pFence
is a pointer to a handle in which the resulting fence object is returned.
The VkDisplayEventInfoEXT
structure is defined as:
// Provided by VK_EXT_display_control
typedef struct VkDisplayEventInfoEXT {
VkStructureType sType;
const void* pNext;
VkDisplayEventTypeEXT displayEvent;
} VkDisplayEventInfoEXT;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
displayEvent
is a VkDisplayEventTypeEXT specifying when the fence will be signaled.
Possible values of VkDisplayEventInfoEXT::displayEvent
,
specifying when a fence will be signaled, are:
// Provided by VK_EXT_display_control
typedef enum VkDisplayEventTypeEXT {
VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0,
} VkDisplayEventTypeEXT;
-
VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT
specifies that the fence is signaled when the first pixel of the next display refresh cycle leaves the display engine for the display.
6.3.2. Importing Fence Payloads
Applications can import a fence payload into an existing fence using an external fence handle. The effects of the import operation will be either temporary or permanent, as specified by the application. If the import is temporary, the fence will be restored to its permanent state the next time that fence is passed to vkResetFences.
Note
Restoring a fence to its prior permanent payload is a distinct operation from resetting a fence payload. See vkResetFences for more detail. |
Performing a subsequent temporary import on a fence before resetting it has
no effect on this requirement; the next unsignal of the fence must still
restore its last permanent state.
A permanent payload import behaves as if the target fence was destroyed, and
a new fence was created with the same handle but the imported payload.
Because importing a fence payload temporarily or permanently detaches the
existing payload from a fence, similar usage restrictions to those applied
to vkDestroyFence
are applied to any command that imports a fence
payload.
Which of these import types is used is referred to as the import operation’s
permanence.
Each handle type supports either one or both types of permanence.
The implementation must perform the import operation by either referencing or copying the payload referred to by the specified external fence handle, depending on the handle’s type. The import method used is referred to as the handle type’s transference. When using handle types with reference transference, importing a payload to a fence adds the fence to the set of all fences sharing that payload. This set includes the fence from which the payload was exported. Fence signaling, waiting, and resetting operations performed on any fence in the set must behave as if the set were a single fence. Importing a payload using handle types with copy transference creates a duplicate copy of the payload at the time of import, but makes no further reference to it. Fence signaling, waiting, and resetting operations performed on the target of copy imports must not affect any other fence or payload.
Export operations have the same transference as the specified handle type’s import operations. Additionally, exporting a fence payload to a handle with copy transference has the same side effects on the source fence’s payload as executing a fence reset operation. If the fence was using a temporarily imported payload, the fence’s prior permanent payload will be restored.
Note
The
tables
Handle Types Supported by
|
External synchronization allows
implementations to modify an object’s internal state, i.e. payload, without
internal synchronization.
However, for fences sharing a payload across processes, satisfying the
external synchronization requirements of VkFence
parameters as if all
fences in the set were the same object is sometimes infeasible.
Satisfying valid usage constraints on the state of a fence would similarly
require impractical coordination or levels of trust between processes.
Therefore, these constraints only apply to a specific fence handle, not to
its payload.
For distinct fence objects which share a payload:
-
If multiple commands which queue a signal operation, or which unsignal a fence, are called concurrently, behavior will be as if the commands were called in an arbitrary sequential order.
-
If a queue submission command is called with a fence that is sharing a payload, and the payload is already associated with another queue command that has not yet completed execution, either one or both of the commands will cause the fence to become signaled when they complete execution.
-
If a fence payload is reset while it is associated with a queue command that has not yet completed execution, the payload will become unsignaled, but may become signaled again when the command completes execution.
-
In the preceding cases, any of the devices associated with the fences sharing the payload may be lost, or any of the queue submission or fence reset commands may return
VK_ERROR_INITIALIZATION_FAILED
.
Other than these non-deterministic results, behavior is well defined. In particular:
-
The implementation must not crash or enter an internally inconsistent state where future valid Vulkan commands might cause undefined results,
-
Timeouts on future wait commands on fences sharing the payload must be effective.
Note
These rules allow processes to synchronize access to shared memory without trusting each other. However, such processes must still be cautious not to use the shared fence for more than synchronizing access to the shared memory. For example, a process should not use a fence with shared payload to tell when commands it submitted to a queue have completed and objects used by those commands may be destroyed, since the other process can accidentally or maliciously cause the fence to signal before the commands actually complete. |
When a fence is using an imported payload, its
VkExportFenceCreateInfo::handleTypes
value is that specified
when creating the fence from which the payload was exported, rather than
that specified when creating the fence.
Additionally,
VkExternalFenceProperties::exportFromImportedHandleTypes
restricts which handle types can be exported from such a fence based on the
specific handle type used to import the current payload.
Passing a fence to vkAcquireNextImageKHR is equivalent to temporarily
importing a fence payload to that fence.
Note
Because the exportable handle types of an imported fence correspond to its current imported payload, and vkAcquireNextImageKHR behaves the same as a temporary import operation for which the source fence is opaque to the application, applications have no way of determining whether any external handle types can be exported from a fence in this state. Therefore, applications must not attempt to export handles from fences using a temporarily imported payload from vkAcquireNextImageKHR. |
When importing a fence payload, it is the responsibility of the application
to ensure the external handles meet all valid usage requirements.
However, implementations must perform sufficient validation of external
handles to ensure that the operation results in a valid fence which will not
cause program termination, device loss, queue stalls, host thread stalls, or
corruption of other resources when used as allowed according to its import
parameters.
If the external handle provided does not meet these requirements, the
implementation must fail the fence payload import operation with the error
code VK_ERROR_INVALID_EXTERNAL_HANDLE
.
To import a fence payload from a Windows handle, call:
// Provided by VK_KHR_external_fence_win32
VkResult vkImportFenceWin32HandleKHR(
VkDevice device,
const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
-
device
is the logical device that created the fence. -
pImportFenceWin32HandleInfo
is a pointer to a VkImportFenceWin32HandleInfoKHR structure specifying the fence and import parameters.
Importing a fence payload from Windows handles does not transfer ownership
of the handle to the Vulkan implementation.
For handle types defined as NT handles, the application must release
ownership using the CloseHandle
system call when the handle is no
longer needed.
Applications can import the same fence payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.
The VkImportFenceWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_fence_win32
typedef struct VkImportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkFenceImportFlags flags;
VkExternalFenceHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportFenceWin32HandleInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
fence
is the fence into which the state will be imported. -
flags
is a bitmask of VkFenceImportFlagBits specifying additional parameters for the fence payload import operation. -
handleType
specifies the type ofhandle
. -
handle
is the external handle to import, orNULL
. -
name
is a null-terminated UTF-16 string naming the underlying synchronization primitive to import, orNULL
.
The handle types supported by handleType
are:
Handle Type | Transference | Permanence Supported |
---|---|---|
|
Reference |
Temporary,Permanent |
|
Reference |
Temporary,Permanent |
To import a fence payload from a POSIX file descriptor, call:
// Provided by VK_KHR_external_fence_fd
VkResult vkImportFenceFdKHR(
VkDevice device,
const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
-
device
is the logical device that created the fence. -
pImportFenceFdInfo
is a pointer to a VkImportFenceFdInfoKHR structure specifying the fence and import parameters.
Importing a fence payload from a file descriptor transfers ownership of the file descriptor from the application to the Vulkan implementation. The application must not perform any operations on the file descriptor after a successful import.
Applications can import the same fence payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.
The VkImportFenceFdInfoKHR
structure is defined as:
// Provided by VK_KHR_external_fence_fd
typedef struct VkImportFenceFdInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkFenceImportFlags flags;
VkExternalFenceHandleTypeFlagBits handleType;
int fd;
} VkImportFenceFdInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
fence
is the fence into which the payload will be imported. -
flags
is a bitmask of VkFenceImportFlagBits specifying additional parameters for the fence payload import operation. -
handleType
specifies the type offd
. -
fd
is the external handle to import.
The handle types supported by handleType
are:
Handle Type | Transference | Permanence Supported |
---|---|---|
|
Reference |
Temporary,Permanent |
|
Copy |
Temporary |
If handleType
is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
, the
special value -1
for fd
is treated like a valid sync file descriptor
referring to an object that has already signaled.
The import operation will succeed and the VkFence
will have a
temporarily imported payload as if a valid file descriptor had been
provided.
Note
This special behavior for importing an invalid sync file descriptor allows
easier interoperability with other system APIs which use the convention that
an invalid sync file descriptor represents work that has already completed
and does not need to be waited for.
It is consistent with the option for implementations to return a |
Bits which can be set in
VkImportFenceWin32HandleInfoKHR::flags
and
VkImportFenceFdInfoKHR::flags
specifying additional parameters of a fence import operation are:
// Provided by VK_VERSION_1_1
typedef enum VkFenceImportFlagBits {
VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001,
// Provided by VK_KHR_external_fence
VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = VK_FENCE_IMPORT_TEMPORARY_BIT,
} VkFenceImportFlagBits;
or the equivalent
// Provided by VK_KHR_external_fence
typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR;
-
VK_FENCE_IMPORT_TEMPORARY_BIT
specifies that the fence payload will be imported only temporarily, as described in Importing Fence Payloads, regardless of the permanence ofhandleType
.
// Provided by VK_VERSION_1_1
typedef VkFlags VkFenceImportFlags;
or the equivalent
// Provided by VK_KHR_external_fence
typedef VkFenceImportFlags VkFenceImportFlagsKHR;
VkFenceImportFlags
is a bitmask type for setting a mask of zero or
more VkFenceImportFlagBits.
6.4. Semaphores
Semaphores are a synchronization primitive that can be used to insert a dependency between queue operations or between a queue operation and the host. Binary semaphores have two states - signaled and unsignaled. Timeline semaphores have a monotonically increasing 64-bit unsigned integer payload and are signaled with respect to a particular reference value. A semaphore can be signaled after execution of a queue operation is completed, and a queue operation can wait for a semaphore to become signaled before it begins execution. A timeline semaphore can additionally be signaled from the host with the vkSignalSemaphore command and waited on from the host with the vkWaitSemaphores command.
As with most objects in Vulkan, semaphores are an interface to internal data which is typically opaque to applications. This internal data is referred to as a semaphore’s payload.
However, in order to enable communication with agents outside of the current device, it is necessary to be able to export that payload to a commonly understood format, and subsequently import from that format as well.
The internal data of a semaphore may include a reference to any resources and pending work associated with signal or unsignal operations performed on that semaphore object. Mechanisms to import and export that internal data to and from semaphores are provided below. These mechanisms indirectly enable applications to share semaphore state between two or more semaphores and other synchronization primitives across process and API boundaries.
Semaphores are represented by VkSemaphore
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
To create a semaphore, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateSemaphore(
VkDevice device,
const VkSemaphoreCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSemaphore* pSemaphore);
-
device
is the logical device that creates the semaphore. -
pCreateInfo
is a pointer to a VkSemaphoreCreateInfo structure containing information about how the semaphore is to be created. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pSemaphore
is a pointer to a handle in which the resulting semaphore object is returned.
The VkSemaphoreCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkSemaphoreCreateInfo {
VkStructureType sType;
const void* pNext;
VkSemaphoreCreateFlags flags;
} VkSemaphoreCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use.
// Provided by VK_VERSION_1_0
typedef VkFlags VkSemaphoreCreateFlags;
VkSemaphoreCreateFlags
is a bitmask type for setting a mask, but is
currently reserved for future use.
To create a semaphore of a specific type, add a
VkSemaphoreTypeCreateInfo structure to the pNext
chain of the
VkSemaphoreCreateInfo structure.
The VkSemaphoreTypeCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkSemaphoreTypeCreateInfo {
VkStructureType sType;
const void* pNext;
VkSemaphoreType semaphoreType;
uint64_t initialValue;
} VkSemaphoreTypeCreateInfo;
or the equivalent
// Provided by VK_KHR_timeline_semaphore
typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
semaphoreType
is a VkSemaphoreType value specifying the type of the semaphore. -
initialValue
is the initial payload value ifsemaphoreType
isVK_SEMAPHORE_TYPE_TIMELINE
.
If no VkSemaphoreTypeCreateInfo
structure is included in the
pNext
chain of VkSemaphoreCreateInfo, then the created semaphore
will have a default VkSemaphoreType of VK_SEMAPHORE_TYPE_BINARY
.
Possible values of VkSemaphoreTypeCreateInfo::semaphoreType
,
specifying the type of a semaphore, are:
// Provided by VK_VERSION_1_2
typedef enum VkSemaphoreType {
VK_SEMAPHORE_TYPE_BINARY = 0,
VK_SEMAPHORE_TYPE_TIMELINE = 1,
// Provided by VK_KHR_timeline_semaphore
VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY,
// Provided by VK_KHR_timeline_semaphore
VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE,
} VkSemaphoreType;
or the equivalent
// Provided by VK_KHR_timeline_semaphore
typedef VkSemaphoreType VkSemaphoreTypeKHR;
-
VK_SEMAPHORE_TYPE_BINARY
specifies a binary semaphore type that has a boolean payload indicating whether the semaphore is currently signaled or unsignaled. When created, the semaphore is in the unsignaled state. -
VK_SEMAPHORE_TYPE_TIMELINE
specifies a timeline semaphore type that has a monotonically increasing 64-bit unsigned integer payload indicating whether the semaphore is signaled with respect to a particular reference value. When created, the semaphore payload has the value given by theinitialValue
field of VkSemaphoreTypeCreateInfo.
To create a semaphore whose payload can be exported to external handles,
add a VkExportSemaphoreCreateInfo structure to the pNext
chain
of the VkSemaphoreCreateInfo structure.
The VkExportSemaphoreCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkExportSemaphoreCreateInfo {
VkStructureType sType;
const void* pNext;
VkExternalSemaphoreHandleTypeFlags handleTypes;
} VkExportSemaphoreCreateInfo;
or the equivalent
// Provided by VK_KHR_external_semaphore
typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleTypes
is a bitmask of VkExternalSemaphoreHandleTypeFlagBits specifying one or more semaphore handle types the application can export from the resulting semaphore. The application can request multiple handle types for the same semaphore.
To specify additional attributes of NT handles exported from a semaphore,
add a VkExportSemaphoreWin32HandleInfoKHR
structure to the pNext
chain of the VkSemaphoreCreateInfo structure.
The VkExportSemaphoreWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_semaphore_win32
typedef struct VkExportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportSemaphoreWin32HandleInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pAttributes
is a pointer to a WindowsSECURITY_ATTRIBUTES
structure specifying security attributes of the handle. -
dwAccess
is aDWORD
specifying access rights of the handle. -
name
is a null-terminated UTF-16 string to associate with the underlying synchronization primitive referenced by NT handles exported from the created semaphore.
If VkExportSemaphoreCreateInfo is not present in the same pNext
chain, this structure is ignored.
If VkExportSemaphoreCreateInfo is present in the pNext
chain of
VkSemaphoreCreateInfo with a Windows handleType
, but either
VkExportSemaphoreWin32HandleInfoKHR
is not present in the pNext
chain, or if it is but pAttributes
is set to NULL
, default security
descriptor values will be used, and child processes created by the
application will not inherit the handle, as described in the MSDN
documentation for “Synchronization Object Security and Access Rights”1.
Further, if the structure is not present, the access rights used depend on
the handle type.
For handles of the following types:
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
The implementation must ensure the access rights allow both signal and wait operations on the semaphore.
For handles of the following types:
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT
The access rights must be:
GENERIC_ALL
To export a Windows handle representing the payload of a semaphore, call:
// Provided by VK_KHR_external_semaphore_win32
VkResult vkGetSemaphoreWin32HandleKHR(
VkDevice device,
const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
-
device
is the logical device that created the semaphore being exported. -
pGetWin32HandleInfo
is a pointer to a VkSemaphoreGetWin32HandleInfoKHR structure containing parameters of the export operation. -
pHandle
will return the Windows handle representing the semaphore state.
For handle types defined as NT handles, the handles returned by
vkGetSemaphoreWin32HandleKHR
are owned by the application.
To avoid leaking resources, the application must release ownership of them
using the CloseHandle
system call when they are no longer needed.
Exporting a Windows handle from a semaphore may have side effects depending on the transference of the specified handle type, as described in Importing Semaphore Payloads.
The VkSemaphoreGetWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_semaphore_win32
typedef struct VkSemaphoreGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetWin32HandleInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
semaphore
is the semaphore from which state will be exported. -
handleType
is the type of handle requested.
The properties of the handle returned depend on the value of
handleType
.
See VkExternalSemaphoreHandleTypeFlagBits for a description of the
properties of the defined external semaphore handle types.
To export a POSIX file descriptor representing the payload of a semaphore, call:
// Provided by VK_KHR_external_semaphore_fd
VkResult vkGetSemaphoreFdKHR(
VkDevice device,
const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
int* pFd);
-
device
is the logical device that created the semaphore being exported. -
pGetFdInfo
is a pointer to a VkSemaphoreGetFdInfoKHR structure containing parameters of the export operation. -
pFd
will return the file descriptor representing the semaphore payload.
Each call to vkGetSemaphoreFdKHR
must create a new file descriptor
and transfer ownership of it to the application.
To avoid leaking resources, the application must release ownership of the
file descriptor when it is no longer needed.
Note
Ownership can be released in many ways.
For example, the application can call |
Where supported by the operating system, the implementation must set the
file descriptor to be closed automatically when an execve
system call
is made.
Exporting a file descriptor from a semaphore may have side effects depending on the transference of the specified handle type, as described in Importing Semaphore State.
The VkSemaphoreGetFdInfoKHR
structure is defined as:
// Provided by VK_KHR_external_semaphore_fd
typedef struct VkSemaphoreGetFdInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetFdInfoKHR;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
semaphore
is the semaphore from which state will be exported. -
handleType
is the type of handle requested.
The properties of the file descriptor returned depend on the value of
handleType
.
See VkExternalSemaphoreHandleTypeFlagBits for a description of the
properties of the defined external semaphore handle types.
To destroy a semaphore, call:
// Provided by VK_VERSION_1_0
void vkDestroySemaphore(
VkDevice device,
VkSemaphore semaphore,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that destroys the semaphore. -
semaphore
is the handle of the semaphore to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
6.4.1. Semaphore Signaling
When a batch is submitted to a queue via a queue submission, and it includes semaphores to be signaled, it defines a memory dependency on the batch, and defines semaphore signal operations which set the semaphores to the signaled state.
In case of semaphores created with a VkSemaphoreType of
VK_SEMAPHORE_TYPE_TIMELINE
the semaphore is considered signaled with
respect to the counter value set to be signaled as specified in
VkTimelineSemaphoreSubmitInfo or VkSemaphoreSignalInfo.
The first synchronization scope includes every command submitted in the same batch. Semaphore signal operations that are defined by vkQueueSubmit additionally include all commands that occur earlier in submission order. Semaphore signal operations that are defined by vkQueueSubmit or vkQueueBindSparse additionally include in the first synchronization scope any semaphore and fence signal operations that occur earlier in signal operation order.
The second synchronization scope includes only the semaphore signal operation.
The first access scope includes all memory access performed by the device.
The second access scope is empty.
6.4.2. Semaphore Waiting
When a batch is submitted to a queue via a queue submission, and it includes semaphores to be waited on, it defines a memory dependency between prior semaphore signal operations and the batch, and defines semaphore wait operations.
Such semaphore wait operations set the semaphores
created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_BINARY
to the unsignaled state.
In case of semaphores created with a VkSemaphoreType of
VK_SEMAPHORE_TYPE_TIMELINE
a prior semaphore signal operation defines
a memory dependency with a semaphore wait operation if the value the
semaphore is signaled with is greater than or equal to the value the
semaphore is waited with, thus the semaphore will continue to be considered
signaled with respect to the counter value waited on as specified in
VkTimelineSemaphoreSubmitInfo.
The first synchronization scope includes all semaphore signal operations that operate on semaphores waited on in the same batch, and that happen-before the wait completes.
The second synchronization scope
includes every command submitted in the same batch.
In the case of vkQueueSubmit, the second synchronization scope is
limited to operations on the pipeline stages determined by the
destination stage mask specified
by the corresponding element of pWaitDstStageMask
.
Also, in the case of vkQueueSubmit, the second synchronization scope
additionally includes all commands that occur later in
submission order.
The first access scope is empty.
The second access scope includes all memory access performed by the device.
The semaphore wait operation happens-after the first set of operations in the execution dependency, and happens-before the second set of operations in the execution dependency.
Note
Unlike timeline semaphores, fences or events, the act of waiting for a binary semaphore also unsignals that semaphore. Applications must ensure that between two such wait operations, the semaphore is signaled again, with execution dependencies used to ensure these occur in order. Binary semaphore waits and signals should thus occur in discrete 1:1 pairs. |
Note
A common scenario for using If an image layout transition needs to be performed on a presentable image
before it is used in a framebuffer, that can be performed as the first
operation submitted to the queue after acquiring the image, and should not
prevent other work from overlapping with the presentation operation.
For example, a
|