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.
The following examples will illustrate the concept of deferrable operations using a hypothetical example. The command vkDoSomethingExpensive denotes a deferrable command.
The following example illustrates how a vulkan application might request deferral of an expensive operation:
// create a deferred operation
VkDeferredOperationKHR hOp;
VkResult result = vkCreateDeferredOperationKHR(device, pCallbacks, &hOp);
assert(result == VK_SUCCESS);
result = vkDoSomethingExpensive(device, hOp, ...);
assert( result == VK_OPERATION_DEFERRED_KHR );
// operation was deferred. Execute it asynchronously
std::async::launch(
[ hOp ] ( )
{
vkDeferredOperationJoinKHR(device, hOp);
result = vkGetDeferredOperationResultKHR(device, hOp);
// deferred operation is now complete. 'result' indicates success or failure
vkDestroyDeferredOperationKHR(device, hOp, pCallbacks);
}
);
The following example illustrates extracting concurrency from a single deferred operation:
// create a deferred operation
VkDeferredOperationKHR hOp;
VkResult result = vkCreateDeferredOperationKHR(device, pCallbacks, &hOp);
assert(result == VK_SUCCESS);
result = vkDoSomethingExpensive(device, hOp, ...);
assert( result == VK_OPERATION_DEFERRED_KHR );
// Query the maximum amount of concurrency and clamp to the desired maximum
uint32_t numLaunches = std::min(vkGetDeferredOperationMaxConcurrencyKHR(device, hOp), maxThreads);
std::vector<std::future<void> > joins;
for (uint32_t i = 0; i < numLaunches; i++) {
joins.emplace_back(std::async::launch(
[ hOp ] ( )
{
vkDeferredOperationJoinKHR(device, hOp);
// in a job system, a return of VK_THREAD_IDLE_KHR should queue another
// job, but it is not functionally required
}
));
}
for (auto &f : joins) {
f.get();
}
result = vkGetDeferredOperationResultKHR(device, hOp);
// deferred operation is now complete. 'result' indicates success or failure
vkDestroyDeferredOperationKHR(device, hOp, pCallbacks);
The following example shows a subroutine which guarantees completion of a deferred operation, in the presence of multiple worker threads, and returns the result of the operation.
VkResult FinishDeferredOperation(VkDeferredOperationKHR hOp)
{
// Attempt to join the operation until the implementation indicates that we should stop
VkResult result = vkDeferredOperationJoinKHR(device, hOp);
while( result == VK_THREAD_IDLE_KHR )
{
std::this_thread::yield();
result = vkDeferredOperationJoinKHR(device, hOp);
}
switch( result )
{
case VK_SUCCESS:
{
// deferred operation has finished. Query its result
result = vkGetDeferredOperationResultKHR(device, hOp);
}
break;
case VK_THREAD_DONE_KHR:
{
// deferred operation is being wrapped up by another thread
// wait for that thread to finish
do
{
std::this_thread::yield();
result = vkGetDeferredOperationResultKHR(device, hOp);
} while( result == VK_NOT_READY );
}
break;
default:
assert(false); // other conditions are illegal.
break;
}
return result;
}
VK_KHR_deferred_host_operations| Modifier and Type | Field and Description |
|---|---|
| public static final String | VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
The extension name. |
| public static final int | VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION
The extension specification version. |
| public static final int | VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR
Extends |
| public static final int | VK_OPERATION_DEFERRED_KHR
Extends |
| public static final int | VK_OPERATION_NOT_DEFERRED_KHR
Extends |
| public static final int | VK_THREAD_DONE_KHR
Extends |
| public static final int | VK_THREAD_IDLE_KHR
Extends |
| Access | Constructor and Description |
|---|---|
| protected |
| Modifier and Type | Method and Description |
|---|---|
| public static int | nvkCreateDeferredOperationKHR(VkDevice device, long pAllocator, long pDeferredOperation)
Unsafe version of: |
| public static void | nvkDestroyDeferredOperationKHR(VkDevice device, long operation, long pAllocator)
Unsafe version of: |
| public static int | vkCreateDeferredOperationKHR(VkDevice
the device which owns device, VkAllocationCallbacks operation.controls host memory allocation as described in the Memory Allocation chapter. pAllocator, LongBuffer a pointer to a handle in which the created pDeferredOperation)VkDeferredOperationKHR is returned.Create a deferred operation handle. |
| public static int | vkCreateDeferredOperationKHR(VkDevice device, VkAllocationCallbacks pAllocator, long[] pDeferredOperation)
Array version of: |
| public static int | vkDeferredOperationJoinKHR(VkDevice
the device which owns device, long operation.the deferred operation that the calling thread should work on. operation)Assign a thread to a deferred operation. |
| public static void | vkDestroyDeferredOperationKHR(VkDevice
the device which owns device, long operation.the completed operation to be destroyed. operation, VkAllocationCallbacks controls host memory allocation as described in the Memory Allocation chapter. pAllocator)Destroy a deferred operation handle. |
| public static int | vkGetDeferredOperationMaxConcurrencyKHR(VkDevice
the device which owns device, long operation.the deferred operation to be queried. operation)Query the maximum concurrency on a deferred operation. |
| public static int | vkGetDeferredOperationResultKHR(VkDevice
the device which owns device, long operation.the operation whose deferred result is being queried. operation)Query the result of a deferred operation. |
| VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME | back to summary |
|---|---|
| public static final String VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME The extension name. | |
| VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION | back to summary |
|---|---|
| public static final int VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION The extension specification version. | |
| VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR | back to summary |
|---|---|
| public static final int VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR Extends | |
| VK_OPERATION_DEFERRED_KHR | back to summary |
|---|---|
| public static final int VK_OPERATION_DEFERRED_KHR Extends Enum values: | |
| VK_OPERATION_NOT_DEFERRED_KHR | back to summary |
|---|---|
| public static final int VK_OPERATION_NOT_DEFERRED_KHR Extends Enum values: | |
| VK_THREAD_DONE_KHR | back to summary |
|---|---|
| public static final int VK_THREAD_DONE_KHR Extends Enum values: | |
| VK_THREAD_IDLE_KHR | back to summary |
|---|---|
| public static final int VK_THREAD_IDLE_KHR Extends Enum values: | |
| KHRDeferredHostOperations | back to summary |
|---|---|
| protected KHRDeferredHostOperations() | |
| nvkCreateDeferredOperationKHR | back to summary |
|---|---|
| public static int nvkCreateDeferredOperationKHR(VkDevice device, long pAllocator, long pDeferredOperation) Unsafe version of: | |
| nvkDestroyDeferredOperationKHR | back to summary |
|---|---|
| public static void nvkDestroyDeferredOperationKHR(VkDevice device, long operation, long pAllocator) Unsafe version of: | |
| vkCreateDeferredOperationKHR | back to summary |
|---|---|
| public static int vkCreateDeferredOperationKHR(VkDevice device, VkAllocationCallbacks pAllocator, LongBuffer pDeferredOperation) Create a deferred operation handle. C SpecificationTo construct the tracking object for a deferred command, call:
Valid Usage (Implicit)
Return Codes
See Also
| |
| vkCreateDeferredOperationKHR | back to summary |
|---|---|
| public static int vkCreateDeferredOperationKHR(VkDevice device, VkAllocationCallbacks pAllocator, long[] pDeferredOperation) Array version of:
| |
| vkDeferredOperationJoinKHR | back to summary |
|---|---|
| public static int vkDeferredOperationJoinKHR(VkDevice device, long operation) Assign a thread to a deferred operation. C SpecificationTo assign a thread to a deferred operation, call:
DescriptionThe The return value will be one of the following:
Implementations must guarantee forward progress by enforcing the following invariants:
Valid Usage (Implicit)
Return Codes
| |
| vkDestroyDeferredOperationKHR | back to summary |
|---|---|
| public static void vkDestroyDeferredOperationKHR(VkDevice device, long operation, VkAllocationCallbacks pAllocator) Destroy a deferred operation handle. C SpecificationWhen a deferred operation is completed, the application can destroy the tracking object by calling:
Valid Usage
Valid Usage (Implicit)
Host Synchronization
See Also
| |
| vkGetDeferredOperationMaxConcurrencyKHR | back to summary |
|---|---|
| public static int vkGetDeferredOperationMaxConcurrencyKHR(VkDevice device, long operation) Query the maximum concurrency on a deferred operation. C SpecificationTo query the number of additional threads that can usefully be joined to a deferred operation, call:
DescriptionThe returned value is the maximum number of threads that can usefully execute a deferred operation concurrently, reported for the state of the deferred operation at the point this command is called. This value is intended to be used to better schedule work onto available threads. Applications can join any number of threads to the deferred operation and expect it to eventually complete, though excessive joins may return If If If Implementations may return NoteThe recommended usage pattern for applications is to query this value once, after deferral, and schedule no more than the specified number of threads to join the operation. Each time a joined thread receives Valid Usage (Implicit)
| |
| vkGetDeferredOperationResultKHR | back to summary |
|---|---|
| public static int vkGetDeferredOperationResultKHR(VkDevice device, long operation) Query the result of a deferred operation. C SpecificationThe
DescriptionIf no command has been deferred on If the deferred operation is pending, If the deferred operation is complete, it returns the appropriate return value from the original command. This value must be one of the Valid Usage (Implicit)
Return Codes
| |