// Copyright 2014-2021 The Khronos Group, Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

include::{generated}/meta/{refprefix}VK_KHR_deferred_host_operations.txt[]

=== 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 `apiext: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
`apiext:VK_KHR_deferred_host_operations`.

include::{generated}/interfaces/VK_KHR_deferred_host_operations.txt[]

=== Code Examples

The following examples will illustrate the concept of deferrable operations
using a hypothetical example.
The command ftext:vkDoSomethingExpensiveEXT denotes a deferrable command.
The structure stext:VkExpensiveOperationArgsEXT represents the arguments
which it would normally accept.

The following example illustrates how a vulkan application might request
deferral of an expensive operation:

[source,cpp]
----

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

[source,cpp]
----

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

[source,cpp]
----

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)
