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.
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);
physicalDevice
must be one of the device handles returned from a
call to vkEnumeratePhysicalDevices
(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
points to a handle in which the created VkDevice
is
returned.
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;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
flags
is reserved for future use.
queueCreateInfoCount
is the unsigned integer size of the
pQueueCreateInfos
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 of
enabledExtensionCount
null-terminated UTF-8 strings containing the
names of extensions to enable for the created device.
See the Extensions section for
further details.
pEnabledFeatures
is NULL
or 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.
The following is a high-level list of VkDevice
uses along with
references on where to find more information:
A logical device may become lost because of hardware errors, execution
timeouts, power management events and/or platform-specific events.
This may cause pending and future command execution to fail and cause
hardware resources to be corrupted.
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 hardware, 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 their hardware has probably developed a fault or become physically disconnected, and should be investigated further. 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. |
![]() | Note |
---|---|
Undefined behavior caused by an application error may cause a device to
become lost.
However, such undefined behavior may also cause unrecoverable damage to the
process, and it is then not guaranteed that the API objects, including the
|
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 pending execution, or whether
resources are considered in-use by the device, a return value of
VK_ERROR_DEVICE_LOST
is equivalent to VK_SUCCESS
.
![]() | editing-note |
---|---|
TODO (piman) - I do not think we are very clear about what “in-use by the device” means. |
To destroy a device, call:
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
|