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, and does
not allow one application to access data belonging to another application.
Applications can request stronger robustness guarantees by enabling the
robustBufferAccess
feature as described in Chapter 31, Features, Limits, and Formats.
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.
Valid usage defines a set of conditions which must be met in order to achieve well-defined run-time 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 run-time 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.
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.
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:
The reserved handle VK_NULL_HANDLE
can be passed in place of valid
object handles when explicitly called out in the specification.
Any command that creates an object successfully must not return
VK_NULL_HANDLE
.
It is valid to pass VK_NULL_HANDLE
to any vkDestroy*
or
vkFree*
command, which will silently ignore these values.
Any parameter that is a pointer must be a valid pointer. 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.
Any parameter of an enumerated type must be a valid enumerant for that type. A enumerant is valid if:
_BEGIN_RANGE
,
_END_RANGE
, _RANGE_SIZE
or _MAX_ENUM
.
A collection of flags is represented by a bitmask using the type
VkFlags
:
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.
These aliases are described in the Flag Types appendix
of the Specification.
Any Vk*Flags
member or parameter used in the API 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:
Vk*FlagBits
type, where the
bits type is obtained by taking the flag type and replacing the trailing
Flags
with FlagBits
.
For example, a flag value of type VkColorComponentFlags
must
contain only bit flags defined by VkColorComponentFlagBits
.
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.
As a general rule, the name of this value is obtained by taking the
structure name, 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
must have a
sType
value of VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
.
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.
The list of supported structure types is defined in an appendix.
Any parameter that is a structure containing a void*
pNext
member
must have a value of pNext
that is either NULL
, or points to a
valid structure defined by an extension, containing sType
and
pNext
members as described in the Vulkan Documentation and Extensions document in the section “Extension
Interactions”.
If that extension is supported by the implementation, then it must be
enabled.
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 chained structures with sType
values not defined by extensions supported by that component.
Extension structures are not described in the base Vulkan specification, but either in layered specifications incorporating those extensions, or in separate vendor-provided documents.
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.
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:
All return codes in Vulkan are reported via VkResult
return values.
The possible codes are:
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_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, VK_ERROR_OUT_OF_DATE_KHR = -1000001004, VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, } VkResult;
Success Codes
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.
Error codes
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 requested pool allocation has failed
due to fragmentation of the pool’s memory.
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.
If a command returns a run time error, it will leave any result pointers unmodified, unless other behavior is explicitly defined in the specification.
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.
Performance-critical commands generally do not have return codes.
If a run time error occurs in such commands, the implementation will defer
reporting the error until a specified point.
For commands that record into command buffers (vkCmd*
) run time errors
are reported by vkEndCommandBuffer
.