• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014-2021 The Khronos Group, Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_KHR_deferred_host_operations.txt[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2020-11-12
11*IP Status*::
12    No known IP claims.
13*Contributors*::
14  - Joshua Barczak, Intel
15  - Jeff Bolz, NVIDIA
16  - Daniel Koch, NVIDIA
17  - Slawek Grajewski, Intel
18  - Tobias Hector, AMD
19  - Yuriy O'Donnell, Epic
20  - Eric Werness, NVIDIA
21  - Baldur Karlsson, Valve
22  - Jesse Barker, Unity
23  - Contributors to VK_KHR_acceleration_structure,
24    VK_KHR_ray_tracing_pipeline
25
26=== Description
27
28The `apiext:VK_KHR_deferred_host_operations` extension defines the
29infrastructure and usage patterns for deferrable commands, but does not
30specify any commands as deferrable.
31This is left to additional dependent extensions.
32Commands must: not be deferred unless the deferral is specifically allowed
33by another extension which depends on
34`apiext:VK_KHR_deferred_host_operations`.
35
36include::{generated}/interfaces/VK_KHR_deferred_host_operations.txt[]
37
38=== Code Examples
39
40The following examples will illustrate the concept of deferrable operations
41using a hypothetical example.
42The command ftext:vkDoSomethingExpensiveEXT denotes a deferrable command.
43The structure stext:VkExpensiveOperationArgsEXT represents the arguments
44which it would normally accept.
45
46The following example illustrates how a vulkan application might request
47deferral of an expensive operation:
48
49[source,cpp]
50----
51
52// create a deferred operation
53VkDeferredOperationKHR hOp;
54VkResult result = vkCreateDeferredOperationKHR(device, pCallbacks, &hOp);
55assert(result == VK_SUCCESS);
56
57result = vkDoSomethingExpensive(device, hOp, ...);
58assert( result == VK_OPERATION_DEFERRED_KHR );
59
60// operation was deferred.  Execute it asynchronously
61std::async::launch(
62    [ hOp ] ( )
63    {
64        vkDeferredOperationJoinKHR(device, hOp);
65
66        result = vkGetDeferredOperationResultKHR(device, hOp);
67
68        // deferred operation is now complete.  'result' indicates success or failure
69
70        vkDestroyDeferredOperationKHR(device, hOp, pCallbacks);
71    }
72);
73
74----
75
76The following example illustrates extracting concurrency from a single
77deferred operation:
78
79[source,cpp]
80----
81
82// create a deferred operation
83VkDeferredOperationKHR hOp;
84VkResult result = vkCreateDeferredOperationKHR(device, pCallbacks, &hOp);
85assert(result == VK_SUCCESS);
86
87result = vkDoSomethingExpensive(device, hOp, ...);
88assert( result == VK_OPERATION_DEFERRED_KHR );
89
90// Query the maximum amount of concurrency and clamp to the desired maximum
91uint32_t numLaunches = std::min(vkGetDeferredOperationMaxConcurrencyKHR(device, hOp), maxThreads);
92
93std::vector<std::future<void> > joins;
94
95for (uint32_t i = 0; i < numLaunches; i++) {
96  joins.emplace_back(std::async::launch(
97    [ hOp ] ( )
98    {
99        vkDeferredOperationJoinKHR(device, hOp);
100                // in a job system, a return of VK_THREAD_IDLE_KHR should queue another
101                // job, but it is not functionally required
102    }
103  );
104}
105
106for (auto &f : joins) {
107  f.get();
108}
109
110result = vkGetDeferredOperationResultKHR(device, hOp);
111
112// deferred operation is now complete.  'result' indicates success or failure
113
114vkDestroyDeferredOperationKHR(device, hOp, pCallbacks);
115
116----
117
118
119The following example shows a subroutine which guarantees completion of a
120deferred operation, in the presence of multiple worker threads, and returns
121the result of the operation.
122
123[source,cpp]
124----
125
126VkResult FinishDeferredOperation(VkDeferredOperationKHR hOp)
127{
128    // Attempt to join the operation until the implementation indicates that we should stop
129
130    VkResult result = vkDeferredOperationJoinKHR(device, hOp);
131    while( result == VK_THREAD_IDLE_KHR )
132    {
133        std::this_thread::yield();
134        result = vkDeferredOperationJoinKHR(device, hOp);
135    }
136
137    switch( result )
138    {
139    case VK_SUCCESS:
140        {
141            // deferred operation has finished.  Query its result
142            result = vkGetDeferredOperationResultKHR(device, hOp);
143        }
144        break;
145
146    case VK_THREAD_DONE_KHR:
147        {
148            // deferred operation is being wrapped up by another thread
149            //  wait for that thread to finish
150            do
151            {
152                std::this_thread::yield();
153                result = vkGetDeferredOperationResultKHR(device, hOp);
154            } while( result == VK_NOT_READY );
155        }
156        break;
157
158    default:
159        assert(false); // other conditions are illegal.
160        break;
161    }
162
163    return result;
164}
165----
166
167=== Issues
168
169. Should this extension have a VkPhysicalDevice*FeaturesKHR structure?
170
171*RESOLVED*: No.
172This extension does not add any functionality on its own and requires a
173dependent extension to actually enable functionality and thus there is no
174value in adding a feature structure.
175If necessary, any dependent extension could add a feature boolean if it
176wanted to indicate that it is adding optional deferral support.
177
178=== Version History
179
180 * Revision 1, 2019-12-05 (Josh Barczak, Daniel Koch)
181   - Initial draft.
182 * Revision 2, 2020-03-06 (Daniel Koch, Tobias Hector)
183   - Add missing VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR enum
184   - fix sample code
185   - Clarified deferred operation parameter lifetimes (#2018,!3647)
186 * Revision 3, 2020-05-15 (Josh Barczak)
187   - Clarify behavior of vkGetDeferredOperationMaxConcurrencyKHR, allowing
188     it to return 0 if the operation is complete (#2036,!3850)
189 * Revision 4, 2020-11-12 (Tobias Hector, Daniel Koch)
190   - Remove VkDeferredOperationInfoKHR and change return value semantics
191     when deferred host operations are in use (#2067,3813)
192   - clarify return value of vkGetDeferredOperationResultKHR (#2339,!4110)
193