vulkan-3.26.1: Bindings to the Vulkan graphics API.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Vulkan.Extensions.VK_KHR_deferred_host_operations

Description

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

New Enum Constants

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

  1. 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

Documentation

createDeferredOperationKHR Source #

Arguments

:: forall io. MonadIO io 
=> Device

device is the device which owns operation.

-> ("allocator" ::: Maybe AllocationCallbacks)

pAllocator controls host memory allocation as described in the Memory Allocation chapter.

-> io DeferredOperationKHR 

vkCreateDeferredOperationKHR - Create a deferred operation handle

Valid Usage (Implicit)

  • device must be a valid Device handle

Return Codes

Success
Failure

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 #

Arguments

:: forall io. MonadIO io 
=> Device

device is the device which owns operation.

-> DeferredOperationKHR

operation is the completed operation to be destroyed.

-> ("allocator" ::: Maybe AllocationCallbacks)

pAllocator controls host memory allocation as described in the Memory Allocation chapter.

-> io () 

vkDestroyDeferredOperationKHR - Destroy a deferred operation handle

Valid Usage

  • If AllocationCallbacks were provided when operation was created, a compatible set of callbacks must be provided here
  • If no AllocationCallbacks were provided when operation was created, pAllocator must be NULL
  • operation must be completed

Valid Usage (Implicit)

  • device must be a valid Device handle
  • If operation is not NULL_HANDLE, operation must be a valid DeferredOperationKHR handle
  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid AllocationCallbacks structure
  • If operation is a valid handle, it must have been created, allocated, or retrieved from device

Host Synchronization

  • Host access to operation must be externally synchronized

See Also

VK_KHR_deferred_host_operations, AllocationCallbacks, DeferredOperationKHR, Device

getDeferredOperationMaxConcurrencyKHR Source #

Arguments

:: forall io. MonadIO io 
=> Device

device is the device which owns operation.

device must be a valid Device handle

-> DeferredOperationKHR

operation is the deferred operation to be queried.

operation must be a valid DeferredOperationKHR handle

operation must have been created, allocated, or retrieved from device

-> 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 #

Arguments

:: forall io. MonadIO io 
=> Device

device is the device which owns operation.

device must be a valid Device handle

-> DeferredOperationKHR

operation is the operation whose deferred result is being queried.

operation must be a valid DeferredOperationKHR handle

operation must have been created, allocated, or retrieved from device

-> 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

Success

See Also

VK_KHR_deferred_host_operations, DeferredOperationKHR, Device

deferredOperationJoinKHR Source #

Arguments

:: forall io. MonadIO io 
=> Device

device is the device which owns operation.

-> DeferredOperationKHR

operation is the deferred operation that the calling thread should work on.

-> 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 that operation is complete. The application should use getDeferredOperationResultKHR to retrieve the result of operation.
  • 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 to deferredOperationJoinKHR are not necessary and will simply harm performance. This situation may occur when other threads executing deferredOperationJoinKHR are about to complete operation, 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 returning THREAD_IDLE_KHR, the implementation is signaling that it expects that more opportunities for parallelism will emerge as execution progresses, and that future calls to deferredOperationJoinKHR 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:

  1. If only one thread has invoked deferredOperationJoinKHR on a given operation, that thread must execute the operation to completion and return SUCCESS.
  2. If multiple threads have concurrently invoked deferredOperationJoinKHR on the same operation, then at least one of them must complete the operation and return SUCCESS.

Valid Usage (Implicit)

  • device must be a valid Device handle
  • operation must be a valid DeferredOperationKHR handle
  • operation must have been created, allocated, or retrieved from device

Return Codes

Success
Failure

See Also

VK_KHR_deferred_host_operations, DeferredOperationKHR, Device

type KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME = "VK_KHR_deferred_host_operations" Source #

newtype DeferredOperationKHR Source #

Instances

Instances details
Storable DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

Show DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

Eq DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

Ord DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

HasObjectType DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

IsHandle DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles

Zero DeferredOperationKHR Source # 
Instance details

Defined in Vulkan.Extensions.Handles