Deferred Host Operations
Certain Vulkan commands are inherently expensive for the host CPU to execute. It is often desirable to offload such work onto background threads, and to parallelize the work across multiple CPUs. The concept of deferred operations allows applications and drivers to coordinate the execution of expensive host commands using an application-managed thread pool.
The VK_KHR_deferred_host_operations extension defines the infrastructure and usage patterns for deferrable commands, but does not specify any commands as deferrable. This is left to additional dependent extensions. Commands must not be deferred unless the deferral is specifically allowed by another extension which depends on VK_KHR_deferred_host_operations. This specification will refer to such extensions as deferral extensions.
Requesting Deferral
When an application requests an operation deferral, the implementation may
defer the operation.
When deferral is requested and the implementation defers any operation, the
implementation must return VK_OPERATION_DEFERRED_KHR
as the success
code if no errors occurred.
When deferral is requested, the implementation should defer the operation
when the workload is significant, however if the implementation chooses not
to defer any of the requested operations and instead executes all of them
immediately, the implementation must return
VK_OPERATION_NOT_DEFERRED_KHR
as the success code if no errors
occurred.
A deferred operation is created complete with an initial result value of
VK_SUCCESS
.
The deferred operation becomes pending when an operation has been
successfully deferred with that deferred operation object.
A deferred operation is considered pending until the deferred operation completes. A pending deferred operation becomes complete when it has been fully executed by one or more threads. Pending deferred operations will never complete until they are joined by an application thread, using vkDeferredOperationJoinKHR. Applications can join multiple threads to the same deferred operation, enabling concurrent execution of subtasks within that operation.
The application can query the status of a VkDeferredOperationKHR using the vkGetDeferredOperationMaxConcurrencyKHR or vkGetDeferredOperationResultKHR commands.
Parameters to the command requesting a deferred operation may be accessed by the implementation at any time until the deferred operation enters the complete state. The application must obey the following rules while a deferred operation is pending:
- Externally synchronized parameters must not be accessed.
- Pointer parameters must not be modified (e.g. reallocated/freed).
- The contents of pointer parameters which may be read by the command must not be modified.
- The contents of pointer parameters which may be written by the command must not be read.
- Vulkan object parameters must not be passed as externally synchronized parameters to any other command.
When the deferred operation is complete, the application should call vkGetDeferredOperationResultKHR to obtain the VkResult indicating success or failure of the operation. The VkResult value returned will be one of the values that the command requesting the deferred operation is able to return. Writes to output parameters of the requesting command will happen-before the deferred operation is complete.
When a deferral is requested for a command, the implementation may perform memory management operations on the allocator supplied to vkCreateDeferredOperationKHR for the deferred operation object, as described in the Memory Allocation chapter. Such allocations must occur on the thread which requests deferral.
If an allocator was supplied for the deferred command at the time of the deferral request, then the implementation may perform memory management operations on this allocator during the execution of vkDeferredOperationJoinKHR. These operations may occur concurrently and may be performed by any joined thread. The application must ensure that the supplied allocator is able to operate correctly under these conditions.