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:
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:
VkResult vkEnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices);
-
instanceis a handle to a Vulkan instance previously created with vkCreateInstance. -
pPhysicalDeviceCountis a pointer to an integer related to the number of physical devices available or queried, as described below. -
pPhysicalDevicesis eitherNULLor a pointer to an array ofVkPhysicalDevicehandles.
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:
void vkGetPhysicalDeviceProperties(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties* pProperties);
-
physicalDeviceis the handle to the physical device whose properties will be queried. -
pPropertiespoints to an instance of the VkPhysicalDeviceProperties structure, that will be filled with returned information.
The VkPhysicalDeviceProperties structure is defined as:
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;
-
apiVersionis the version of Vulkan supported by the device, encoded as described in Version Numbers. -
driverVersionis the vendor-specified version of the driver. -
vendorIDis a unique identifier for the vendor (see below) of the physical device. -
deviceIDis a unique identifier for the physical device among devices available from the vendor. -
deviceTypeis a VkPhysicalDeviceType specifying the type of device. -
deviceNameis a null-terminated UTF-8 string containing the name of the device. -
pipelineCacheUUIDis an array of sizeVK_UUID_SIZE, containing 8-bit values that represent a universally unique identifier for the device. -
limitsis the VkPhysicalDeviceLimits structure which specifies device-specific limits of the physical device. See Limits for details. -
sparsePropertiesis the VkPhysicalDeviceSparseProperties structure which specifies 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:
typedef enum VkVendorId {
VK_VENDOR_ID_VIV = 0x10001,
VK_VENDOR_ID_VSI = 0x10002,
VK_VENDOR_ID_KAZAN = 0x10003,
VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
} 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:
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,
VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
} 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:
void vkGetPhysicalDeviceProperties2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2* pProperties);
or the equivalent command
void vkGetPhysicalDeviceProperties2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2* pProperties);
-
physicalDeviceis the handle to the physical device whose properties will be queried. -
pPropertiespoints to an instance of the VkPhysicalDeviceProperties2 structure, that will be filled with returned information.
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:
typedef struct VkPhysicalDeviceProperties2 {
VkStructureType sType;
void* pNext;
VkPhysicalDeviceProperties properties;
} VkPhysicalDeviceProperties2;
or the equivalent
typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
propertiesis a structure of type VkPhysicalDeviceProperties describing the 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 UUID and LUID of a device, add
VkPhysicalDeviceIDProperties to the pNext chain of the
VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceIDProperties structure is defined as:
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
typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
deviceUUIDis an array of sizeVK_UUID_SIZE, containing 8-bit values that represent a universally unique identifier for the device. -
driverUUIDis an array of sizeVK_UUID_SIZE, containing 8-bit values that represent a universally unique identifier for the driver build in use by the device. -
deviceLUIDis an array of sizeVK_LUID_SIZE, containing 8-bit values that represent a locally unique identifier for the device. -
deviceNodeMaskis a bitfield identifying the node within a linked device adapter corresponding to the device. -
deviceLUIDValidis a boolean value that will beVK_TRUEifdeviceLUIDcontains a valid LUID anddeviceNodeMaskcontains a valid node mask, andVK_FALSEif 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:: |
|
Note
While VkPhysicalDeviceIDProperties:: |
To query the properties of the driver corresponding to a physical device,
add VkPhysicalDeviceDriverPropertiesKHR to the pNext chain of
the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDeviceDriverPropertiesKHR structure is defined as:
typedef struct VkPhysicalDeviceDriverPropertiesKHR {
VkStructureType sType;
void* pNext;
VkDriverIdKHR driverID;
char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
VkConformanceVersionKHR conformanceVersion;
} VkPhysicalDeviceDriverPropertiesKHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension specific structure. -
driverIDis a unique identifier for the driver of the physical device. -
driverNameis a null-terminated UTF-8 string containing the name of the driver. -
driverInfois a null-terminated UTF-8 string containing additional information about the driver. -
conformanceVersionis the version of the Vulkan conformance test this driver is conformant against (see VkConformanceVersionKHR).
driverID must be immutable for a given driver across instances,
processes, driver versions, and system reboots.
Khronos driver IDs which may be returned in
VkPhysicalDeviceDriverPropertiesKHR::driverID are:
typedef enum VkDriverIdKHR {
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1,
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2,
VK_DRIVER_ID_MESA_RADV_KHR = 3,
VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4,
VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5,
VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6,
VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = 10,
VK_DRIVER_ID_GGP_PROPRIETARY_KHR = 11,
VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = 12,
VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF
} 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 an instance of the VkConformanceVersionKHR structure.
The VkConformanceVersionKHR structure is defined as:
typedef struct VkConformanceVersionKHR {
uint8_t major;
uint8_t minor;
uint8_t subminor;
uint8_t patch;
} VkConformanceVersionKHR;
-
majoris the major version number of the conformance test suite. -
minoris the minor version number of the conformance test suite. -
subminoris the subminor version number of the conformance test suite. -
patchis the patch version number of the conformance test suite.
To query the PCI bus information of a physical device, add
VkPhysicalDevicePCIBusInfoPropertiesEXT to the pNext chain of
the VkPhysicalDeviceProperties2 structure.
The VkPhysicalDevicePCIBusInfoPropertiesEXT structure is defined as:
typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT {
VkStructureType sType;
void* pNext;
uint32_t pciDomain;
uint32_t pciBus;
uint32_t pciDevice;
uint32_t pciFunction;
} VkPhysicalDevicePCIBusInfoPropertiesEXT;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
pciDomainis the PCI bus domain. -
pciBusis the PCI bus identifier. -
pciDeviceis the PCI device identifier. -
pciFunctionis the PCI device function identifier.
To query properties of queues available on a physical device, call:
void vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties);
-
physicalDeviceis the handle to the physical device whose properties will be queried. -
pQueueFamilyPropertyCountis a pointer to an integer related to the number of queue families available or queried, as described below. -
pQueueFamilyPropertiesis eitherNULLor 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:
typedef struct VkQueueFamilyProperties {
VkQueueFlags queueFlags;
uint32_t queueCount;
uint32_t timestampValidBits;
VkExtent3D minImageTransferGranularity;
} VkQueueFamilyProperties;
-
queueFlagsis a bitmask of VkQueueFlagBits indicating capabilities of the queues in this queue family. -
queueCountis the unsigned integer count of queues in this queue family. Each queue family must support at least one queue. -
timestampValidBitsis 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. -
minImageTransferGranularityis 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, andzmembers of a VkOffset3D parameter must always be zero. -
The
width,height, anddepthmembers 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, andzof a VkOffset3D parameter must be integer multiples of Ax, Ay, and Az, respectively. -
widthof a VkExtent3D parameter must be an integer multiple of Ax, or elsex+widthmust equal the width of the image subresource corresponding to the parameter. -
heightof a VkExtent3D parameter must be an integer multiple of Ay, or elsey+heightmust equal the height of the image subresource corresponding to the parameter. -
depthof a VkExtent3D parameter must be an integer multiple of Az, or elsez+depthmust 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:
typedef enum VkQueueFlagBits {
VK_QUEUE_GRAPHICS_BIT = 0x00000001,
VK_QUEUE_COMPUTE_BIT = 0x00000002,
VK_QUEUE_TRANSFER_BIT = 0x00000004,
VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
VK_QUEUE_PROTECTED_BIT = 0x00000010,
VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkQueueFlagBits;
-
VK_QUEUE_GRAPHICS_BITspecifies that queues in this queue family support graphics operations. -
VK_QUEUE_COMPUTE_BITspecifies that queues in this queue family support compute operations. -
VK_QUEUE_TRANSFER_BITspecifies that queues in this queue family support transfer operations. -
VK_QUEUE_SPARSE_BINDING_BITspecifies 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_BITis set, then the queues in this queue family support theVK_DEVICE_QUEUE_CREATE_PROTECTED_BITbit. (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.
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:
void vkGetPhysicalDeviceQueueFamilyProperties2(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2* pQueueFamilyProperties);
or the equivalent command
void vkGetPhysicalDeviceQueueFamilyProperties2KHR(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2* pQueueFamilyProperties);
-
physicalDeviceis the handle to the physical device whose properties will be queried. -
pQueueFamilyPropertyCountis a pointer to an integer related to the number of queue families available or queried, as described in vkGetPhysicalDeviceQueueFamilyProperties. -
pQueueFamilyPropertiesis eitherNULLor 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:
typedef struct VkQueueFamilyProperties2 {
VkStructureType sType;
void* pNext;
VkQueueFamilyProperties queueFamilyProperties;
} VkQueueFamilyProperties2;
or the equivalent
typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
queueFamilyPropertiesis a structure of type VkQueueFamilyProperties which is populated with the same values as in vkGetPhysicalDeviceQueueFamilyProperties.
Additional queue family information can be queried by setting
VkQueueFamilyProperties2::pNext to point to an instance of the
VkQueueFamilyCheckpointPropertiesNV structure.
The VkQueueFamilyCheckpointPropertiesNV structure is defined as:
typedef struct VkQueueFamilyCheckpointPropertiesNV {
VkStructureType sType;
void* pNext;
VkPipelineStageFlags checkpointExecutionStageMask;
} VkQueueFamilyCheckpointPropertiesNV;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
checkpointExecutionStageMaskis a mask indicating which pipeline stages the implementation can execute checkpoint markers in.
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:
VkResult vkEnumeratePhysicalDeviceGroups(
VkInstance instance,
uint32_t* pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
or the equivalent command
VkResult vkEnumeratePhysicalDeviceGroupsKHR(
VkInstance instance,
uint32_t* pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
-
instanceis a handle to a Vulkan instance previously created with vkCreateInstance. -
pPhysicalDeviceGroupCountis a pointer to an integer related to the number of device groups available or queried, as described below. -
pPhysicalDeviceGroupPropertiesis eitherNULLor 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:
typedef struct VkPhysicalDeviceGroupProperties {
VkStructureType sType;
void* pNext;
uint32_t physicalDeviceCount;
VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE];
VkBool32 subsetAllocation;
} VkPhysicalDeviceGroupProperties;
or the equivalent
typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
physicalDeviceCountis the number of physical devices in the group. -
physicalDevicesis an array of physical device handles representing all physical devices in the group. The firstphysicalDeviceCountelements of the array will be valid. -
subsetAllocationspecifies whether logical devices created from the group support allocating device memory on a subset of devices, via thedeviceMaskmember of the VkMemoryAllocateFlagsInfo. If this isVK_FALSE, then all device memory allocations are made across all physical devices in the group. IfphysicalDeviceCountis1, thensubsetAllocationmust beVK_FALSE.
4.2.1. Device Creation
Logical devices are represented by VkDevice handles:
VK_DEFINE_HANDLE(VkDevice)
A logical device is created as a connection to a physical device. To create a logical device, call:
VkResult vkCreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
-
physicalDevicemust be one of the device handles returned from a call tovkEnumeratePhysicalDevices(see Physical Device Enumeration). -
pCreateInfois a pointer to a VkDeviceCreateInfo structure containing information about how to create the device. -
pAllocatorcontrols host memory allocation as described in the Memory Allocation chapter. -
pDevicepoints 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:
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;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
flagsis reserved for future use. -
queueCreateInfoCountis the unsigned integer size of thepQueueCreateInfosarray. Refer to the Queue Creation section below for further details. -
pQueueCreateInfosis 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. -
enabledLayerCountis deprecated and ignored. -
ppEnabledLayerNamesis deprecated and ignored. See Device Layer Deprecation. -
enabledExtensionCountis the number of device extensions to enable. -
ppEnabledExtensionNamesis a pointer to an array ofenabledExtensionCountnull-terminated UTF-8 strings containing the names of extensions to enable for the created device. See the Extensions section for further details. -
pEnabledFeaturesisNULLor a pointer to a VkPhysicalDeviceFeatures structure that contains boolean indicators of all the features to be enabled. Refer to the Features section for further details.
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 including a VkDeviceGroupDeviceCreateInfo structure in the
pNext chain of VkDeviceCreateInfo.
The VkDeviceGroupDeviceCreateInfo structure is defined as:
typedef struct VkDeviceGroupDeviceCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t physicalDeviceCount;
const VkPhysicalDevice* pPhysicalDevices;
} VkDeviceGroupDeviceCreateInfo;
or the equivalent
typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
physicalDeviceCountis the number of elements in thepPhysicalDevicesarray. -
pPhysicalDevicesis 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.
typedef struct VkDeviceMemoryOverallocationCreateInfoAMD {
VkStructureType sType;
const void* pNext;
VkMemoryOverallocationBehaviorAMD overallocationBehavior;
} VkDeviceMemoryOverallocationCreateInfoAMD;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
overallocationBehavioris the desired overallocation behavior.
Possible values for VkDeviceMemoryOverallocationCreateInfoAMD::overallocationBehavior include:
typedef enum VkMemoryOverallocationBehaviorAMD {
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0,
VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1,
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2,
VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF
} VkMemoryOverallocationBehaviorAMD;
-
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMDlets the implementation decide if overallocation should be allowed. -
VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMDspecifies overallocation is allowed if platform permits. -
VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMDspecifies 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.
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
(see Error Codes for a list of such commands).
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 run-time 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.
4.2.4. Device Destruction
To destroy a device, call:
void vkDestroyDevice(
VkDevice device,
const VkAllocationCallbacks* pAllocator);
-
deviceis the logical device to destroy. -
pAllocatorcontrols 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:
VK_DEFINE_HANDLE(VkQueue)
The VkDeviceQueueCreateInfo structure is defined as:
typedef struct VkDeviceQueueCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueCount;
const float* pQueuePriorities;
} VkDeviceQueueCreateInfo;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
flagsis a bitmask indicating behavior of the queue. -
queueFamilyIndexis 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 thepQueueFamilyPropertiesarray that was returned byvkGetPhysicalDeviceQueueFamilyProperties. -
queueCountis an unsigned integer specifying the number of queues to create in the queue family indicated byqueueFamilyIndex. -
pQueuePrioritiesis an array ofqueueCountnormalized 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:
typedef enum VkDeviceQueueCreateFlagBits {
VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001,
VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkDeviceQueueCreateFlagBits;
-
VK_DEVICE_QUEUE_CREATE_PROTECTED_BITspecifies that the device queue is a protected-capable queue. If the protected memory feature is not enabled, theVK_DEVICE_QUEUE_CREATE_PROTECTED_BITbit offlagsmust not be set.
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 including a
VkDeviceQueueGlobalPriorityCreateInfoEXT structure in the pNext
chain of VkDeviceQueueCreateInfo.
The VkDeviceQueueGlobalPriorityCreateInfoEXT structure is defined as:
typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkQueueGlobalPriorityEXT globalPriority;
} VkDeviceQueueGlobalPriorityCreateInfoEXT;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. -
globalPriorityis 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:
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,
VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF
} 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_EXTis below the system default. Useful for non-interactive tasks. -
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXTis the system default priority. -
VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXTis above the system default. -
VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXTis 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:
void vkGetDeviceQueue(
VkDevice device,
uint32_t queueFamilyIndex,
uint32_t queueIndex,
VkQueue* pQueue);
-
deviceis the logical device that owns the queue. -
queueFamilyIndexis the index of the queue family to which the queue belongs. -
queueIndexis the index within this queue family of the queue to retrieve. -
pQueueis 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:
void vkGetDeviceQueue2(
VkDevice device,
const VkDeviceQueueInfo2* pQueueInfo,
VkQueue* pQueue);
-
deviceis the logical device that owns the queue. -
pQueueInfopoints to an instance of the VkDeviceQueueInfo2 structure, describing the parameters used to create the device queue. -
pQueueis a pointer to a VkQueue object that will be filled with the handle for the requested queue.
The VkDeviceQueueInfo2 structure is defined as:
typedef struct VkDeviceQueueInfo2 {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueIndex;
} VkDeviceQueueInfo2;
-
sTypeis the type of this structure. -
pNextisNULLor a pointer to an extension-specific structure. ThepNextchain ofVkDeviceQueueInfo2is used to provide additional image parameters tovkGetDeviceQueue2. -
flagsis a VkDeviceQueueCreateFlags value indicating the flags used to create the device queue. -
queueFamilyIndexis the index of the queue family to which the queue belongs. -
queueIndexis 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 Events) 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.
4.3.6. Queue Destruction
Queues are created along with a logical device during vkCreateDevice.
All queues associated with a logical device are destroyed when
vkDestroyDevice is called on that device.