Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Name
VK_KHR_deferred_host_operations - device extension
VK_KHR_deferred_host_operations
- Name String
VK_KHR_deferred_host_operations
- Extension Type
- Device extension
- Registered Extension Number
- 269
- Revision
- 4
- Ratification Status
- Ratified
- Extension and Version Dependencies; Contact
Other Extension Metadata
- Last Modified Date
- 2020-11-12
- IP Status
- No known IP claims.
- Contributors
- Joshua Barczak, Intel
- Jeff Bolz, NVIDIA
- Daniel Koch, NVIDIA
- Slawek Grajewski, Intel
- Tobias Hector, AMD
- Yuriy O’Donnell, Epic
- Eric Werness, NVIDIA
- Baldur Karlsson, Valve
- Jesse Barker, Unity
- Contributors to VK_KHR_acceleration_structure, VK_KHR_ray_tracing_pipeline
Description
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
.
New Object Types
New Commands
deferredOperationJoinKHR
destroyDeferredOperationKHR
getDeferredOperationMaxConcurrencyKHR
getDeferredOperationResultKHR
New Enum Constants
KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION
Extending
ObjectType
:Extending
Result
:
Code Examples
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; }
Issues
- Should this extension have a VkPhysicalDevice*FeaturesKHR structure?
RESOLVED: No. This extension does not add any functionality on its own and requires a dependent extension to actually enable functionality and thus there is no value in adding a feature structure. If necessary, any dependent extension could add a feature boolean if it wanted to indicate that it is adding optional deferral support.
Version History
Revision 1, 2019-12-05 (Josh Barczak, Daniel Koch)
- Initial draft.
Revision 2, 2020-03-06 (Daniel Koch, Tobias Hector)
- Add missing VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR enum
- fix sample code
- Clarified deferred operation parameter lifetimes (#2018,!3647)
Revision 3, 2020-05-15 (Josh Barczak)
- Clarify behavior of vkGetDeferredOperationMaxConcurrencyKHR, allowing it to return 0 if the operation is complete (#2036,!3850)
Revision 4, 2020-11-12 (Tobias Hector, Daniel Koch)
- Remove VkDeferredOperationInfoKHR and change return value semantics when deferred host operations are in use (#2067,3813)
- clarify return value of vkGetDeferredOperationResultKHR (#2339,!4110)
See Also
DeferredOperationKHR
,
createDeferredOperationKHR
, deferredOperationJoinKHR
,
destroyDeferredOperationKHR
, getDeferredOperationMaxConcurrencyKHR
,
getDeferredOperationResultKHR
Document Notes
For more information, see the Vulkan Specification
This page is a generated document. Fixes and changes should be made to the generator scripts, not directly.
Synopsis
- createDeferredOperationKHR :: forall io. MonadIO io => Device -> ("allocator" ::: Maybe AllocationCallbacks) -> io DeferredOperationKHR
- withDeferredOperationKHR :: forall io r. MonadIO io => Device -> Maybe AllocationCallbacks -> (io DeferredOperationKHR -> (DeferredOperationKHR -> io ()) -> r) -> r
- destroyDeferredOperationKHR :: forall io. MonadIO io => Device -> DeferredOperationKHR -> ("allocator" ::: Maybe AllocationCallbacks) -> io ()
- getDeferredOperationMaxConcurrencyKHR :: forall io. MonadIO io => Device -> DeferredOperationKHR -> io Word32
- getDeferredOperationResultKHR :: forall io. MonadIO io => Device -> DeferredOperationKHR -> io Result
- deferredOperationJoinKHR :: forall io. MonadIO io => Device -> DeferredOperationKHR -> io Result
- type KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION = 4
- pattern KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION :: forall a. Integral a => a
- type KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME = "VK_KHR_deferred_host_operations"
- pattern KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME :: forall a. (Eq a, IsString a) => a
- newtype DeferredOperationKHR = DeferredOperationKHR Word64
Documentation
createDeferredOperationKHR Source #
:: forall io. MonadIO io | |
=> Device |
|
-> ("allocator" ::: Maybe AllocationCallbacks) |
|
-> io DeferredOperationKHR |
vkCreateDeferredOperationKHR - Create a deferred operation handle
Valid Usage (Implicit)
-
device
must be a validDevice
handle
- If
pAllocator
is notNULL
,pAllocator
must be a valid pointer to a validAllocationCallbacks
structure -
pDeferredOperation
must be a valid pointer to aDeferredOperationKHR
handle
Return Codes
See Also
VK_KHR_deferred_host_operations,
AllocationCallbacks
,
DeferredOperationKHR
,
Device
withDeferredOperationKHR :: forall io r. MonadIO io => Device -> Maybe AllocationCallbacks -> (io DeferredOperationKHR -> (DeferredOperationKHR -> io ()) -> r) -> r Source #
A convenience wrapper to make a compatible pair of calls to
createDeferredOperationKHR
and destroyDeferredOperationKHR
To ensure that destroyDeferredOperationKHR
is always called: pass
bracket
(or the allocate function from your
favourite resource management library) as the last argument.
To just extract the pair pass (,)
as the last argument.
destroyDeferredOperationKHR Source #
:: forall io. MonadIO io | |
=> Device |
|
-> DeferredOperationKHR |
|
-> ("allocator" ::: Maybe AllocationCallbacks) |
|
-> io () |
vkDestroyDeferredOperationKHR - Destroy a deferred operation handle
Valid Usage
- If
AllocationCallbacks
were provided whenoperation
was created, a compatible set of callbacks must be provided here
- If no
AllocationCallbacks
were provided whenoperation
was created,pAllocator
must beNULL
-
operation
must be completed
Valid Usage (Implicit)
-
device
must be a validDevice
handle
- If
operation
is notNULL_HANDLE
,operation
must be a validDeferredOperationKHR
handle - If
pAllocator
is notNULL
,pAllocator
must be a valid pointer to a validAllocationCallbacks
structure - If
operation
is a valid handle, it must have been created, allocated, or retrieved fromdevice
Host Synchronization
- Host access to
operation
must be externally synchronized
See Also
VK_KHR_deferred_host_operations,
AllocationCallbacks
,
DeferredOperationKHR
,
Device
getDeferredOperationMaxConcurrencyKHR Source #
:: forall io. MonadIO io | |
=> Device |
|
-> DeferredOperationKHR |
|
-> io Word32 |
vkGetDeferredOperationMaxConcurrencyKHR - Query the maximum concurrency on a deferred operation
Description
The 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 THREAD_DONE_KHR
immediately,
performing no useful work.
If operation
is complete, getDeferredOperationMaxConcurrencyKHR
returns zero.
If operation
is currently joined to any threads, the value returned by
this command may immediately be out of date.
If operation
is pending, implementations must not return zero unless
at least one thread is currently executing deferredOperationJoinKHR
on
operation
. If there are such threads, the implementation should
return an estimate of the number of additional threads which it could
profitably use.
Implementations may return 232-1 to indicate that the maximum concurrency is unknown and cannot be easily derived. Implementations may return values larger than the maximum concurrency available on the host CPU. In these situations, an application should clamp the return value rather than oversubscribing the machine.
Note
The 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
THREAD_IDLE_KHR
, the application should
schedule an additional join at some point in the future, but is not
required to do so.
Valid Usage (Implicit)
See Also
VK_KHR_deferred_host_operations,
DeferredOperationKHR
,
Device
getDeferredOperationResultKHR Source #
:: forall io. MonadIO io | |
=> Device |
|
-> DeferredOperationKHR |
|
-> io Result |
vkGetDeferredOperationResultKHR - Query the result of a deferred operation
Description
If no command has been deferred on operation
,
getDeferredOperationResultKHR
returns
SUCCESS
.
If the deferred operation is pending, getDeferredOperationResultKHR
returns NOT_READY
.
If the deferred operation is complete, it returns the appropriate return
value from the original command. This value must be one of the
Result
values which could have been
returned by the original command if the operation had not been deferred.
Return Codes
See Also
VK_KHR_deferred_host_operations,
DeferredOperationKHR
,
Device
deferredOperationJoinKHR Source #
:: forall io. MonadIO io | |
=> Device |
|
-> DeferredOperationKHR |
|
-> io Result |
vkDeferredOperationJoinKHR - Assign a thread to a deferred operation
Description
The deferredOperationJoinKHR
command will execute a portion of the
deferred operation on the calling thread.
The return value will be one of the following:
- A return value of
SUCCESS
indicates thatoperation
is complete. The application should usegetDeferredOperationResultKHR
to retrieve the result ofoperation
. - A return value of
THREAD_DONE_KHR
indicates that the deferred operation is not complete, but there is no work remaining to assign to threads. Future calls todeferredOperationJoinKHR
are not necessary and will simply harm performance. This situation may occur when other threads executingdeferredOperationJoinKHR
are about to completeoperation
, and the implementation is unable to partition the workload any further. - A return value of
THREAD_IDLE_KHR
indicates that the deferred operation is not complete, and there is no work for the thread to do at the time of the call. This situation may occur if the operation encounters a temporary reduction in parallelism. By returningTHREAD_IDLE_KHR
, the implementation is signaling that it expects that more opportunities for parallelism will emerge as execution progresses, and that future calls todeferredOperationJoinKHR
can be beneficial. In the meantime, the application can perform other work on the calling thread.
Implementations must guarantee forward progress by enforcing the following invariants:
- If only one thread has invoked
deferredOperationJoinKHR
on a given operation, that thread must execute the operation to completion and returnSUCCESS
. - If multiple threads have concurrently invoked
deferredOperationJoinKHR
on the same operation, then at least one of them must complete the operation and returnSUCCESS
.
Valid Usage (Implicit)
-
device
must be a validDevice
handle
-
operation
must be a validDeferredOperationKHR
handle -
operation
must have been created, allocated, or retrieved fromdevice
Return Codes
See Also
VK_KHR_deferred_host_operations,
DeferredOperationKHR
,
Device
pattern KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION :: forall a. Integral a => a Source #
type KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME = "VK_KHR_deferred_host_operations" Source #
pattern KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME :: forall a. (Eq a, IsString a) => a Source #
newtype DeferredOperationKHR Source #
VkDeferredOperationKHR - A deferred operation
Description
This handle refers to a tracking structure which manages the execution state for a deferred command.
See Also
VK_KHR_deferred_host_operations,
buildAccelerationStructuresKHR
,
buildMicromapsEXT
,
copyAccelerationStructureKHR
,
copyAccelerationStructureToMemoryKHR
,
copyMemoryToAccelerationStructureKHR
,
copyMemoryToMicromapEXT
,
copyMicromapEXT
,
copyMicromapToMemoryEXT
,
createDeferredOperationKHR
,
createRayTracingPipelinesKHR
,
deferredOperationJoinKHR
,
destroyDeferredOperationKHR
,
getDeferredOperationMaxConcurrencyKHR
,
getDeferredOperationResultKHR